From b0ec291345e23ec36cc08f31a8671ac5b5b36fc1 Mon Sep 17 00:00:00 2001 From: dekun Date: Tue, 23 Jun 2026 18:20:51 +0800 Subject: [PATCH] Replace httpx with urllib in calculator market fetch. Avoid ModuleNotFoundError when hub_calculator_market_lib loads outside the manual-trading-hub venv. Co-authored-by: Cursor --- hub_calculator_market_lib.py | 38 ++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/hub_calculator_market_lib.py b/hub_calculator_market_lib.py index 7615406..b9c99b2 100644 --- a/hub_calculator_market_lib.py +++ b/hub_calculator_market_lib.py @@ -2,13 +2,14 @@ from __future__ import annotations +import json import threading import time +import urllib.error +import urllib.request from typing import Any, Callable, Optional, Tuple from urllib.parse import urlencode -import httpx - from manual_trading_hub.settings_store import enabled_exchanges, load_settings MARKET_CACHE: dict[str, tuple[float, dict[str, Any]]] = {} @@ -180,20 +181,27 @@ def fetch_instance_market_sync(ex: dict, *, base: str) -> dict[str, Any]: return {"ok": False, "msg": "未配置 flask_url"} params = urlencode({"base": normalize_base_symbol(base) or base}) url = f"{base_url}/api/hub/market?{params}" + req = urllib.request.Request(url, headers=_hub_headers(), method="GET") try: - with httpx.Client(timeout=HUB_FLASK_TIMEOUT) as client: - r = client.get(url, headers=_hub_headers()) - if r.status_code >= 400: - try: - body = r.json() - except Exception: - body = {"ok": False, "msg": r.text or f"HTTP {r.status_code}"} - if isinstance(body, dict): - body.setdefault("ok", False) - return body - return {"ok": False, "msg": f"HTTP {r.status_code}"} - data = r.json() if r.content else {} - return data if isinstance(data, dict) else {"ok": False, "msg": "无效 JSON"} + with urllib.request.urlopen(req, timeout=HUB_FLASK_TIMEOUT) as resp: + status = int(getattr(resp, "status", 200) or 200) + raw = resp.read().decode("utf-8", errors="replace") + data = json.loads(raw) if raw else {} + if not isinstance(data, dict): + return {"ok": False, "msg": "无效 JSON"} + if status >= 400: + data.setdefault("ok", False) + return data + except urllib.error.HTTPError as exc: + try: + raw = exc.read().decode("utf-8", errors="replace") + body = json.loads(raw) if raw else {} + except Exception: + body = {"ok": False, "msg": raw if "raw" in locals() else str(exc)} + if isinstance(body, dict): + body.setdefault("ok", False) + return body + return {"ok": False, "msg": f"HTTP {exc.code}"} except Exception as exc: return {"ok": False, "msg": str(exc)}