Json-Python-Server/app/core/config.py
2026-01-29 18:18:32 +08:00

123 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
FastAPI 应用配置管理
支持环境变量配置,生产级配置管理
"""
import os
from pathlib import Path
from typing import Optional
import logging
try:
from dotenv import load_dotenv
except Exception: # pragma: no cover
load_dotenv = None
# 项目根目录
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# 加载 .env不覆盖已存在的系统环境变量
_dotenv_path = BASE_DIR / ".env"
if load_dotenv is not None and _dotenv_path.exists():
load_dotenv(dotenv_path=_dotenv_path, override=False)
# 环境变量
ENVIRONMENT = os.getenv('ENV', 'development')
DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'
class Settings:
"""应用配置类"""
# FastAPI 基础配置
APP_TITLE = "时间序列数据分析系统"
APP_DESCRIPTION = "支持多格式数据上传、AI增强分析、多语言报告生成"
APP_VERSION = "2.0.0"
# API 暴露模式
# - full: 暴露 v1 + v2默认
# - v2: 仅暴露 v2 分析接口 + 基础状态接口(禁用 v1 上传/文件/图片接口)
API_MODE = os.getenv('API_MODE', 'full').strip().lower()
# 服务器配置
HOST = os.getenv('HOST', '0.0.0.0')
PORT = int(os.getenv('PORT', 60201))
RELOAD = DEBUG
# CORS 配置
CORS_ORIGINS = os.getenv('CORS_ORIGINS', '*').split(',')
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_METHODS = ['*']
CORS_ALLOW_HEADERS = ['*']
# 文件上传配置
UPLOAD_DIR = Path(os.getenv('UPLOAD_DIR', BASE_DIR / 'uploads'))
UPLOAD_DIR.mkdir(exist_ok=True)
MAX_UPLOAD_SIZE = int(os.getenv('MAX_UPLOAD_SIZE', 16 * 1024 * 1024)) # 16MB
ALLOWED_EXTENSIONS = {'csv'}
# 临时文件配置
TEMP_DIR = Path(os.getenv('TEMP_DIR', BASE_DIR / 'temp'))
TEMP_DIR.mkdir(exist_ok=True)
# 字体配置
FONTS_DIR = Path(os.getenv('FONTS_DIR', BASE_DIR / 'resource' / 'fonts'))
FONTS_DIR.mkdir(parents=True, exist_ok=True)
# API 配置 (阿里云千问)
API_KEY = os.getenv('MY_API_KEY', '')
API_BASE = os.getenv('MY_API_BASE', 'https://dashscope.aliyuncs.com/compatible-mode/v1')
API_MODEL = os.getenv('MY_MODEL', 'qwen-turbo')
API_TIMEOUT = int(os.getenv('API_TIMEOUT', 30))
# 分析配置
LANGUAGE_DEFAULT = os.getenv('LANGUAGE_DEFAULT', 'zh')
ANALYSIS_TIMEOUT = int(os.getenv('ANALYSIS_TIMEOUT', 300)) # 5分钟
# 日志配置
LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO' if not DEBUG else 'DEBUG')
LOG_DIR = Path(os.getenv('LOG_DIR', BASE_DIR / 'logs'))
LOG_DIR.mkdir(exist_ok=True)
# 内存管理
MAX_MEMORY_MB = int(os.getenv('MAX_MEMORY_MB', 500))
# v2 (OSS URL) 配置
# 允许的域名白名单(逗号分隔)。为空时表示不启用域名白名单(仍会做私网/环回 IP 拦截)。
V2_ALLOWED_HOSTS = [h.strip() for h in os.getenv('V2_ALLOWED_HOSTS', '').split(',') if h.strip()]
# 是否允许 http默认仅 https
V2_ALLOW_HTTP = os.getenv('V2_ALLOW_HTTP', 'False').lower() == 'true'
# 是否允许私网/环回地址(仅用于本地开发/冒烟;生产建议保持 False
V2_ALLOW_PRIVATE_NETWORKS = os.getenv('V2_ALLOW_PRIVATE_NETWORKS', 'False').lower() == 'true'
# 下载超时。requests 支持 (connect, read),这里统一使用 read 超时。
V2_DOWNLOAD_TIMEOUT_SECONDS = float(os.getenv('V2_DOWNLOAD_TIMEOUT_SECONDS', 30))
V2_CONNECT_TIMEOUT_SECONDS = float(os.getenv('V2_CONNECT_TIMEOUT_SECONDS', 5))
@classmethod
def get_upload_path(cls, filename: str) -> Path:
"""获取上传文件的完整路径"""
return cls.UPLOAD_DIR / filename
@classmethod
def get_temp_path(cls, filename: str) -> Path:
"""获取临时文件的完整路径"""
return cls.TEMP_DIR / filename
# 日志配置
def setup_logging():
"""设置日志系统"""
logging.basicConfig(
level=Settings.LOG_LEVEL,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(Settings.LOG_DIR / 'app.log'),
logging.StreamHandler()
]
)
# 创建全局配置实例
settings = Settings()
# 启用日志
setup_logging()