| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- import os
- from dataclasses import dataclass
- from functools import lru_cache
- from dotenv import load_dotenv
- load_dotenv()
- def _get_bool(name: str, default: bool) -> bool:
- value = os.getenv(name)
- if value is None:
- return default
- return value.strip().lower() in {"1", "true", "yes", "on"}
- def _get_int(name: str, default: int) -> int:
- """从环境变量中读取整数配置。"""
- value = os.getenv(name)
- if value is None:
- return default
- try:
- return int(value)
- except ValueError:
- return default
- def _get_float(name: str, default: float) -> float:
- """从环境变量中读取浮点数配置。"""
- value = os.getenv(name)
- if value is None:
- return default
- try:
- return float(value)
- except ValueError:
- return default
- @dataclass(frozen=True)
- class AppSettings:
- """
- FastAPI 服务本身的运行配置。
- """
- title: str
- version: str
- description: str
- host: str
- port: int
- @classmethod
- def from_env(cls) -> "AppSettings":
- return cls(
- title=os.getenv("APP_TITLE", "Raspberry Pi Camera API"),
- version=os.getenv("APP_VERSION", "0.1.0"),
- description=os.getenv(
- "APP_DESCRIPTION",
- "用于树莓派相机抓拍的 FastAPI 服务。",
- ),
- host=os.getenv("APP_HOST", "0.0.0.0"),
- port=_get_int("APP_PORT", 8002)
- )
- @dataclass(frozen=True)
- class CameraSettings:
- """
- 树莓派相机的集中配置。
- """
- camera_index: int
- width: int
- height: int
- frame_format: str
- jpeg_quality: int
- warmup_seconds: float
- enable_continuous_autofocus: bool
- enable_auto_white_balance: bool
- @classmethod
- def from_env(cls) -> "CameraSettings":
- return cls(
- camera_index=_get_int("CAMERA_INDEX", 0),
- width=_get_int("CAMERA_WIDTH", 2048),
- height=_get_int("CAMERA_HEIGHT", 2048),
- frame_format=os.getenv("CAMERA_FRAME_FORMAT", "RGB888"),
- jpeg_quality=_get_int("CAMERA_JPEG_QUALITY", 95),
- warmup_seconds=_get_float("CAMERA_WARMUP_SECONDS", 0.05),
- enable_continuous_autofocus=_get_bool(
- "CAMERA_ENABLE_CONTINUOUS_AUTOFOCUS",
- True,
- ),
- enable_auto_white_balance=_get_bool(
- "CAMERA_ENABLE_AUTO_WHITE_BALANCE",
- True,
- ),
- )
- @dataclass(frozen=True)
- class Settings:
- """项目总配置入口,统一汇总服务配置与相机配置。"""
- app: AppSettings
- camera: CameraSettings
- @lru_cache(maxsize=1)
- def get_settings() -> Settings:
- """
- 返回单例配置对象。
- 使用缓存的原因是:
- 1. 避免每次请求都重复读取环境变量。
- 2. 让整个项目里的配置来源保持一致。
- """
- return Settings(
- app=AppSettings.from_env(),
- camera=CameraSettings.from_env(),
- )
- settings = get_settings()
|