Decoder2704/python-chatbot-jay
0
1"""2Single source of truth for backend layout.3 4All locations are derived from this file's path (``backend/app/paths.py``), never from5the process current working directory — so Hugging Face Spaces, Docker, and local runs6behave the same as long as ``backend/app`` is laid out correctly.7"""8 9from __future__ import annotations10 11import os12from pathlib import Path13 14# Anchor: backend/app/paths.py -> backend/ is two levels up from this file15_APP_DIR = Path(__file__).resolve().parent16BACKEND_DIR = _APP_DIR.parent17REPO_ROOT = BACKEND_DIR.parent18DATA_DIR = BACKEND_DIR / "data"19ARTIFACTS_DIR = BACKEND_DIR / "artifacts"20 21# Resolved absolute paths (files may not exist yet; existence is checked at load time)22ARTIFACT_VECTORIZER_PATH = (ARTIFACTS_DIR / "vectorizer.pkl").resolve()23ARTIFACT_QUESTION_VECTORS_PATH = (ARTIFACTS_DIR / "question_vectors.pkl").resolve()24ARTIFACT_CHATBOT_DF_PATH = (ARTIFACTS_DIR / "chatbot_df.pkl").resolve()25 26RETRIEVAL_ARTIFACT_FILES: tuple[tuple[str, Path], ...] = (27 ("vectorizer.pkl", ARTIFACT_VECTORIZER_PATH),28 ("question_vectors.pkl", ARTIFACT_QUESTION_VECTORS_PATH),29 ("chatbot_df.pkl", ARTIFACT_CHATBOT_DF_PATH),30)31PYBOT_DATA_DIR = REPO_ROOT / "pybot_data"32SCRIPTS_DIR = BACKEND_DIR / "scripts"33DEBUG_DIR = BACKEND_DIR / "debug"34 35 36def resolve_frontend_dist_dir() -> Path | None:37 """38 Directory containing the React production build (e.g. ``index.html``, ``assets/``).39 40 Resolution order:41 42 1. ``FRONTEND_DIST_DIR`` or ``FRONTEND_BUILD_DIR`` env (absolute or relative to cwd)43 2. ``<repo>/frontend/dist`` (Vite default)44 3. ``<repo>/frontend/build`` (CRA default)45 4. ``backend/static/dist`` (Docker / copy-into-backend layouts)46 47 Returns ``None`` if no existing directory is found.48 """49 for key in ("FRONTEND_DIST_DIR", "FRONTEND_BUILD_DIR"):50 raw = os.environ.get(key, "").strip()51 if raw:52 p = Path(raw).expanduser().resolve()53 return p if p.is_dir() else None54 55 candidates = (56 REPO_ROOT / "frontend" / "dist",57 REPO_ROOT / "frontend" / "build",58 BACKEND_DIR / "static" / "dist",59 )60 for c in candidates:61 if c.is_dir():62 return c63 return None64 65 66def ensure_data_and_artifacts_dirs() -> None:67 """Ensure ``backend/data`` and ``backend/artifacts`` exist (idempotent)."""68 DATA_DIR.mkdir(parents=True, exist_ok=True)69 ARTIFACTS_DIR.mkdir(parents=True, exist_ok=True)70 