Spaces:
Running
Running
| """Shared yaml config path resolver — works for monorepo dev + flat container deploy. | |
| 【這個模組在做什麼?】 | |
| ssrf_policy.py + pricing_config.py 都需要讀 monorepo 共用的 yaml | |
| (packages/ssrf-policy/policy.yaml、packages/pricing-config/*.yaml)。 | |
| 本機 dev 跑 Python 時 __file__ 在 apps/ml-service/src/,往上四層 (parents[3]) | |
| 正好是 monorepo root。但 HF Spaces / Render 部署是把 apps/ml-service/* 攤平 | |
| 當 repo root,container 內 __file__ = /app/src/X.py,parents[3] 直接 IndexError。 | |
| 【這個 helper 的作法】 | |
| - 先試 monorepo layout(parents[3] / packages/ 存在) | |
| - fallback 到 container 的 _shared/ 目錄(GitHub Actions sync 時 stage 進去 | |
| 的 yaml 副本,Dockerfile 把它 COPY 到 /app/_shared/) | |
| - 都找不到就 raise,避免 silent fallback 讓 SSRF policy 變空白規則 | |
| 【為什麼不用 env var override】 | |
| ssrf_policy.py 已有 SSRF_POLICY_PATH,但要 caller 自己拼路徑——HF Variables / | |
| Render env 容易設錯。這個 helper 走「資料隨 image 走」原則,少一個運維變數。 | |
| """ | |
| from __future__ import annotations | |
| from pathlib import Path | |
| def shared_packages_dir() -> Path: | |
| """Return the directory that holds shared monorepo `packages/*` yaml configs. | |
| Resolution order: | |
| 1. **Monorepo layout**: `<repo>/packages/` exists relative to this file | |
| (used for local `pnpm dev` / `uv run` workflows). | |
| 2. **Flat container layout**: `<container_root>/_shared/` exists | |
| (sync-hf-space.yml stages monorepo packages here before upload; | |
| Dockerfile COPYs it into /app/_shared/). | |
| Raises: | |
| FileNotFoundError if neither layout has the expected directory. | |
| """ | |
| here = Path(__file__).resolve() | |
| # Monorepo: apps/ml-service/src/_shared_paths.py → parents[3] = repo root | |
| # Path.resolve().parents is finite; container path /app/src/X.py only has 3 | |
| # parents (/app/src, /app, /), so probe length first to avoid IndexError. | |
| if len(here.parents) > 3: | |
| candidate = here.parents[3] / "packages" | |
| if candidate.is_dir(): | |
| return candidate | |
| # Container: /app/src/_shared_paths.py → parents[1] = /app | |
| container_candidate = here.parents[1] / "_shared" | |
| if container_candidate.is_dir(): | |
| return container_candidate | |
| raise FileNotFoundError( | |
| "Cannot locate shared packages directory. Tried monorepo " | |
| f"({here.parents[3] / 'packages' if len(here.parents) > 3 else '<n/a>'}) " | |
| f"and container fallback ({container_candidate}). " | |
| "Ensure either the monorepo layout is intact or the deployment image " | |
| "has _shared/ populated by the sync workflow." | |
| ) | |