refactor(config): centralize api settings source

This commit is contained in:
Xiaoxia AI
2026-06-21 00:36:13 +08:00
parent e2f0e6faf9
commit f474b97a57
2 changed files with 32 additions and 121 deletions
+15 -121
View File
@@ -1,125 +1,19 @@
from pydantic_settings import BaseSettings, SettingsConfigDict
from typing import Optional
import os
"""Compatibility layer for the canonical API settings module.
Use `app.config` as the single source of truth for API configuration.
This module remains only for older imports during migration.
"""
from app.config import Settings as AppSettings
from app.config import get_settings, settings
class AppSettings(BaseSettings):
"""应用配置"""
# 基础配置
app_name: str = "xiaoxia-saas"
app_env: str = "development" # development / staging / production
app_version: str = "0.1.0"
debug: bool = True
# API 配置
api_host: str = "0.0.0.0"
api_port: int = 8000
api_prefix: str = "/api/v1"
# 数据库配置
database_url: str = "postgresql+psycopg://postgres:postgres@localhost:5432/xiaoxia_saas"
database_pool_size: int = 20
database_max_overflow: int = 40
database_pool_timeout: int = 30
database_pool_recycle: int = 3600
# Redis 配置
redis_url: str = "redis://localhost:6379/0"
redis_max_connections: int = 50
# Celery 配置
celery_broker_url: str = "redis://localhost:6379/0"
celery_result_backend: str = "redis://localhost:6379/1"
celery_worker_concurrency: int = 4
celery_worker_max_tasks_per_child: int = 1000
# MinIO 配置
minio_endpoint: str = "localhost:9000"
minio_access_key: str = "admin"
minio_secret_key: str = "xiaoxia2026"
minio_bucket: str = "xiaoxia-assets"
minio_secure: bool = False
minio_public_url: str = "http://localhost:9000"
# 日志配置
log_level: str = "INFO"
log_format: str = "json" # json / text
log_file: Optional[str] = None
# CORS 配置
cors_origins: str = "http://localhost:3000,http://localhost:8000"
cors_allow_credentials: bool = True
# 文件上传限制
max_upload_size_mb: int = 1000
allowed_file_types: str = "video/mp4,video/quicktime,video/x-msvideo,audio/mpeg,audio/wav,image/jpeg,image/png,image/gif"
# 安全配置
secret_key: str = "change-me-in-production"
access_token_expire_minutes: int = 60
refresh_token_expire_days: int = 7
# 监控配置(可选)
sentry_dsn: Optional[str] = None
prometheus_port: Optional[int] = None
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False,
extra="ignore",
)
@property
def cors_origins_list(self) -> list[str]:
"""解析 CORS origins 为列表"""
return [origin.strip() for origin in self.cors_origins.split(",")]
@property
def allowed_file_types_list(self) -> list[str]:
"""解析允许的文件类型为列表"""
return [ft.strip() for ft in self.allowed_file_types.split(",")]
@property
def is_production(self) -> bool:
"""是否为生产环境"""
return self.app_env == "production"
@property
def is_staging(self) -> bool:
"""是否为 staging 环境"""
return self.app_env == "staging"
@property
def is_development(self) -> bool:
"""是否为开发环境"""
return self.app_env == "development"
def reload_settings() -> AppSettings:
"""Reload settings for tests and legacy callers."""
import app.config as canonical_config
canonical_config.settings = canonical_config.get_settings()
return canonical_config.settings
# 全局配置实例
_settings: Optional[AppSettings] = None
def get_settings() -> AppSettings:
"""获取配置实例(单例模式)"""
global _settings
if _settings is None:
# 根据环境加载不同的 .env 文件
env = os.getenv("APP_ENV", "development")
env_file = f".env.{env}" if env != "development" else ".env"
# 如果环境特定的配置文件存在,则使用它
if os.path.exists(env_file):
_settings = AppSettings(_env_file=env_file)
else:
_settings = AppSettings()
return _settings
def reload_settings():
"""重新加载配置(用于测试)"""
global _settings
_settings = None
return get_settings()
__all__ = ["AppSettings", "get_settings", "reload_settings", "settings"]
@@ -84,6 +84,23 @@
- 未配置 OSS 时,下载 URL 对本地 `/generated-files/` 直接返回,对 OSS URL 回退为公开 URL。
- 上传/下载等 OSS 专属操作在未配置时返回明确错误。
### 5. P1API 配置存在双真源
**涉及文件**`apps/api/app/config.py``apps/api/app/core/config.py`
**问题**
- `app/config.py``app/core/config.py` 同时定义 Settings。
- 两套配置字段命名、OSS/MinIO、JWT、CORS 等含义不一致。
- 新代码主要使用 `app.config`,旧模块可能误导入 `app.core.config`
**根因**
- 早期目录重构后没有清理旧配置入口。
**修复**
- 明确 `app.config` 为 API 配置唯一真源。
- `app/core/config.py` 改为兼容转发层,只 re-export canonical Settings/get_settings/settings。
- 避免未来继续在旧文件增加新字段导致漂移。
## 三、已补充测试
### 新增