Spaces:
Runtime error
Runtime error
feat: synchronize text-to-sql-bot codebase with Hugging Face Space repository, including Docker build configurations
6086e71 | """ | |
| PlainSQL Configuration β Pydantic Settings with environment-based config. | |
| All secrets loaded from .env, with sensible defaults for local dev. | |
| """ | |
| from pydantic_settings import BaseSettings | |
| from pydantic import Field, model_validator | |
| from typing import Optional | |
| from functools import lru_cache | |
| _JWT_DEFAULT = "change-me-in-production-use-openssl-rand-hex-32" | |
| class Settings(BaseSettings): | |
| """Application settings loaded from environment variables.""" | |
| # ββ App ββββββββββββββββββββββββββββββββββββββββββββββ | |
| APP_NAME: str = "PlainSQL" | |
| APP_VERSION: str = "2.0.0" | |
| DEBUG: bool = False | |
| ENV: str = Field(default="development", description="development | staging | production") | |
| # ββ Database βββββββββββββββββββββββββββββββββββββββββ | |
| DB_URI: str = Field(..., description="MySQL connection URI") | |
| DB_POOL_SIZE: int = 10 | |
| DB_MAX_OVERFLOW: int = 20 | |
| DB_POOL_TIMEOUT: int = 30 | |
| DB_QUERY_TIMEOUT: int = 30 | |
| # ββ Redis ββββββββββββββββββββββββββββββββββββββββββββ | |
| REDIS_URL: str = Field(default="redis://localhost:6379/0") | |
| CACHE_TTL_SECONDS: int = 300 | |
| # ββ Authentication βββββββββββββββββββββββββββββββββββ | |
| JWT_SECRET_KEY: str = Field(default=_JWT_DEFAULT) | |
| JWT_ALGORITHM: str = "HS256" | |
| JWT_EXPIRY_HOURS: int = 8 | |
| # ββ LLM Providers βββββββββββββββββββββββββββββββββββ | |
| HUGGINGFACEHUB_API_TOKEN: Optional[str] = None | |
| OPENAI_API_KEY: Optional[str] = None | |
| ANTHROPIC_API_KEY: Optional[str] = None | |
| GROQ_API_KEY: Optional[str] = None | |
| GROQ_MODEL_PRIMARY: str = "llama-3.3-70b-versatile" | |
| GROQ_MODEL_FAST: str = "llama-3.1-8b-instant" | |
| GROQ_BASE_URL: str = "https://api.groq.com/openai/v1" | |
| OLLAMA_BASE_URL: str = "http://localhost:11434" | |
| DEFAULT_LLM_PROVIDER: str = Field(default="groq", description="groq | huggingface | openai | anthropic | ollama") | |
| DEFAULT_MODEL: str = "Qwen/Qwen2.5-Coder-32B-Instruct" | |
| # ββ RAG ββββββββββββββββββββββββββββββββββββββββββββββ | |
| CHROMA_PERSIST_DIR: str = "./chroma_db" | |
| EMBEDDING_MODEL: str = "all-MiniLM-L6-v2" | |
| RAG_TOP_K: int = 5 | |
| # ββ Safety βββββββββββββββββββββββββββββββββββββββββββ | |
| MAX_QUERY_ROWS: int = 1000 | |
| QUERY_TIMEOUT_SECONDS: int = 30 | |
| # ββ Rate Limiting ββββββββββββββββββββββββββββββββββββ | |
| RATE_LIMIT_RPM: int = 60 | |
| # ββ Observability ββββββββββββββββββββββββββββββββββββ | |
| LANGSMITH_API_KEY: Optional[str] = None | |
| LANGSMITH_PROJECT: str = "plainsql" | |
| LOG_LEVEL: str = "INFO" | |
| # ββ CORS βββββββββββββββββββββββββββββββββββββββββββββ | |
| CORS_ORIGINS: list[str] = [ | |
| "http://localhost:3000", | |
| "http://localhost:5173", | |
| "http://127.0.0.1:3000", | |
| "http://127.0.0.1:5173", | |
| "http://localhost:5500", | |
| ] | |
| model_config = { | |
| "env_file": [".env", "../.env", "../../.env"], | |
| "env_file_encoding": "utf-8", | |
| "case_sensitive": True, | |
| "extra": "ignore", | |
| } | |
| def _validate_production_secrets(self) -> "Settings": | |
| """Prevent deployment with default secrets in production/staging.""" | |
| if self.ENV in ("production", "staging"): | |
| if self.JWT_SECRET_KEY == _JWT_DEFAULT: | |
| raise ValueError( | |
| "FATAL: JWT_SECRET_KEY must be changed from the default value " | |
| "in production/staging. Generate one with: openssl rand -hex 32" | |
| ) | |
| if len(self.JWT_SECRET_KEY) < 32: | |
| raise ValueError( | |
| "FATAL: JWT_SECRET_KEY must be at least 32 characters for production." | |
| ) | |
| return self | |
| def get_settings() -> Settings: | |
| """Cached settings singleton.""" | |
| return Settings() | |