MicroFish/backend/app/config.py

103 lines
5.1 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.

"""
配置管理
统一从项目根目录的 .env 文件加载配置
"""
import os
from dotenv import load_dotenv
# 加载项目根目录的 .env 文件
# 路径: MiroFish/.env (相对于 backend/app/config.py)
project_root_env = os.path.join(os.path.dirname(__file__), '../../.env')
if os.path.exists(project_root_env):
load_dotenv(project_root_env, override=True)
else:
# 如果根目录没有 .env尝试加载环境变量用于生产环境
load_dotenv(override=True)
class Config:
"""Flask配置类"""
# Flask配置
# 注意SECRET_KEY 的默认值是公开值,仅供 DEBUG 模式使用生产模式DEBUG=false
# 必须通过环境变量设置自定义值(见 validate())。
SECRET_KEY = os.environ.get('SECRET_KEY', 'mirofish-secret-key')
# 安全默认C1DEBUG 默认关闭,避免误把 Werkzeug 交互式调试器(可远程 RCE暴露到网络。
DEBUG = os.environ.get('FLASK_DEBUG', 'False').lower() == 'true'
# 认证配置C2所有 /api/* 端点强制 API Key 鉴权
# AUTH_ENABLED 默认开启;本地开发可显式设 AUTH_ENABLED=false 关闭。
# fail-closed 解析:仅显式 false/0/no/off 才关闭鉴权;其余任何值(含空白、拼写错误、
# 带尾换行的 'true\n'、'1'、'yes' 等)一律视为开启,避免 env 配置失误悄悄回到零鉴权。
API_KEY = os.environ.get('API_KEY')
AUTH_ENABLED = os.environ.get('AUTH_ENABLED', 'true').strip().lower() not in ('false', '0', 'no', 'off')
# JSON配置 - 禁用ASCII转义让中文直接显示而不是 \uXXXX 格式)
JSON_AS_ASCII = False
# LLM配置统一使用OpenAI格式
LLM_API_KEY = os.environ.get('LLM_API_KEY')
LLM_BASE_URL = os.environ.get('LLM_BASE_URL', 'https://api.openai.com/v1')
LLM_MODEL_NAME = os.environ.get('LLM_MODEL_NAME', 'gpt-4o-mini')
# Zep配置
ZEP_API_KEY = os.environ.get('ZEP_API_KEY')
# 文件上传配置
MAX_CONTENT_LENGTH = 50 * 1024 * 1024 # 50MB
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), '../uploads')
ALLOWED_EXTENSIONS = {'pdf', 'md', 'txt', 'markdown'}
# 文本处理配置
DEFAULT_CHUNK_SIZE = 500 # 默认切块大小
DEFAULT_CHUNK_OVERLAP = 50 # 默认重叠大小
# OASIS模拟配置
# OASIS_DEFAULT_MAX_ROUNDSC3客户端未显式传 max_rounds 时应用的默认轮数上限。
# 之前此常量从未被引用dead config现已在 SimulationRunner 中生效。默认 150 覆盖
# 典型配置72h/30min = 144 轮)以免悄悄截断标准演示;更长的配置会被截到此值,且无论如何
# 都不会超过硬上限 OASIS_MAX_ROUNDS_CAP。匿名 denial-of-wallet 已由 C2 鉴权堵住,此处
# 仅约束“已鉴权客户端”单次运行的成本上界。
OASIS_DEFAULT_MAX_ROUNDS = int(os.environ.get('OASIS_DEFAULT_MAX_ROUNDS', '150'))
# 硬上限C3denial-of-wallet 防护):无论客户端传入何值,轮数/agent 数都不得超过这些上限。
OASIS_MAX_ROUNDS_CAP = int(os.environ.get('OASIS_MAX_ROUNDS_CAP', '200'))
OASIS_MAX_AGENTS_CAP = int(os.environ.get('OASIS_MAX_AGENTS_CAP', '1000'))
# 模拟超时C4每轮 env.step 超时 + 整轮模拟总超时。子进程读取同名环境变量。
OASIS_ROUND_TIMEOUT_SEC = int(os.environ.get('OASIS_ROUND_TIMEOUT_SEC', '600'))
OASIS_RUN_TIMEOUT_SEC = int(os.environ.get('OASIS_RUN_TIMEOUT_SEC', '7200'))
OASIS_SIMULATION_DATA_DIR = os.path.join(os.path.dirname(__file__), '../uploads/simulations')
# OASIS平台可用动作配置
OASIS_TWITTER_ACTIONS = [
'CREATE_POST', 'LIKE_POST', 'REPOST', 'FOLLOW', 'DO_NOTHING', 'QUOTE_POST'
]
OASIS_REDDIT_ACTIONS = [
'LIKE_POST', 'DISLIKE_POST', 'CREATE_POST', 'CREATE_COMMENT',
'LIKE_COMMENT', 'DISLIKE_COMMENT', 'SEARCH_POSTS', 'SEARCH_USER',
'TREND', 'REFRESH', 'DO_NOTHING', 'FOLLOW', 'MUTE'
]
# Report Agent配置
REPORT_AGENT_MAX_TOOL_CALLS = int(os.environ.get('REPORT_AGENT_MAX_TOOL_CALLS', '5'))
REPORT_AGENT_MAX_REFLECTION_ROUNDS = int(os.environ.get('REPORT_AGENT_MAX_REFLECTION_ROUNDS', '2'))
REPORT_AGENT_TEMPERATURE = float(os.environ.get('REPORT_AGENT_TEMPERATURE', '0.5'))
@classmethod
def validate(cls) -> list[str]:
"""验证必要配置"""
errors: list[str] = []
if not cls.LLM_API_KEY:
errors.append("LLM_API_KEY 未配置")
if not cls.ZEP_API_KEY:
errors.append("ZEP_API_KEY 未配置")
# C1生产模式必须设置自定义 SECRET_KEY默认值是公开值可伪造签名 / 削弱调试器 PIN
if not cls.DEBUG and cls.SECRET_KEY == 'mirofish-secret-key':
errors.append("生产模式FLASK_DEBUG=false必须设置自定义 SECRET_KEY")
# C2开启鉴权时必须配置 API_KEY否则所有 /api/* 都会 401
if cls.AUTH_ENABLED and not cls.API_KEY:
errors.append("AUTH_ENABLED=true 时必须设置 API_KEY或显式 AUTH_ENABLED=false 关闭鉴权)")
return errors