diff --git a/backend/apps/subscriptions/NineRouter/NineRouterClient.py b/backend/apps/subscriptions/NineRouter/NineRouterClient.py index e097c8f2..bf7ccca2 100644 --- a/backend/apps/subscriptions/NineRouter/NineRouterClient.py +++ b/backend/apps/subscriptions/NineRouter/NineRouterClient.py @@ -1,31 +1,11 @@ """HTTP client for 9Router's REST API.""" -import logging - import httpx from typeguard import typechecked +from backend.apps.subscriptions.NineRouter.constants import NINE_ROUTER_API, NINE_ROUTER_V1 from backend.ports import NINE_ROUTER_PORT -logger = logging.getLogger(__name__) - -NINE_ROUTER_URL: str = f"http://localhost:{NINE_ROUTER_PORT}" -NINE_ROUTER_API: str = f"{NINE_ROUTER_URL}/api" -NINE_ROUTER_V1: str = f"{NINE_ROUTER_URL}/v1" - - -@typechecked -async def get_usage_stats(period: str = "all") -> dict | None: - try: - async with httpx.AsyncClient(timeout=5.0) as client: - r = await client.get(f"{NINE_ROUTER_API}/usage/stats", params={"period": period}) - if r.status_code == 200: - return r.json() - except Exception as e: - logger.debug(f"9Router usage stats fetch failed: {e}") - return None - - @typechecked async def get_providers() -> list[dict] | dict: try: @@ -34,7 +14,7 @@ async def get_providers() -> list[dict] | dict: if r.status_code == 200: return r.json() except Exception as e: - logger.debug(f"9Router providers fetch failed: {e}") + print(f"9Router providers fetch failed: {e}") return [] @@ -110,10 +90,10 @@ async def exchange_oauth( "codeVerifier": code_verifier, "state": state, } - logger.info(f"exchange_oauth: provider={provider} redirect_uri={redirect_uri}") + print(f"exchange_oauth: provider={provider} redirect_uri={redirect_uri}") async with httpx.AsyncClient(timeout=15.0) as client: r = await client.post(f"{NINE_ROUTER_API}/oauth/{provider}/exchange", json=payload) - logger.info(f"exchange_oauth: status={r.status_code}") + print(f"exchange_oauth: status={r.status_code}") r.raise_for_status() return r.json() @@ -136,5 +116,5 @@ async def get_models() -> list[dict]: for m in models ] except Exception as e: - logger.debug(f"9Router models fetch failed: {e}") + print(f"9Router models fetch failed: {e}") return [] diff --git a/backend/apps/subscriptions/NineRouter/NineRouterProcess.py b/backend/apps/subscriptions/NineRouter/NineRouterProcess.py index e7cf995b..b336a777 100644 --- a/backend/apps/subscriptions/NineRouter/NineRouterProcess.py +++ b/backend/apps/subscriptions/NineRouter/NineRouterProcess.py @@ -5,7 +5,6 @@ Claude/ChatGPT/Gemini subscriptions to OpenSwarm without API keys. """ import asyncio -import logging import os import shutil import subprocess @@ -15,14 +14,10 @@ import httpx from typeguard import typechecked from backend.ports import NINE_ROUTER_PORT +from backend.apps.subscriptions.NineRouter.constants import NINE_ROUTER_V1, NINE_ROUTER_URL -logger = logging.getLogger(__name__) - -NINE_ROUTER_URL: str = f"http://localhost:{NINE_ROUTER_PORT}" -NINE_ROUTER_V1: str = f"{NINE_ROUTER_URL}/v1" - -_process: subprocess.Popen | None = None -_THIS_DIR: str = os.path.dirname(os.path.abspath(__file__)) +P_PROCESS: subprocess.Popen | None = None +P_THIS_DIR: str = os.path.dirname(os.path.abspath(__file__)) def _forward_output(pipe) -> None: @@ -55,12 +50,12 @@ def _find_9router_dir() -> str | None: _is_packaged: bool = os.environ.get("OPENSWARM_PACKAGED") == "1" if _is_packaged: - _resources: str = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(_THIS_DIR)))) + _resources: str = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(P_THIS_DIR)))) _candidate: str = os.path.join(_resources, "9router") if os.path.isdir(_candidate): return _candidate else: - _backend_dir: str = os.path.dirname(os.path.dirname(os.path.dirname(_THIS_DIR))) + _backend_dir: str = os.path.dirname(os.path.dirname(os.path.dirname(P_THIS_DIR))) _project_root: str = os.path.dirname(_backend_dir) _candidate = os.path.join(_project_root, "9router") if os.path.isdir(_candidate): @@ -83,7 +78,7 @@ def _find_node() -> str | None: @typechecked async def ensure_running() -> None: """Start 9Router if not already running.""" - global _process + global P_PROCESS _is_packaged: bool = os.environ.get("OPENSWARM_PACKAGED") == "1" if is_running(): @@ -173,14 +168,14 @@ async def ensure_running() -> None: } try: - _process = subprocess.Popen( + P_PROCESS = subprocess.Popen( cmd, cwd=cwd, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env, ) - threading.Thread(target=_forward_output, args=(_process.stdout,), daemon=True).start() + threading.Thread(target=_forward_output, args=(P_PROCESS.stdout,), daemon=True).start() timeout: int = 20 if _is_packaged else 30 for _ in range(timeout * 2): @@ -196,15 +191,15 @@ async def ensure_running() -> None: @typechecked def stop() -> None: - global _process - if _process: + global P_PROCESS + if P_PROCESS: try: - _process.terminate() - _process.wait(timeout=5) + P_PROCESS.terminate() + P_PROCESS.wait(timeout=5) except Exception: try: - _process.kill() + P_PROCESS.kill() except Exception: pass - _process = None - logger.info("9Router stopped") + P_PROCESS = None + print("9Router stopped") diff --git a/backend/apps/subscriptions/NineRouter/constants.py b/backend/apps/subscriptions/NineRouter/constants.py new file mode 100644 index 00000000..d2734833 --- /dev/null +++ b/backend/apps/subscriptions/NineRouter/constants.py @@ -0,0 +1,5 @@ +from backend.ports import NINE_ROUTER_PORT + +NINE_ROUTER_URL: str = f"http://localhost:{NINE_ROUTER_PORT}" +NINE_ROUTER_API: str = f"{NINE_ROUTER_URL}/api" +NINE_ROUTER_V1: str = f"{NINE_ROUTER_URL}/v1" \ No newline at end of file diff --git a/backend/apps/subscriptions/html_constants.py b/backend/apps/subscriptions/html_constants.py new file mode 100644 index 00000000..d57ec047 --- /dev/null +++ b/backend/apps/subscriptions/html_constants.py @@ -0,0 +1,23 @@ + + +SUCCESS_HTML: str = ( + '
' + 'You can close this window
' + 'You can close this window
' - '{desc}
Please try connecting again.
{e}