{"record":{"id":"7577c89cdcecf4f6","repo":"HKUDS/Vibe-Trading","slug":"tushare-import-failed-exc","errorCode":null,"errorMessage":"tushare import failed: {exc}","messagePattern":"tushare import failed: (.+?)","errorType":"exception","errorClass":"TushareFallbackUnavailable","httpStatus":null,"severity":"error","filePath":"agent/src/tools/tushare_fallbacks.py","lineNumber":29,"sourceCode":"from typing import Any\n\nfrom src.config.accessor import get_env_config\n\n_TUSHARE_TOKEN_PLACEHOLDERS = {\"\", \"your-tushare-token\"}\n\n\nclass TushareFallbackUnavailable(RuntimeError):\n    \"\"\"Raised when the optional Tushare fallback cannot be used.\"\"\"\n\n\ndef _pro_api() -> Any:\n    token = get_env_config().data.tushare_token.strip()\n    if token in _TUSHARE_TOKEN_PLACEHOLDERS:\n        raise TushareFallbackUnavailable(\"TUSHARE_TOKEN is not configured\")\n    try:\n        import tushare as ts\n    except Exception as exc:  # noqa: BLE001 - import errors vary by install\n        raise TushareFallbackUnavailable(f\"tushare import failed: {exc}\") from exc\n    return ts.pro_api(token)\n\n\ndef _records(frame: Any) -> list[dict[str, Any]]:\n    if frame is None:\n        return []\n    if bool(getattr(frame, \"empty\", False)):\n        return []\n    if hasattr(frame, \"to_dict\"):\n        rows = frame.to_dict(\"records\")\n        return [row for row in rows if isinstance(row, dict)]\n    if isinstance(frame, list):\n        return [row for row in frame if isinstance(row, dict)]\n    return []\n\n\ndef _compact_date(value: str) -> str:\n    digits = str(value).strip().replace(\"-\", \"\")","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/tushare_fallbacks.py#L11-L47","documentation":"_pro_api raises this when `import tushare` fails while building the fallback client. The tushare package is an optional dependency in this project, so any ImportError/ModuleNotFoundError during import is wrapped in TushareFallbackUnavailable instead of crashing the caller. The underlying exception text is chained and included in the message.","triggerScenarios":"Calling any of fetch_fund_flow, fetch_dragon_tiger, fetch_northbound_flow, or fetch_margin_trading on an environment where the tushare package is not installed, is installed for a different interpreter/virtualenv, or fails at import time due to a broken dependency (e.g. missing pandas or an incompatible numpy).","commonSituations":"Deploying without the extras/optional dependency group that includes tushare; running under a different Python than the one used by pip; a transitive dependency version conflict breaking the import; partially corrupted site-packages.","solutions":["Install tushare into the same interpreter/venv the agent runs on (e.g. pip install tushare or add it to the optional extras)","If the import error mentions another package (pandas, numpy), upgrade/align that dependency","Confirm with `python -c \"import tushare\"` in the runtime environment","If Tushare is intentionally unused, catch TushareFallbackUnavailable and skip the fallback path"],"exampleFix":"# before: package missing in runtime env\npip install tushare  # skipped / wrong venv\n\n# after\npip install tushare\npython -c \"import tushare; print(tushare.__version__)\"","handlingStrategy":"try-catch","validationCode":"def tushare_importable() -> bool:\n    try:\n        import tushare  # noqa: F401\n        return True\n    except Exception:\n        return False\n\nif tushare_importable() and tushare_ready():\n    data = fetch_dragon_tiger(trade_date=d)\nelse:\n    data = primary_source(d)","typeGuard":null,"tryCatchPattern":"try:\n    data = fetch_margin_trading(symbol, days=d)\nexcept TushareFallbackUnavailable as exc:\n    if str(exc).startswith('tushare import failed'):\n        # optional dependency missing in this env; degrade gracefully\n        data = primary_source(symbol, days=d)\n    else:\n        raise","preventionTips":["Pin tushare (and its pandas/numpy deps) in the lockfile or an extras group","Smoke-test imports in the deployed interpreter: python -c 'import tushare'","Never assume optional dependencies exist — guard or catch before relying on fallback data"],"tags":["tushare","import-error","dependencies","virtualenv","fallback"],"backgroundTag":"module-not-found","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}