-
Notifications
You must be signed in to change notification settings - Fork 74
working branch #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
working branch #46
Conversation
Summary of ChangesHello @kumarcloud-code, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request primarily focuses on enhancing the usability and robustness of the Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Caution Review failedThe pull request is closed. WalkthroughThe PR introduces utility scripts for testing and inspecting the PocketOption API client, updates internal import paths to absolute package-qualified references, and adds a comprehensive connection monitoring system with metrics collection, health tracking, and diagnostics reporting. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes The changes span multiple new utility scripts (straightforward logic) and a substantial connection monitoring system with multiple dataclasses, async methods, metrics collection, and diagnostic reporting. Import updates are consistent but applied across files. Heterogeneity of purposes (utilities, imports, and monitoring system) requires separate reasoning for each cohort, but individual logic is not overly dense. Possibly related PRs
Suggested reviewers
Poem
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (7)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces several useful example and utility scripts, and fixes some import paths. The changes are a good addition, but there are some critical issues to address. A backup file (.bak) has been committed, which should be removed. Additionally, the new scripts contain some resource management issues (potential leaks) and logic bugs that could cause them to fail or behave unexpectedly. I've provided detailed comments and suggestions to improve the robustness and correctness of these scripts.
| @@ -0,0 +1,815 @@ | |||
| """ | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| async def main(): | ||
| client = AsyncPocketOptionClient(SSID) | ||
|
|
||
| print("Connecting...") | ||
| try: | ||
| await client.connect() | ||
| except Exception as e: | ||
| print("Failed to connect:", e) | ||
| return | ||
|
|
||
| print("Connected. Attempting to place order...") | ||
|
|
||
| # candidate method names in priority order | ||
| candidate_methods = [ | ||
| "place_order", | ||
| "buy", | ||
| "create_order", | ||
| "trade", | ||
| "_send_order" # internal but present in some versions | ||
| ] | ||
|
|
||
| tried = False | ||
| for method_name in candidate_methods: | ||
| if hasattr(client, method_name): | ||
| tried = True | ||
| method = getattr(client, method_name) | ||
| print(f"Trying method: {method_name} (positional)") | ||
|
|
||
| ok, res = await try_call(method, AMOUNT, ASSET, DURATION, DIRECTION) | ||
| if ok: | ||
| print(f"Success (positional) with {method_name} ->", res) | ||
| order_result = res | ||
| break | ||
|
|
||
| # try common keyword variations | ||
| kw_variants = [ | ||
| {"amount": AMOUNT, "asset": ASSET, "direction": DIRECTION, "duration": DURATION}, | ||
| {"amount": AMOUNT, "instrument": ASSET, "direction": DIRECTION, "duration": DURATION}, | ||
| {"amount": AMOUNT, "asset": ASSET, "type": "binary", "duration": DURATION, "direction": DIRECTION}, | ||
| {"value": AMOUNT, "asset": ASSET, "side": DIRECTION, "duration": DURATION}, | ||
| ] | ||
| for kw in kw_variants: | ||
| print(f"Trying {method_name} with kwargs: {list(kw.keys())}") | ||
| ok, res = await try_call(method, **kw) | ||
| if ok: | ||
| print(f"Success (kw) with {method_name} ->", res) | ||
| order_result = res | ||
| break | ||
| else: | ||
| print(f"{method_name} didn't accept attempted signatures; last error:", res) | ||
| order_result = None | ||
|
|
||
| if order_result is not None: | ||
| break | ||
|
|
||
| if not tried: | ||
| print("No candidate order methods found on client.") | ||
| else: | ||
| # If we got an order result, attempt to check order status / active orders | ||
| try: | ||
| if hasattr(client, "check_order_result"): | ||
| print("Calling check_order_result(...) to verify...") | ||
| try: | ||
| ok, info = await try_call(client.check_order_result, order_result) | ||
| print("check_order_result:", ok, info) | ||
| except Exception as e: | ||
| print("check_order_result call failed:", e) | ||
|
|
||
| if hasattr(client, "get_active_orders"): | ||
| print("Fetching active orders...") | ||
| ok, active = await try_call(client.get_active_orders) | ||
| if ok: | ||
| print("Active orders:", active) | ||
| else: | ||
| print("get_active_orders error:", active) | ||
| except Exception as e: | ||
| print("Post-order checks failed:", e) | ||
|
|
||
| # read balance if method exists | ||
| try: | ||
| if hasattr(client, "get_balance"): | ||
| bal = await client.get_balance() | ||
| print("Balance:", bal) | ||
| except Exception as e: | ||
| print("get_balance failed:", e) | ||
|
|
||
| # disconnect | ||
| try: | ||
| await client.disconnect() | ||
| except Exception: | ||
| # some forks use close/disconnect variations | ||
| try: | ||
| await client.close() | ||
| except Exception: | ||
| pass | ||
|
|
||
| print("Done.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main function has a couple of issues:
- Resource Leak: It doesn't guarantee that
client.disconnect()is called if an error occurs, which can lead to resource leaks. This is best fixed with atry...finallyblock. - Logic Bug: If no order placement succeeds,
order_resultcan beNoneand is then used in post-order checks, which can cause an error. This can be fixed by checking iforder_resulthas a value before using it.
The suggested change refactors the function to address both issues for more robust and reliable execution.
async def main():
client = AsyncPocketOptionClient(SSID)
order_result = None
try:
print("Connecting...")
try:
await client.connect()
except Exception as e:
print("Failed to connect:", e)
return
print("Connected. Attempting to place order...")
# candidate method names in priority order
candidate_methods = [
"place_order",
"buy",
"create_order",
"trade",
"_send_order" # internal but present in some versions
]
tried = False
for method_name in candidate_methods:
if hasattr(client, method_name):
tried = True
method = getattr(client, method_name)
print(f"Trying method: {method_name} (positional)")
ok, res = await try_call(method, AMOUNT, ASSET, DURATION, DIRECTION)
if ok:
print(f"Success (positional) with {method_name} ->", res)
order_result = res
break
# try common keyword variations
kw_variants = [
{"amount": AMOUNT, "asset": ASSET, "direction": DIRECTION, "duration": DURATION},
{"amount": AMOUNT, "instrument": ASSET, "direction": DIRECTION, "duration": DURATION},
{"amount": AMOUNT, "asset": ASSET, "type": "binary", "duration": DURATION, "direction": DIRECTION},
{"value": AMOUNT, "asset": ASSET, "side": DIRECTION, "duration": DURATION},
]
for kw in kw_variants:
print(f"Trying {method_name} with kwargs: {list(kw.keys())}")
ok, res = await try_call(method, **kw)
if ok:
print(f"Success (kw) with {method_name} ->", res)
order_result = res
break
else:
print(f"{method_name} didn't accept attempted signatures; last error:", res)
if order_result is not None:
break
if not tried:
print("No candidate order methods found on client.")
elif order_result:
# If we got an order result, attempt to check order status / active orders
try:
if hasattr(client, "check_order_result"):
print("Calling check_order_result(...) to verify...")
try:
ok, info = await try_call(client.check_order_result, order_result)
print("check_order_result:", ok, info)
except Exception as e:
print("check_order_result call failed:", e)
if hasattr(client, "get_active_orders"):
print("Fetching active orders...")
ok, active = await try_call(client.get_active_orders)
if ok:
print("Active orders:", active)
else:
print("get_active_orders error:", active)
except Exception as e:
print("Post-order checks failed:", e)
# read balance if method exists
try:
if hasattr(client, "get_balance"):
bal = await client.get_balance()
print("Balance:", bal)
except Exception as e:
print("get_balance failed:", e)
finally:
# disconnect
if client:
try:
await client.disconnect()
except Exception:
# some forks use close/disconnect variations
try:
await client.close()
except Exception:
pass
print("Done.")| def main(): | ||
| ssid = os.getenv("SSID") | ||
| if not ssid: | ||
| raise SystemExit("SSID not set. Put it in .env or export SSID in shell.") | ||
|
|
||
| api = PocketOption(ssid) # instantiate client | ||
| ok, msg = api.connect() # many forks return (ok, msg) from connect | ||
| if not ok: | ||
| print("Connect failed:", msg) | ||
| return | ||
|
|
||
| # --- change these to an asset available in demo account --- | ||
| amount = 1.0 | ||
| asset = "EURUSD" # example — use an asset listed by the demo account | ||
| direction = "call" # or "put" | ||
| duration = 60 # seconds or API-specific timeframe | ||
|
|
||
| # Try common method names in order of likelihood | ||
| for method in ("buy", "place_order", "create_order", "trade"): | ||
| if hasattr(api, method): | ||
| fn = getattr(api, method) | ||
| try: | ||
| print(f"Using method: {method}") | ||
| res = fn(amount, asset, duration, direction) # many libs use this signature | ||
| except TypeError: | ||
| # try keyword style | ||
| try: | ||
| res = fn(amount=amount, asset=asset, direction=direction, duration=duration) | ||
| except Exception as e: | ||
| print("Method exists but calling failed:", e) | ||
| res = None | ||
| print("Result:", res) | ||
| break | ||
| else: | ||
| print("No typical order method found on api object. See instructions to grep for available methods.") | ||
|
|
||
| try: | ||
| # read balance or open positions if available | ||
| if hasattr(api, "get_balance"): | ||
| print("Balance:", api.get_balance()) | ||
| elif hasattr(api, "balance"): | ||
| print("Balance property:", api.balance) | ||
| except Exception: | ||
| pass | ||
|
|
||
| api.close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main function has two issues:
- Resource Leak:
api.close()is not guaranteed to be called on an error, which can lead to resource leaks. Atry...finallyblock is needed. - Logic Bug: The loop to find an order method has a
breakthat causes it to exit after the first attempt, whether it was successful or not. It should only break on success.
The suggested refactoring addresses both points for a more robust script.
def main():
ssid = os.getenv("SSID")
if not ssid:
raise SystemExit("SSID not set. Put it in .env or export SSID in shell.")
api = PocketOption(ssid) # instantiate client
try:
ok, msg = api.connect() # many forks return (ok, msg) from connect
if not ok:
print("Connect failed:", msg)
return
# --- change these to an asset available in demo account ---
amount = 1.0
asset = "EURUSD" # example — use an asset listed by the demo account
direction = "call" # or "put"
duration = 60 # seconds or API-specific timeframe
# Try common method names in order of likelihood
order_successful = False
for method in ("buy", "place_order", "create_order", "trade"):
if hasattr(api, method):
fn = getattr(api, method)
try:
print(f"Using method: {method} (positional)")
res = fn(amount, asset, duration, direction) # many libs use this signature
print("Result:", res)
order_successful = True
break # Success, so exit loop
except TypeError:
# try keyword style
try:
print(f"Using method: {method} (keyword)")
res = fn(amount=amount, asset=asset, direction=direction, duration=duration)
print("Result:", res)
order_successful = True
break # Success, so exit loop
except Exception as e:
print(f"Method '{method}' with kwargs failed: {e}")
except Exception as e:
print(f"Method '{method}' failed: {e}")
if not order_successful:
print("No typical order method found on api object, or all attempts failed.")
try:
# read balance or open positions if available
if hasattr(api, "get_balance"):
print("Balance:", api.get_balance())
elif hasattr(api, "balance"):
print("Balance property:", api.balance)
except Exception:
pass
finally:
api.close()| try: | ||
| from pocketoptionapi_async.client import AsyncPocketOptionClient | ||
| except Exception as e: | ||
| raise SystemExit("Cannot import AsyncPocketOptionClient: " + str(e)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Catching the generic Exception is too broad and can hide other unexpected errors during startup. It's better to catch the specific ImportError that you're expecting here.
| try: | |
| from pocketoptionapi_async.client import AsyncPocketOptionClient | |
| except Exception as e: | |
| raise SystemExit("Cannot import AsyncPocketOptionClient: " + str(e)) | |
| try: | |
| from pocketoptionapi_async.client import AsyncPocketOptionClient | |
| except ImportError as e: | |
| raise SystemExit("Cannot import AsyncPocketOptionClient: " + str(e)) |
| It will back up each file to filename.bak before editing. | ||
| """ | ||
| import sys, os, re, shutil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| @@ -0,0 +1,47 @@ | |||
| # inspect_pocket.py | |||
| import importlib, pkgutil, inspect, os | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| try: | ||
| # common sync API wrapper | ||
| from pocketoptionapi_async.stable_api import PocketOption | ||
| except Exception: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Catching a generic Exception is too broad and can hide unexpected errors. It's better to catch the specific ImportError you're expecting.
| try: | |
| # common sync API wrapper | |
| from pocketoptionapi_async.stable_api import PocketOption | |
| except Exception: | |
| try: | |
| # common sync API wrapper | |
| from pocketoptionapi_async.stable_api import PocketOption | |
| except ImportError: |
| except Exception: | ||
| # fallback to client (some forks expose sync client differently) | ||
| try: | ||
| from pocketoptionapi_async.client import PocketOption as PocketOption |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary by CodeRabbit