{"record":{"id":"f1fa961fd66932bc","repo":"ZhuLinsen/daily_stock_analysis","slug":"pytdx","errorCode":null,"errorMessage":"pytdx 库未安装","messagePattern":"pytdx 库未安装","errorType":"exception","errorClass":"DataFetchError","httpStatus":null,"severity":"error","filePath":"data_provider/pytdx_fetcher.py","lineNumber":205,"sourceCode":"        Pytdx 连接上下文管理器\n        \n        确保：\n        1. 进入上下文时自动连接\n        2. 退出上下文时自动断开\n        3. 异常时也能正确断开\n        \n        使用示例：\n            with self._pytdx_session() as api:\n                # 在这里执行数据查询\n        \"\"\"\n        if self._is_in_connection_cooldown():\n            raise DataSourceUnavailableError(\n                f\"Pytdx temporarily unavailable: {self._last_unavailable_reason or 'connection cooldown'}\"\n            )\n\n        TdxHq_API = self._get_pytdx()\n        if TdxHq_API is None:\n            raise DataFetchError(\"pytdx 库未安装\")\n        \n        api = TdxHq_API()\n        connected = False\n        \n        try:\n            # 尝试连接服务器（自动选择最优）\n            for i in range(len(self._hosts)):\n                host_idx = (self._current_host_idx + i) % len(self._hosts)\n                host, port = self._hosts[host_idx]\n                \n                try:\n                    if api.connect(host, port, time_out=5):\n                        connected = True\n                        self._current_host_idx = host_idx\n                        logger.debug(f\"Pytdx 连接成功: {host}:{port}\")\n                        break\n                except Exception as e:\n                    logger.debug(f\"Pytdx 连接 {host}:{port} 失败: {e}\")","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/data_provider/pytdx_fetcher.py#L187-L223","documentation":"DataFetchError raised inside PytdxFetcher._pytdx_session() when self._get_pytdx() returns None, i.e. the optional pytdx package could not be imported. pytdx is an optional dependency of this project, so the fetcher degrades to this explicit error instead of an ImportError at module load.","triggerScenarios":"Any PytdxFetcher data or realtime-quote call when pytdx is not installed in the current interpreter (missing from requirements, different venv, slim Docker image without the extras).","commonSituations":"Fresh environment where only requirements.txt was installed but pytdx is an optional extra; running in CI or a container built without pytdx; venv mismatch where the package is installed elsewhere.","solutions":["Install pytdx into the active environment: pip install pytdx.","If pytdx is deliberately not shipped (e.g. slim deployments), remove PytdxFetcher from the provider priority chain so it is never selected.","Check at startup whether pytdx is importable and log/skip PytdxFetcher registration when it is not."],"exampleFix":"# before\n# pytdx not installed -> DataFetchError(\"pytdx 库未安装\") at request time\n\n# after\npip install pytdx\n# or at provider registration time:\ntry:\n    import pytdx  # noqa: F401\n    register_fetcher(PytdxFetcher())\nexcept ImportError:\n    logger.warning(\"pytdx not installed; PytdxFetcher disabled\")","handlingStrategy":"type-guard","validationCode":"def pytdx_available() -> bool:\n    try:\n        import pytdx  # noqa: F401\n        return True\n    except ImportError:\n        return False","typeGuard":"def pytdx_available() -> bool:\n    \"\"\"True when the optional pytdx package is importable.\"\"\"\n    try:\n        import pytdx  # noqa: F401\n        return True\n    except ImportError:\n        return False","tryCatchPattern":"try:\n    df = pytdx_fetcher.get_stock_data(code, start, end)\nexcept DataFetchError as e:\n    if \"未安装\" in str(e):\n        df = akshare_fetcher.get_stock_data(code, start, end)\n    else:\n        raise","preventionTips":["Register optional-dependency fetchers only when their import succeeds.","Pin optional extras in deployment docs and Docker images.","Fail loudly at startup (log skipped providers) instead of discovering missing packages at request time."],"tags":["pytdx","missing-dependency","optional-dependency","environment"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}