chongming/app/core/config.py
2026-01-26 09:50:55 +08:00

132 lines
4.1 KiB
Python

"""
配置管理模块
基于 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