{"record":{"id":"ce5e914a44a864ec","repo":"ZhuLinsen/daily_stock_analysis","slug":"futu-openapi-sdk-pip-install-futu-api","errorCode":null,"errorMessage":"未安装 Futu OpenAPI SDK；请先执行 `pip install \"futu-api==10.8.6808\"`。","messagePattern":"未安装 Futu OpenAPI SDK；请先执行 `pip install \"futu-api==10\\.8\\.6808\"`。","errorType":"exception","errorClass":"FutuPortfolioError","httpStatus":null,"severity":"error","filePath":"src/brokers/futu/portfolio.py","lineNumber":67,"sourceCode":"_STATIC_INFO_BATCH_SIZE = 100\n\n\ndef _load_futu_api() -> _FutuApi:\n    \"\"\"Import the supported Futu SDK surface or raise an actionable error.\"\"\"\n\n    try:\n        from futu import (\n            Market,\n            OpenQuoteContext,\n            OpenSecTradeContext,\n            RET_OK,\n            SecurityFirm,\n            SecurityType,\n            TrdEnv,\n            TrdMarket,\n        )\n    except ImportError as exc:\n        raise FutuPortfolioError(\n            \"未安装 Futu OpenAPI SDK；请先执行 \"\n            \"`pip install \\\"futu-api==10.8.6808\\\"`。\"\n        ) from exc\n    except Exception as exc:  # noqa: BLE001 - SDK import initializes its file logger\n        raise FutuPortfolioError(f\"加载 Futu OpenAPI SDK 失败: {exc}\") from exc\n\n    return _FutuApi(\n        OpenQuoteContext=OpenQuoteContext,\n        OpenSecTradeContext=OpenSecTradeContext,\n        Market=Market,\n        RET_OK=RET_OK,\n        SecurityFirm=SecurityFirm,\n        SecurityType=SecurityType,\n        TrdEnv=TrdEnv,\n        TrdMarket=TrdMarket,\n    )\n\n","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/brokers/futu/portfolio.py#L49-L85","documentation":"FutuPortfolioError raised in src/brokers/futu/portfolio.py:67 when importing the pinned Futu OpenAPI SDK ('from futu import ...') fails with ImportError. The module deliberately imports the SDK lazily so the rest of the app runs without Futu support; this error means futu-api is missing from the environment (the project pins futu-api==10.8.6808).","triggerScenarios":"Invoking the Futu portfolio source (e.g. fetching a Futu-sourced portfolio/positions) in an environment where 'pip install futu-api==10.8.6808' was never run; a venv/Docker image built without the optional broker extras; a CI job that installs only requirements.txt while futu-api is optional.","commonSituations":"Fresh clone/deploy without the broker dependency; switching virtualenvs; Docker images for the web/API tier that omit the optional SDK; dependency cleanup that removed the pin.","solutions":["Install the pinned SDK exactly as the message says: pip install \"futu-api==10.8.6808\" (keep the pin; the code's IPv4 and table handling are written against this version).","Verify with 'python -c \"import futu; print(futu.__version__)\"' in the same interpreter/venv the app runs under.","If Futu is intentionally unused in that deployment, avoid triggering the Futu portfolio path (do not set it as the portfolio source) so the lazy import never runs.","If deploying via Docker, add the pin to the image's requirements so rebuilds are reproducible."],"exampleFix":"# before: runtime failure\nfrom src.brokers.futu import portfolio  # later raises FutuPortfolioError\n\n# after: explicit capability check at startup\ntry:\n    import futu  # noqa: F401\n    FUTU_AVAILABLE = True\nexcept ImportError:\n    FUTU_AVAILABLE = False\n\nif not FUTU_AVAILABLE:\n    raise SystemExit(\"Futu source requires: pip install 'futu-api==10.8.6808'\")","handlingStrategy":"validation","validationCode":"def futu_sdk_available() -> bool:\n    try:\n        import futu  # noqa: F401\n        return True\n    except ImportError:\n        return False\n\nassert futu_sdk_available(), \"pip install 'futu-api==10.8.6808'\"","typeGuard":null,"tryCatchPattern":"try:\n        from src.brokers.futu import portfolio\n    except Exception as exc:  # module wraps import errors in FutuPortfolioError\n        if '未安装 Futu OpenAPI SDK' in str(exc):\n            log.warning('Futu unavailable: install futu-api==10.8.6808; skipping broker source')\n        else:\n            raise","preventionTips":["Declare the pinned futu-api requirement wherever the Futu source is enabled (requirements/deploy docs).","Gate the Futu portfolio source on an import probe at startup instead of failing mid-run.","Keep the exact pin (10.8.6808); the module's guards target that version."],"tags":["dependency","futu","import","setup"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}