Vue 3 + FastAPI Webapp zur Anzeige von Filebot/n8n-Medienmetadaten aus PostgreSQL. Enthält Frontend, API, Nginx-Config, SQL-Migrationen und Docker-Compose-Setup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
50 lines
1.4 KiB
Python
50 lines
1.4 KiB
Python
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
|