import os import urllib.parse from typing import Dict, Any from dotenv import load_dotenv load_dotenv() class Settings: """配置管理器""" def __init__(self): self.HOST = os.getenv("HOST", "0.0.0.0") self.PORT = int(os.getenv("PORT", "8000")) self.DEBUG = os.getenv("DEBUG", "false").lower() == "true" self.UPLOAD_DIR = os.getenv("UPLOAD_DIR", "./uploads") self.MAX_FILE_SIZE = int(os.getenv("MAX_FILE_SIZE", "104857600")) self.ALLOWED_EXTENSIONS = os.getenv("ALLOWED_EXTENSIONS", ".stp,.step,.stp.gz") self.POINTCLOUD_SAMPLE_COUNT = int(os.getenv("POINTCLOUD_SAMPLE_COUNT", "10000")) self.MESH_QUALITY = os.getenv("MESH_QUALITY", "high") self.PARALLEL_PROCESSING = os.getenv("PARALLEL_PROCESSING", "true").lower() == "true" self.RUSTFS_ENDPOINT = os.getenv("RUSTFS_ENDPOINT") or os.getenv("MINIO_ENDPOINT") or "http://localhost:8080" self.RUSTFS_ACCESS_KEY = os.getenv("RUSTFS_ACCESS_KEY") or os.getenv("MINIO_ACCESS_KEY") or "your-access-key" self.RUSTFS_SECRET_KEY = os.getenv("RUSTFS_SECRET_KEY") or os.getenv("MINIO_SECRET_KEY") or "your-secret-key" self.RUSTFS_TIMEOUT = int(os.getenv("RUSTFS_TIMEOUT", "30")) self.RUSTFS_PRESIGNED_URL_EXPIRES = int(os.getenv("RUSTFS_PRESIGNED_URL_EXPIRES", "3600")) db_host = os.getenv("DB_HOST") db_port_str = os.getenv("DB_PORT") db_name = os.getenv("DB_NAME") db_user = os.getenv("DB_USER") db_password = os.getenv("DB_PASSWORD") missing_configs = [] if not db_host: missing_configs.append("DB_HOST") if not db_port_str: missing_configs.append("DB_PORT") if not db_name: missing_configs.append("DB_NAME") if not db_user: missing_configs.append("DB_USER") if not db_password: missing_configs.append("DB_PASSWORD") if missing_configs: raise ValueError(f"数据库配置缺失,请在.env文件中设置: {', '.join(missing_configs)}") self.DB_HOST = db_host self.DB_PORT = int(db_port_str) self.DB_NAME = db_name self.DB_USER = db_user self.DB_PASSWORD = db_password self.SECRET_KEY = os.getenv("SECRET_KEY") self.ALGORITHM = os.getenv("ALGORITHM", "HS256") self.ACCESS_TOKEN_EXPIRE_MINUTES = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "1440")) self.ADMIN_USERNAME = os.getenv("ADMIN_USERNAME", "admin") self.ADMIN_PASSWORD = os.getenv("ADMIN_PASSWORD") self.ADMIN_EMAIL = os.getenv("ADMIN_EMAIL", "admin@gemold.com") self.ADMIN_FULL_NAME = os.getenv("ADMIN_FULL_NAME", "系统管理员") self.ENABLE_FREECAD_VERIFICATION = os.getenv("ENABLE_FREECAD_VERIFICATION", "false").lower() == "true" self.FREECAD_VERIFICATION_TIMEOUT = int(os.getenv("FREECAD_VERIFICATION_TIMEOUT", "120")) self.PROCESSING_TIMEOUT_BASE = int(os.getenv("PROCESSING_TIMEOUT_BASE", "300")) self.PROCESSING_TIMEOUT_PER_MB = int(os.getenv("PROCESSING_TIMEOUT_PER_MB", "15")) # Redis self.REDIS_HOST = os.getenv("REDIS_HOST", "localhost") self.REDIS_PORT = int(os.getenv("REDIS_PORT", "6379")) self.REDIS_PASSWORD = os.getenv("REDIS_PASSWORD", "") self.REDIS_DB = int(os.getenv("REDIS_DB", "0")) # LLM 增强分析配置(可选) self.LLM_ENABLED = os.getenv("LLM_ENABLED", "false").lower() == "true" self.LLM_API_URL = os.getenv("LLM_API_URL", "https://api.openai.com/v1") self.LLM_API_KEY = os.getenv("LLM_API_KEY", "") self.LLM_MODEL = os.getenv("LLM_MODEL", "gpt-4o-mini") self.LLM_TIMEOUT = int(os.getenv("LLM_TIMEOUT", "60")) self.LLM_MAX_TOKENS = int(os.getenv("LLM_MAX_TOKENS", "2000")) @property def DATABASE_URL(self) -> str: if self.DB_PASSWORD: safe_password = urllib.parse.quote(self.DB_PASSWORD.encode("utf-8"), safe="") else: safe_password = "" return f"postgresql+asyncpg://{self.DB_USER}:{safe_password}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}" @property def allowed_extensions_set(self) -> set: return set(ext.strip() for ext in self.ALLOWED_EXTENSIONS.split(",")) settings = Settings()