"""Settings loaded from backend/.env (or real environment variables in prod).""" from functools import cached_property, lru_cache from pathlib import Path from pydantic_settings import BaseSettings, SettingsConfigDict BACKEND_DIR = Path(__file__).resolve().parent # Repo root in dev (backend/ sits under finsight-v3/). In Docker the image root # is /app, so parent would wrongly resolve to /. ROOT = BACKEND_DIR.parent def data_root() -> Path: """Directory that local_path values are relative to.""" if (BACKEND_DIR / "data").is_dir(): return BACKEND_DIR parent = BACKEND_DIR.parent if (parent / "data").is_dir(): return parent return BACKEND_DIR def resolve_data_path(local_path: str) -> Path: """Normalize DB paths (Windows backslashes) and resolve under data_root.""" return data_root() / local_path.replace("\\", "/") class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=BACKEND_DIR / ".env", env_file_encoding="utf-8", extra="ignore" ) openai_api_key: str = "" openai_model: str = "gpt-4o-mini" database_url: str = "" supabase_url: str = "" supabase_service_role_key: str = "" embedding_model: str = "sentence-transformers/all-MiniLM-L6-v2" retrieval_k: int = 6 max_tool_rounds: int = 6 # Comma-separated frontend origins. Plain string (not list) so pydantic # doesn't JSON-decode a bare URL at startup. cors_origins: str = "http://localhost:8080,http://127.0.0.1:8080,http://localhost:5173" sec_edgar_user_agent: str = "" @cached_property def cors_origin_list(self) -> list[str]: return [origin.strip() for origin in self.cors_origins.split(",") if origin.strip()] @lru_cache def get_settings() -> Settings: return Settings()