config.py•1.45 kB
from functools import lru_cache
from pathlib import Path
from dotenv import dotenv_values
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
db_address: str
db_port: int = 5432
db_name: str
db_user: str
db_password: str
mcp_api_key: str | None = None
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False,
)
@property
def conninfo(self) -> str:
return (
f"host={self.db_address} port={self.db_port} dbname={self.db_name} "
f"user={self.db_user} password={self.db_password}"
)
@lru_cache(maxsize=1)
def load_settings() -> Settings:
env_path = Path(".env")
if not env_path.exists():
raise FileNotFoundError("Missing .env file with DB settings")
# python-dotenv accepts both KEY= and KEY: syntax; we load explicitly to
# tolerate either format, then feed values into Settings.
raw = dotenv_values(env_path)
normalized = {}
for key, value in raw.items():
if value is None:
continue
lower = key.lower()
if lower.startswith("db_") or lower == "mcp_api_key":
normalized[lower] = value
if "db_port" in normalized:
try:
normalized["db_port"] = int(normalized["db_port"])
except ValueError:
pass
return Settings(**normalized)