""" 配置管理模块 基于 Pydantic Settings 和 TOML 文件 """ from typing import Optional, Dict, Any from pydantic_settings import BaseSettings from pydantic import Field import toml from pathlib import Path import sys import os from utils.launch import args class Settings(BaseSettings): """应用配置""" # 应用信息 app_name: str = "FastAPI Demo" app_version: str = "1.0.0" description: str = "FastAPI 应用" # 服务器配置 host: str = "0.0.0.0" port: int = 8000 reload: bool = False workers: int = 4 # 数据库配置 database_url: str = "sqlite://db.sqlite3" generate_schemas: bool = False # 环境配置 env: str = "development" debug: bool = False # 日志配置 logging_level: str = "INFO" logging_file: Optional[str] = None # CORS 配置 cors_allow_origins: list = ["*"] cors_allow_credentials: bool = True cors_allow_methods: list = ["*"] cors_allow_headers: list = ["*"] # 安全配置 secret_key: str = "your-secret-key-change-in-production" algorithm: str = "HS256" access_token_expire_minutes: int = 30 # 模块系统 module_system_type: str = "local" module_system_path: list = ["plugins", "app"] class Config: env_file = ".env" extra = "ignore" @classmethod def from_toml(cls, config_path: Optional[str] = None) -> "Settings": """从 TOML 文件加载配置""" if config_path is None: # 尝试多个可能的配置路径 possible_paths = [ "config.toml", "./config.toml", "../config.toml", Path(__file__).parent.parent.parent / "config.toml", ] for path in possible_paths: if Path(path).exists(): config_path = str(path) print(f"📄 加载配置文件: {config_path}") break if config_path is None: print("⚠️ 未找到配置文件,使用默认配置") return cls() try: config_file = Path(config_path) if not config_file.exists(): print(f"⚠️ 配置文件不存在: {config_path}") return cls() config_data = toml.load(config_file) # 获取默认配置 default_config = config_data.get("default", {}) # 确定环境 env = default_config.get("env", "development") # 获取环境特定配置 env_config = config_data.get(env, {}) # 合并配置 merged_config = {**default_config, **env_config} # 处理嵌套配置 for section in ["server", "database", "security", "logging", "cors", "module_system"]: if section in config_data: if isinstance(config_data[section], dict): merged_config.update(config_data[section]) # 从环境特定配置中覆盖 for section in ["server", "database", "security", "logging", "cors", "module_system"]: env_section_key = f"{env}.{section}" if env_section_key in config_data: if isinstance(config_data[env_section_key], dict): merged_config.update(config_data[env_section_key]) print(f"🌍 环境: {env}") return cls(**merged_config) except Exception as e: print(f"❌ 加载配置失败: {e}") import traceback traceback.print_exc() return cls() # 全局配置实例 _settings = None def get_settings() -> Settings: """获取配置实例(单例模式)""" global _settings if _settings is None: _settings = Settings.from_toml(args.config) return _settings