from functools import lru_cache from typing import Literal from pydantic import Field, field_validator from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore") database_url: str = "sqlite:///./miem_workers.db" source_url: str = "https://miem.hse.ru/persons" crawl_cron: str = "0 3 * * 1" crawl_limit: int | None = None request_timeout: int = 30 request_delay_seconds: float = 1.0 parser_use_playwright: bool = False admin_username: str = "admin" admin_password: str = "admin" session_secret: str = Field(default="dev-session-secret", min_length=8) mcp_token: str = "dev-mcp-token" mcp_auth_mode: Literal["token", "oauth"] = "oauth" mcp_resource_url: str = "http://localhost:8001/mcp" mcp_oauth_issuer: str = "" mcp_oauth_audience: str = "" mcp_oauth_jwks_url: str = "" mcp_oauth_required_scope: str = "mcp:tools" @field_validator("crawl_limit", mode="before") @classmethod def empty_crawl_limit_as_none(cls, value): if value == "": return None return value def oauth_jwks_url(self) -> str: if self.mcp_oauth_jwks_url: return self.mcp_oauth_jwks_url issuer = self.mcp_oauth_issuer.rstrip("/") if not issuer: return "" return f"{issuer}/.well-known/jwks.json" @lru_cache def get_settings() -> Settings: return Settings()