from __future__ import annotations import dataclasses from pathlib import Path from typing import Any import yaml from configs.models import ( AppConfig, AudioConfig, DeadBugConfig, LoggingConfig, ModelConfig, ServerConfig, VideoConfig, ) _PROJECT_ROOT = Path(__file__).resolve().parent.parent _SECTION_CLASS = { "server": ServerConfig, "video": VideoConfig, "model": ModelConfig, "dead_bug": DeadBugConfig, "audio": AudioConfig, "logging": LoggingConfig, } def _dict_to_dataclass(cls: type, data: dict[str, Any] | None) -> dict[str, Any]: if data is None: return {} field_names = {f.name for f in dataclasses.fields(cls)} return {k: v for k, v in data.items() if k in field_names} def _read_yaml(path: Path) -> dict[str, Any]: if not path.exists(): return {} with open(path, encoding="utf-8") as f: return yaml.safe_load(f) or {} def load_config(config_path: str | Path | None = None) -> AppConfig: if config_path is None: config_path = _PROJECT_ROOT / "config.yaml" raw = _read_yaml(Path(config_path)) return AppConfig(**{ section: cls(**_dict_to_dataclass(cls, raw.get(section))) for section, cls in _SECTION_CLASS.items() }) config = load_config()