import os import configparser from typing import Optional class Config: """从 config.ini 读取的应用配置""" _config = configparser.ConfigParser() _root_dir = os.path.dirname(os.path.dirname(__file__)) _config_path = os.path.join(_root_dir, 'config', 'config.ini') # 在类初始化时加载配置 if not os.path.exists(_config_path): raise FileNotFoundError( f"Configuration file not found at: {_config_path}. " "Please copy 'config/config.ini.example' to 'config/config.ini' and fill in your details." ) try: with open(_config_path, "r", encoding="utf-8") as f: _config.read_file(f) except UnicodeDecodeError: with open(_config_path, "r", encoding="gbk") as f: _config.read_file(f) # 通用设置 DEFAULT_MODEL_SECTION: str = _config.get('General', 'DEFAULT_MODEL_SECTION', fallback='gpt-4o') MAX_RETRIES: int = _config.getint('General', 'MAX_RETRIES', fallback=3) TIMEOUT: int = _config.getint('General', 'TIMEOUT', fallback=30) @classmethod def get_model_config(cls, section: Optional[str] = None) -> dict: """ 获取指定模型配置段。 若 section 为 None,则使用默认模型配置段。 """ if section is None: section = cls.DEFAULT_MODEL_SECTION if not cls._config.has_section(section): raise ValueError(f"Model section '{section}' not found in config.ini") config = dict(cls._config.items(section)) # 确保必需的键存在 if 'model_name' not in config or 'openai_api_key' not in config: raise ValueError(f"Model section '{section}' must contain 'model_name' and 'openai_api_key'") return { "model": config['model_name'], "api_key": config['openai_api_key'], "base_url": config.get('url') or config.get('base_url') } @classmethod def get_section(cls, section: str) -> dict: """获取指定配置段的键值对(键名会被转为小写)""" if not cls._config.has_section(section): return {} return dict(cls._config.items(section)) @classmethod def validate_config(cls): """校验默认模型配置是否存在且有效""" try: default_config = cls.get_model_config() if not default_config.get("api_key") or 'your_openai_api_key_here' in default_config.get("api_key"): raise ValueError(f"API key for default model '{cls.DEFAULT_MODEL_SECTION}' is missing or a placeholder.") except (ValueError, configparser.Error) as e: raise ValueError(f"Configuration validation failed: {e}") # 如有需要可在导入时做初始校验, # 但已移到 main.py 以便更可控地执行。 # 如需在导入时校验,可在此调用 Config.validate_config()