{"record":{"id":"29776b9df2ed063b","repo":"HKUDS/Vibe-Trading","slug":"futu-api-is-not-installed-run-pip-install-futu-a","errorCode":null,"errorMessage":"futu-api is not installed; run `pip install futu-api`.","messagePattern":"futu-api is not installed; run `pip install futu-api`\\.","errorType":"exception","errorClass":"FutuDependencyError","httpStatus":null,"severity":"error","filePath":"agent/src/trading/connectors/futu/sdk.py","lineNumber":977,"sourceCode":"        return f\"Futu unlock_trade failed: {data}\"\n    return None\n\n\ndef _order_error(cfg: FutuConfig, message: str) -> dict[str, Any]:\n    \"\"\"Build a fail-closed order error envelope tagged with the profile.\"\"\"\n    return {\"status\": \"error\", \"error\": message, \"profile\": cfg.profile}\n\n\n# ---------------------------------------------------------------------------\n# SDK plumbing\n# ---------------------------------------------------------------------------\n\n\ndef _require_futu() -> ModuleType:\n    try:\n        import futu  # type: ignore\n    except ModuleNotFoundError as exc:\n        raise FutuDependencyError(\"futu-api is not installed; run `pip install futu-api`.\") from exc\n    return futu\n\n\ndef tcp_port_open(host: str, port: int, timeout: float = 0.5) -> bool:\n    \"\"\"Return whether a TCP socket accepts connections.\"\"\"\n    try:\n        with socket.create_connection((host, int(port)), timeout=timeout):\n            return True\n    except OSError:\n        return False\n\n\ndef _assert_gateway(cfg: FutuConfig) -> None:\n    \"\"\"Fail with a clean error when the local OpenD gateway is unreachable.\"\"\"\n    if not tcp_port_open(cfg.host, cfg.port):\n        raise FutuConfigError(\n            f\"No Futu OpenD gateway is listening at {cfg.host}:{cfg.port}. \"\n            \"Start OpenD, log in, and confirm the API port.\"","sourceCodeStart":959,"sourceCodeEnd":995,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/futu/sdk.py#L959-L995","documentation":"Raised by _require_futu when the optional 'futu-api' Python package is not installed. All Futu SDK functions that need the real API gate through this check.","triggerScenarios":"Calling get_account_snapshot/get_positions/get_historical_bars etc. in an environment where `import futu` fails; futu_available() exists to probe this.","commonSituations":"Fresh virtualenv without the optional dependency, dependency not pinned in requirements, production image missing the extra.","solutions":["pip install futu-api","Add futu-api to your project dependencies","Use futu_available() to feature-gate Futu code paths"],"exampleFix":"# before\nsnapshot = get_account_snapshot()  # ModuleNotFoundError wrapped\n# after\nif futu_available():\n    snapshot = get_account_snapshot()","handlingStrategy":"type-guard","validationCode":"from src.trading.connectors.futu.sdk import futu_available\nif not futu_available():\n    disable_futu_features()","typeGuard":"def futu_available() -> bool:\n    try:\n        import futu  # noqa: F401\n        return True\n    except ModuleNotFoundError:\n        return False","tryCatchPattern":"try:\n    snap = get_account_snapshot()\nexcept FutuDependencyError:\n    logger.warning('futu-api missing; skipping Futu integration')","preventionTips":["Gate all Futu code paths behind futu_available()","Pin futu-api in requirements for deployments that use Futu"],"tags":["futu","dependency","import"],"backgroundTag":"missing-optional-dependency","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}