import secrets from typing import Annotated, Any, Literal from pydantic import ( AnyUrl, BeforeValidator, PostgresDsn, computed_field, ) from pydantic_core import MultiHostUrl from pydantic_settings import BaseSettings, SettingsConfigDict def parse_cors(v: Any) -> list[str] | str: if isinstance(v, str) and not v.startswith("["): return [i.strip() for i in v.split(",")] elif isinstance(v, list | str): return v raise ValueError(v) class Settings(BaseSettings): model_config = SettingsConfigDict( # Use top level .env file (one level above ./backend/) env_file="../.env", env_ignore_empty=True, extra="ignore", ) PROJECT_NAME: str = "SQLBot" API_V1_STR: str = "/api/v1" SECRET_KEY: str = secrets.token_urlsafe(32) # 60 minutes * 24 hours * 8 days = 8 days ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 FRONTEND_HOST: str = "http://localhost:5173" BACKEND_CORS_ORIGINS: Annotated[ list[AnyUrl] | str, BeforeValidator(parse_cors) ] = [] @computed_field # type: ignore[prop-decorator] @property def all_cors_origins(self) -> list[str]: return [str(origin).rstrip("/") for origin in self.BACKEND_CORS_ORIGINS] + [ self.FRONTEND_HOST ] POSTGRES_SERVER: str = 'localhost' POSTGRES_PORT: int = 5432 POSTGRES_USER: str = 'root' POSTGRES_PASSWORD: str = "Password123@pg" POSTGRES_DB: str = "sqlbot" SQLBOT_DB_URL: str = '' # SQLBOT_DB_URL: str = 'mysql+pymysql://root:Password123%40mysql@127.0.0.1:3306/sqlbot' TOKEN_KEY: str = "X-SQLBOT-TOKEN" DEFAULT_PWD: str = "SQLBot@123456" ASSISTANT_TOKEN_KEY: str = "X-SQLBOT-ASSISTANT-TOKEN" CACHE_TYPE: Literal["redis", "memory", "None"] = "memory" CACHE_REDIS_URL: str | None = None # Redis URL, e.g., "redis://[[username]:[password]]@localhost:6379/0" LOG_LEVEL: str = "INFO" # DEBUG, INFO, WARNING, ERROR LOG_DIR: str = "logs" LOG_FORMAT: str = "%(asctime)s - %(name)s - %(levelname)s:%(lineno)d - %(message)s" SQL_DEBUG: bool = False UPLOAD_DIR: str = "/opt/sqlbot/data/file" SQLBOT_KEY_EXPIRED: int = 100 # License key expiration timestamp, 0 means no expiration @computed_field # type: ignore[prop-decorator] @property def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn | str: if self.SQLBOT_DB_URL: return self.SQLBOT_DB_URL return MultiHostUrl.build( scheme="postgresql+psycopg", username=self.POSTGRES_USER, password=self.POSTGRES_PASSWORD, host=self.POSTGRES_SERVER, port=self.POSTGRES_PORT, path=self.POSTGRES_DB, ) MCP_IMAGE_PATH: str = '/opt/sqlbot/images' EXCEL_PATH: str = '/opt/sqlbot/data/excel' MCP_IMAGE_HOST: str = 'http://localhost:3000' SERVER_IMAGE_HOST: str = 'https://YOUR_SERVE_IP:MCP_PORT/images/' LOCAL_MODEL_PATH: str = '/opt/sqlbot/models' DEFAULT_EMBEDDING_MODEL: str = 'shibing624/text2vec-base-chinese' EMBEDDING_ENABLED: bool = True EMBEDDING_SIMILARITY: float = 0.4 EMBEDDING_TOP_COUNT: int = 5 settings = Settings() # type: ignore