from pathlib import Path from pydantic_settings import BaseSettings, SettingsConfigDict # Resolved next to API/.env rather than the process working directory, so the # same config loads whether you run `python main.py` from API/ or # `uvicorn API.main:app` from the repo root. ENV_FILE = Path(__file__).resolve().parents[1] / ".env" class Settings(BaseSettings): """Precedence: real environment variables > API/.env > defaults below.""" model_config = SettingsConfigDict( env_file=ENV_FILE, env_file_encoding="utf-8", extra="ignore", ) # MongoDB mongo_uri: str = "mongodb://admin:30e51UdjHo9YAiLF@127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=8000&connectTimeoutMS=8000&socketTimeoutMS=20000&authSource=admin" mongo_db: str = "ighub" # Server (consumed by main.py's __main__ block) api_host: str = "127.0.0.1" api_port: int = 8000 api_reload: bool = True # App api_title: str = "IGHub Users API" api_prefix: str = "/api" cors_origins: str = "*" # Shared secret every client must send as X-API-Key. # # Empty (the default) leaves the API open, which is fine bound to localhost # and is what keeps existing local setups working. Set it before the service # is reachable from anywhere else: without it, anyone who can reach the URL # can read and modify every user record. api_key: str = "9885887181" # Interactive docs expose the whole surface; turn them off in production. docs_enabled: bool = True @property def cors_origin_list(self) -> list[str]: return [o.strip() for o in self.cors_origins.split(",") if o.strip()] @property def auth_required(self) -> bool: return bool(self.api_key.strip()) @property def env_file_loaded(self) -> bool: return ENV_FILE.is_file() @property def safe_mongo_uri(self) -> str: """mongo_uri with any user:password stripped, for logging.""" if "@" not in self.mongo_uri: return self.mongo_uri scheme, _, rest = self.mongo_uri.partition("://") return f"{scheme}://***@{rest.rpartition('@')[2]}" settings = Settings()