Separate config models from loader

- configs/models.py: AppConfig and all section dataclasses
- configs/load.py: pure loading logic (yaml, env overrides)
- config = load_config() singleton for consumers
This commit is contained in:
2026-06-10 10:24:45 +08:00
parent f9384f7bc1
commit ae52578ed7
2 changed files with 126 additions and 73 deletions
+63
View File
@@ -0,0 +1,63 @@
from __future__ import annotations
from dataclasses import dataclass, field
from pathlib import Path
@dataclass
class ServerConfig:
host: str = "0.0.0.0"
port: int = 8765
max_ws_size: int = 10_485_760
@dataclass
class VideoConfig:
process_every_n_frames: int = 1
@dataclass
class ModelConfig:
path: str = ""
prefer_gpu: bool = True
@property
def resolved_path(self) -> str:
if self.path:
return self.path
return str(Path(__file__).resolve().parent.parent / "pose_models" / "pose_landmarker_full.task")
@dataclass
class DeadBugConfig:
visibility_threshold: float = 0.45
extension_confirm_frames: int = 4
reset_confirm_frames: int = 3
@dataclass
class AudioConfig:
rep_announcer_enabled: bool = True
rep_announcer_rate: int = 185
rep_announcer_volume: float = 1.0
@dataclass
class LoggingConfig:
dir: str = "logs"
rotation: str = "20 MB"
retention: str = "14 days"
@property
def dir_path(self) -> Path:
return Path(__file__).resolve().parent.parent / self.dir
@dataclass
class AppConfig:
server: ServerConfig = field(default_factory=ServerConfig)
video: VideoConfig = field(default_factory=VideoConfig)
model: ModelConfig = field(default_factory=ModelConfig)
dead_bug: DeadBugConfig = field(default_factory=DeadBugConfig)
audio: AudioConfig = field(default_factory=AudioConfig)
logging: LoggingConfig = field(default_factory=LoggingConfig)