Files
qihuaiflow/backend/python/app/config.py
T
qyyfw 78ff261b5a 初始提交: Qihu-AIFlow v2.0.1 完整项目
- 前端 React+TypeScript (源码+构建产物)
- 后端 Python FastAPI
- 数据库迁移 001-015
- Docker部署配置
- 微信ClawBot API频道绑定
- 项目文档 README.md
2026-07-02 14:40:46 +08:00

133 lines
4.7 KiB
Python

"""
Qihu-AIFlow 智能自动化PaaS平台 - 后端配置
"""
import os
import logging
from pathlib import Path
from logging.handlers import TimedRotatingFileHandler
from dotenv import load_dotenv
# 加载 .env 文件(Docker 环境跳过,直接使用容器环境变量)
if not (Path("/.dockerenv").exists() or Path("/run/.containerenv").exists()):
env_path = Path("/data/share/project/.env")
if env_path.exists():
load_dotenv(env_path, override=False)
# 数据库配置
DATABASE_URL = f"mysql+pymysql://{os.getenv('MYSQL_USER', 'root')}:{os.getenv('MYSQL_PASSWORD', 'pwd2026')}@{os.getenv('MYSQL_HOST', 'localhost')}:{os.getenv('MYSQL_PORT', '3306')}/{os.getenv('MYSQL_DATABASE', 'aiflow')}?charset=utf8mb4"
# Redis配置
REDIS_HOST = os.getenv("REDIS_HOST", "localhost")
REDIS_PORT = int(os.getenv("REDIS_PORT", "6379"))
REDIS_PASSWORD = os.getenv("REDIS_PASSWORD", "pwd2026")
REDIS_URL = f"redis://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/0"
# JWT配置
SECRET_KEY = os.getenv("SECRET_KEY", "aiflow-secret-key-change-in-production-2026")
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 # 24小时
# 应用配置
APP_NAME = "Qihu-AIFlow"
APP_VERSION = "1.0.0"
DEBUG = os.getenv("DEBUG", "false").lower() == "true"
# 服务地址
# 三级优先级:
# 1. docker-compose.yml 的环境变量(生产部署)
# 2. .env 文件中的配置(本地开发)
# 3. 硬编码正式域名(最终兜底)
# 注意:如果环境变量是临时开发地址(如team-coding子域名),强制使用.env中的正式域名
APP_ACCESS_URL = os.getenv("APP_ACCESS_URL", "")
# 检测是否为临时/开发环境域名,这些域名在生产不可用
_TEMP_DOMAIN_PATTERNS = ["team-coding", "localhost", "127.0.0.1", "0.0.0.0"]
_is_temp_url = any(p in (APP_ACCESS_URL or "") for p in _TEMP_DOMAIN_PATTERNS)
if not APP_ACCESS_URL or _is_temp_url:
# 尝试从.env文件读取正式域名(Docker环境跳过.env,直接用docker-compose变量)
try:
from dotenv import load_dotenv as _load_dotenv
_env_path = Path("/data/share/project/.env")
if _env_path.exists():
_load_dotenv(_env_path, override=True)
env_url = os.getenv("APP_ACCESS_URL", "")
if env_url:
APP_ACCESS_URL = env_url
_is_temp_url = any(p in (APP_ACCESS_URL or "") for p in _TEMP_DOMAIN_PATTERNS)
except Exception:
pass
# 最终兜底:如果仍然是临时URL或为空,使用硬编码正式域名
if not APP_ACCESS_URL or _is_temp_url:
APP_ACCESS_URL = "https://bot.qihuyun.com"
# 上传文件配置(兼容 Docker /app 和本地 /data/share/project 路径)
_DATA_BASE = Path("/app/data") if Path("/.dockerenv").exists() else Path("/data/share/project/data")
UPLOAD_DIR = _DATA_BASE / "uploads"
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
MAX_UPLOAD_SIZE = 50 * 1024 * 1024 # 50MB
# ============================================================
# 日志配置 - 按天轮转输出到文件
# ============================================================
LOG_DIR = _DATA_BASE / "logs"
LOG_DIR.mkdir(parents=True, exist_ok=True)
# 慢请求阈值(秒)
SLOW_REQUEST_THRESHOLD = float(os.getenv("SLOW_REQUEST_THRESHOLD", "3.0"))
def setup_file_logging():
"""配置应用日志按天轮转输出到文件"""
log_format = logging.Formatter(
"%(asctime)s [%(levelname)s] %(name)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
# 应用日志 - 按天轮转,保留30天
app_handler = TimedRotatingFileHandler(
filename=str(LOG_DIR / "app.log"),
when="midnight",
interval=1,
backupCount=30,
encoding="utf-8",
)
app_handler.setFormatter(log_format)
app_handler.setLevel(logging.INFO)
# 错误日志 - 按天轮转,保留30天
error_handler = TimedRotatingFileHandler(
filename=str(LOG_DIR / "error.log"),
when="midnight",
interval=1,
backupCount=30,
encoding="utf-8",
)
error_handler.setFormatter(log_format)
error_handler.setLevel(logging.ERROR)
# 访问日志 - 按天轮转,保留14天
access_handler = TimedRotatingFileHandler(
filename=str(LOG_DIR / "access.log"),
when="midnight",
interval=1,
backupCount=14,
encoding="utf-8",
)
access_handler.setFormatter(log_format)
access_handler.setLevel(logging.INFO)
# 配置根logger
root_logger = logging.getLogger()
root_logger.setLevel(logging.INFO)
root_logger.addHandler(app_handler)
root_logger.addHandler(error_handler)
# 配置访问日志专用logger
access_logger = logging.getLogger("aiflow.access")
access_logger.addHandler(access_handler)
access_logger.propagate = False
return access_logger