from __future__ import annotations from pathlib import Path from pydantic_settings import BaseSettings, SettingsConfigDict _SERVER_DIR = Path(__file__).parent.parent _ROOT_DIR = _SERVER_DIR.parent class Settings(BaseSettings): # HTTP server backend_ws_port: int = 7860 # Auth — comma-separated app API keys. Acts as a rate-limit token # (extension embeds one), not a security boundary; see ADR 0004. api_keys: str = "" admin_key: str = "" # Groq groq_api_key: str = "" groq_model: str = "llama-3.3-70b-versatile" groq_timeout_seconds: float = 12.0 # Rate limits (slowapi). Strings in slowapi's "N/period" form. rate_limit_per_ip: str = "30/minute" rate_limit_per_key: str = "500/minute" # CORS — overridable for self-hosters. cors_allowed_origins: str = "chrome-extension://*,http://localhost:*" # Optional version label surfaced by /health. app_version: str = "2.0.0" model_config = SettingsConfigDict( env_file=(_ROOT_DIR / ".env", _SERVER_DIR / ".env"), extra="ignore", ) @property def api_keys_list(self) -> list[str]: return [k.strip() for k in self.api_keys.split(",") if k.strip()] @property def cors_origins_list(self) -> list[str]: return [o.strip() for o in self.cors_allowed_origins.split(",") if o.strip()] settings = Settings()