智教助手平台:完整初始化
- 前端:Vue3 + TS + Element Plus,24 个页面路由(课件/组题/教案/动画/思维导图/作文批改/命题/课堂/资源/社区等) - 后端:FastAPI + SQLAlchemy + SQLite,17 个路由模块,AI 服务层含降级模板 - AI:glm-5.x 推理模型已禁用思维链,确保输出真实内容 - 修复:ai_service 两处请求体注入 enable_thinking/thinking disabled - 测试账号:13900999999 / test1234
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import os
|
||||
import logging
|
||||
import secrets as _secrets
|
||||
from pydantic_settings import BaseSettings
|
||||
from pydantic import field_validator
|
||||
from functools import lru_cache
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 已知的弱/默认密钥,实例化时会拒绝(防止源码泄露后被伪造 JWT)
|
||||
_INSECURE_DEFAULTS = {
|
||||
"",
|
||||
"change-me-in-production",
|
||||
"changeme",
|
||||
"secret",
|
||||
"your-secret-key",
|
||||
}
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
APP_NAME: str = "智教助手"
|
||||
APP_VERSION: str = "1.0.0"
|
||||
DEBUG: bool = True
|
||||
|
||||
DATABASE_URL: str = "sqlite:///./jiaoyu.db"
|
||||
REDIS_URL: str = "redis://localhost:6379/0"
|
||||
|
||||
SECRET_KEY: str = "change-me-in-production"
|
||||
ALGORITHM: str = "HS256"
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24
|
||||
REFRESH_TOKEN_EXPIRE_DAYS: int = 7
|
||||
|
||||
AI_API_KEY: str = ""
|
||||
AI_API_BASE: str = "https://api.openai.com/v1"
|
||||
AI_MODEL: str = "gpt-4o"
|
||||
|
||||
CORS_ORIGINS: list[str] = ["http://localhost:5173"]
|
||||
|
||||
UPLOAD_DIR: str = "uploads"
|
||||
MAX_UPLOAD_SIZE: int = 50 * 1024 * 1024
|
||||
MAX_REQUEST_BODY_SIZE: int = 60 * 1024 * 1024 # global request body limit
|
||||
|
||||
@field_validator("SECRET_KEY")
|
||||
@classmethod
|
||||
def _validate_secret_key(cls, v: str) -> str:
|
||||
"""在 .env 加载后执行:弱默认值在开发模式生成临时密钥,生产模式拒绝启动。"""
|
||||
raw = (v or "").strip()
|
||||
debug_env = str(os.getenv("DEBUG", "")).lower()
|
||||
# DEBUG 字段可能已被 pydantic 解析;优先看环境变量原始值,回退看已解析的 DEBUG
|
||||
is_debug = debug_env in ("", "1", "true", "yes", "on") if debug_env else True
|
||||
# 若环境变量显式设了 DEBUG,用它;否则用 pydantic 解析后的值(默认 True)
|
||||
if debug_env:
|
||||
is_debug = debug_env in ("1", "true", "yes", "on")
|
||||
|
||||
if raw in _INSECURE_DEFAULTS:
|
||||
if is_debug:
|
||||
generated = _secrets.token_urlsafe(48)
|
||||
logger.warning(
|
||||
"SECRET_KEY 未配置或为弱默认值,已生成临时开发密钥(仅本次运行有效)。"
|
||||
"生产环境请在 .env 中设置 SECRET_KEY 为至少 32 字符的随机字符串。"
|
||||
)
|
||||
return generated
|
||||
raise RuntimeError(
|
||||
"SECRET_KEY 未配置或为弱默认值,生产环境拒绝启动。"
|
||||
"请在 .env 中设置 SECRET_KEY 为至少 32 字符的随机字符串。"
|
||||
)
|
||||
if len(raw) < 32:
|
||||
if is_debug:
|
||||
logger.warning(
|
||||
"SECRET_KEY 长度不足 32 字符(当前 %d),建议使用更长的随机字符串。", len(raw)
|
||||
)
|
||||
return raw
|
||||
raise RuntimeError(
|
||||
f"SECRET_KEY 长度不足 32 字符(当前 {len(raw)}),生产环境拒绝启动。"
|
||||
)
|
||||
return raw
|
||||
|
||||
class Config:
|
||||
env_file = ".env"
|
||||
extra = "ignore"
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_settings() -> Settings:
|
||||
return Settings()
|
||||
Reference in New Issue
Block a user