deps.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. # -*- coding: utf-8 -*-
  2. r"""算法服务的**依赖兜底**:离线目标机没有网、`wheels/` 里也没有 FastAPI 的轮子 ⇒ 用随包的 `vendor/pyfastapi/`。
  3. 实逮(2026-09-29):开发机的 `.venv` 是 `include-system-site-packages=true`,fastapi/uvicorn 实际来自
  4. 系统 Python;所以"能跑"不等于"随包能跑"。本模块在 `import fastapi` 失败时把 `vendor/pyfastapi` 插进
  5. `sys.path`,让服务在**纯 stdlib + 随包依赖**的环境下也能起来。
  6. """
  7. from __future__ import annotations
  8. import pathlib
  9. import sys
  10. try:
  11. from app_common.app_common_guanlan.api import install_root as _install_root
  12. except ImportError: # 包结构异常时按位置上跳兜底
  13. from pathlib import Path as _P
  14. def _install_root(_f): # type: ignore[no-redef]
  15. return _P(_f).resolve().parents[4]
  16. def vendor_dir() -> pathlib.Path:
  17. return _install_root(__file__) / 'vendor' / 'pyfastapi'
  18. def ensure_fastapi() -> tuple[object, object]:
  19. """→ (fastapi, uvicorn);缺依赖时依次尝试:本地已装 → vendor/ 随包。"""
  20. d = vendor_dir()
  21. if d.is_dir() and str(d) not in sys.path:
  22. sys.path.append(str(d)) # 放在最后:已装的优先
  23. try:
  24. import fastapi
  25. import uvicorn
  26. return fastapi, uvicorn
  27. except ImportError as e: # noqa: BLE001
  28. raise SystemExit(
  29. f'[X] 算法服务缺运行期依赖: {e}\n'
  30. f' 随包目录: {d}(存在: {d.is_dir()})\n'
  31. ' 修法: 在有网机器上跑 python scripts/fetch_offline_deps.py all 把 fastapi/uvicorn 打进 '
  32. 'wheels/,或把 site-packages 里的 fastapi·uvicorn·pydantic·starlette·anyio·h11·sniffio·'
  33. 'annotated_types·typing_extensions·typing_inspection·annotated_doc·idna·click·colorama 复制到 '
  34. f'{d}')
  35. __all__ = ['ensure_fastapi', 'vendor_dir']