""" 应用配置管理 """ from pydantic_settings import BaseSettings from typing import List from urllib.parse import quote_plus import os class Settings(BaseSettings): """应用配置类""" # 应用信息 APP_NAME: str = "NEX Docus" APP_VERSION: str = "1.0.0" DEBUG: bool = True # 服务器配置 HOST: str = "0.0.0.0" PORT: int = 8000 # 数据库配置 DB_HOST: str DB_PORT: int = 3306 DB_USER: str DB_PASSWORD: str DB_NAME: str DB_CHARSET: str = "utf8mb4" @property def DATABASE_URL(self) -> str: """数据库连接URL""" # URL 编码密码,防止特殊字符导致解析错误 password = quote_plus(self.DB_PASSWORD) return f"mysql+aiomysql://{self.DB_USER}:{password}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}?charset={self.DB_CHARSET}" @property def SYNC_DATABASE_URL(self) -> str: """同步数据库连接URL(用于 Alembic)""" # URL 编码密码 password = quote_plus(self.DB_PASSWORD) return f"mysql+pymysql://{self.DB_USER}:{password}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}?charset={self.DB_CHARSET}" # Redis 配置 REDIS_HOST: str REDIS_PORT: int = 6379 REDIS_PASSWORD: str REDIS_DB: int = 8 @property def REDIS_URL(self) -> str: """Redis 连接URL""" return f"redis://:{self.REDIS_PASSWORD}@{self.REDIS_HOST}:{self.REDIS_PORT}/{self.REDIS_DB}" # JWT 配置 SECRET_KEY: str ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 1440 # 24小时 # 用户配置 DEFAULT_USER_PASSWORD: str = "User@123456" # 新用户默认密码 # 文件存储配置 STORAGE_ROOT: str = "/data/nex_docus_store" PROJECTS_PATH: str = "/data/nex_docus_store/projects" USERS_PATH: str = "/data/nex_docus_store/users" TEMP_PATH: str = "/data/nex_docus_store/temp" # 头像上传配置 AVATAR_MAX_SIZE: int = 1 * 1024 * 1024 # 1MB # RAG 分块配置 CHUNK_SIZE: int = 800 # 单个文档分块的字符数 CHUNK_OVERLAP: int = 150 # 相邻分块之间的重叠字符数 # 跨域配置 CORS_ORIGINS: List[str] = ["http://localhost:5173", "http://localhost:3000"] # 日志配置 LOG_LEVEL: str = "INFO" LOG_PATH: str = "logs" class Config: env_file = ".env" case_sensitive = True def security_warnings(self) -> List[str]: """启动自检:返回仍在使用的占位/默认敏感配置说明(不阻断启动,仅告警)。""" warnings: List[str] = [] if self.SECRET_KEY in INSECURE_SECRET_KEYS or len(self.SECRET_KEY) < 16: warnings.append( "SECRET_KEY 仍是占位值或过短,任何人都可伪造 JWT。" "请在 .env 中设置为随机值:openssl rand -hex 32" ) if self.DEFAULT_USER_PASSWORD in DEFAULT_INSECURE_PASSWORDS: warnings.append( "DEFAULT_USER_PASSWORD 仍是仓库内置默认值,管理员新建的账号可被猜到。" "请在部署配置中改为随机初始密码" ) return warnings # 仓库/模板里出现过的占位值:命中即视为未修改 INSECURE_SECRET_KEYS = { "your-secret-key-change-me-in-production", "your-secret-key-change-me-in-production-use-openssl-rand-hex-32", "change_me", "change-me", "secret", } DEFAULT_INSECURE_PASSWORDS = {"User@123", "User@123456"} # 创建配置实例 settings = Settings()