"""配置管理模块 提供应用程序配置的加载和管理功能。 支持多环境配置和环境变量覆盖。 """ import os from pathlib import Path from typing import Any, Dict, Optional import yaml from pydantic import Field from pydantic_settings import BaseSettings from pydantic_settings import SettingsConfigDict class AppConfig(BaseSettings): """应用程序配置""" model_config = SettingsConfigDict( env_prefix="APP_", env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore" # 忽略额外字段 ) name: str = "音频转文字服务" version: str = "1.0.0" debug: bool = False host: str = "127.0.0.1" port: int = 7860 max_file_size: int = 2147483648 # 2GB max_files_count: int = 100 concurrent_tasks: int = 5 class OSSConfig(BaseSettings): """OSS配置""" model_config = SettingsConfigDict( env_prefix="OSS_", env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore" ) endpoint: str = Field(..., description="OSS服务端点") access_key_id: str = Field(..., description="访问密钥ID") access_key_secret: str = Field(..., description="访问密钥密码") bucket_name: str = Field(..., description="存储桶名称") upload_timeout: int = 300 url_expire_hours: int = 24 temp_prefix: str = "temp/audio" auto_cleanup_days: int = 7 class DashScopeConfig(BaseSettings): """阿里云百炼API配置""" model_config = SettingsConfigDict( env_prefix="DASHSCOPE_", env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore" ) api_key: str = Field(..., description="API密钥") base_url: str = "https://dashscope.aliyuncs.com/api/v1" model: str = "paraformer-v2" timeout: int = 300 max_retries: int = 3 retry_delay: int = 5 language_hints: list[str] = ["zh", "en"] class TaskConfig(BaseSettings): """任务配置""" model_config = SettingsConfigDict( env_prefix="TASK_", env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore" ) status_check_interval: int = 2 max_processing_time: int = 3600 # 1小时 queue_size: int = 1000 class LoggingConfig(BaseSettings): """日志配置""" model_config = SettingsConfigDict( env_prefix="LOGGING_", env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore" ) level: str = "INFO" format: str = "structured" file_max_size: str = "10MB" backup_count: int = 5 class Config: """配置管理器""" def __init__(self, environment: Optional[str] = None): """初始化配置管理器 Args: environment: 环境名称(development/production) """ self.environment = environment or os.getenv("ENVIRONMENT", "development") self._config_data = self._load_config() # 初始化各个配置模块 self.app = AppConfig(**self._config_data.get("app", {})) # OSS配置 - 直接创建实例以支持环境变量覆盖 self.oss = OSSConfig() # DashScope配置 - 直接创建实例以支持环境变量覆盖 self.dashscope = DashScopeConfig() self.task = TaskConfig(**self._config_data.get("task", {})) self.logging = LoggingConfig(**self._config_data.get("logging", {})) def _load_config(self) -> Dict[str, Any]: """加载配置文件""" config_dir = Path(__file__).parent.parent.parent / "config" / "environments" config_file = config_dir / f"{self.environment}.yaml" if not config_file.exists(): raise FileNotFoundError(f"配置文件不存在: {config_file}") with open(config_file, 'r', encoding='utf-8') as file: return yaml.safe_load(file) def get_project_root(self) -> Path: """获取项目根目录""" return Path(__file__).parent.parent.parent def get_logs_dir(self) -> Path: """获取日志目录""" logs_dir = self.get_project_root() / "logs" logs_dir.mkdir(exist_ok=True) return logs_dir def get_temp_dir(self) -> Path: """获取临时文件目录""" temp_dir = self.get_project_root() / "temp" temp_dir.mkdir(exist_ok=True) return temp_dir # 全局配置实例 config = Config() def get_config() -> Config: """获取配置实例""" return config def reload_config(environment: Optional[str] = None) -> Config: """重新加载配置""" global config config = Config(environment) return config