| from __future__ import annotations |
|
|
| import os |
| from pathlib import Path |
| from typing import Optional |
| from dotenv import load_dotenv |
|
|
| load_dotenv() |
|
|
| ROOT_DIR = Path(__file__).resolve().parents[1] |
|
|
|
|
| def _resolve_path(value: Optional[str], default: Path) -> Path: |
| if value: |
| return Path(value).expanduser().resolve() |
| return default.resolve() |
|
|
|
|
| def _get_int(name: str, default: int) -> int: |
| value = os.getenv(name) |
| if value is None: |
| return default |
| try: |
| return int(value) |
| except ValueError: |
| return default |
|
|
|
|
| def _get_float(name: str, default: float) -> float: |
| value = os.getenv(name) |
| if value is None: |
| return default |
| try: |
| return float(value) |
| except ValueError: |
| return default |
|
|
|
|
| class Settings: |
| def __init__(self) -> None: |
| self.faq_data_path: Path = _resolve_path( |
| os.getenv("FAQ_DATA_PATH"), ROOT_DIR / "faq_kb.json" |
| ) |
| self.vectorstore_dir: Path = _resolve_path( |
| os.getenv("VECTORSTORE_DIR"), ROOT_DIR / "vectorstore" |
| ) |
| self.vectorstore_index_name: str = os.getenv("VECTORSTORE_INDEX_NAME", "index") |
| self.top_k: int = _get_int("TOP_K", 5) |
| self.google_genai_model: str = os.getenv( |
| "GOOGLE_GENAI_MODEL", "gemini-2.5-flash" |
| ) |
| self.google_genai_temperature: float = _get_float( |
| "GOOGLE_GENAI_TEMPERATURE", 0.0 |
| ) |
| self.google_genai_api_key: Optional[str] = os.getenv("GOOGLE_GENAI_API_KEY") |
| self.hf_token: Optional[str] = os.getenv("HF_TOKEN") |
|
|
| self._validate() |
| self.vectorstore_dir.mkdir(parents=True, exist_ok=True) |
| if self.hf_token: |
| os.environ.setdefault("HUGGINGFACEHUB_API_TOKEN", self.hf_token) |
|
|
| def _validate(self) -> None: |
| if not self.faq_data_path.exists(): |
| raise FileNotFoundError( |
| f"FAQ file not found: {self.faq_data_path}. " |
| "Please put faq_kb.json in the repo root or set FAQ_DATA_PATH in .env." |
| ) |
|
|
| settings = Settings() |
|
|