import re from pathlib import Path from typing import Any import yaml from pydantic import AliasChoices, BaseModel, Field, field_validator IDENT_RE = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]*$") class DatabaseConfig(BaseModel): host: str = "192.168.30.186" port: int = 5432 name: str = "postgres" user: str = "postgres" password: str = "" table: str = "movie_files" # "schema" ist in YAML erlaubt; intern db_schema (Pydantic-Konflikt mit BaseModel.schema) db_schema: str = Field( default="public", validation_alias=AliasChoices("db_schema", "schema"), ) ssl: bool = False @field_validator("table", "db_schema") @classmethod def validate_identifiers(cls, v: str) -> str: if not IDENT_RE.match(v): raise ValueError(f"Ungültiger Datenbank-Identifier: {v}") return v @property def qualified_table(self) -> str: return f'"{self.db_schema}"."{self.table}"' class AppConfig(BaseModel): database: DatabaseConfig = Field(default_factory=DatabaseConfig) def load_config(path: str | Path | None = None) -> tuple[AppConfig, Path]: config_path = Path(path or "/app/config/config.yaml") if not config_path.is_file(): return AppConfig(), config_path with config_path.open(encoding="utf-8") as f: raw: dict[str, Any] = yaml.safe_load(f) or {} return AppConfig.model_validate(raw), config_path