Spaces:
Running
Running
File size: 3,513 Bytes
82e122c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
from __future__ import annotations
import os
from dataclasses import dataclass
from functools import lru_cache
from pathlib import Path
# Resolve repo root from this file's location:
# app/settings.py → parent = app/ → parent = repo root
REPO_ROOT = Path(__file__).resolve().parents[1]
# Canonical demo DB and pipeline config shipped with the repo
DEFAULT_DEMO_DB = REPO_ROOT / "data" / "demo.db"
DEFAULT_PIPELINE_CONFIG = REPO_ROOT / "configs" / "sqlite_pipeline.yaml"
@dataclass
class Settings:
"""
Centralized application configuration.
Does NOT depend on pydantic. Values are loaded from environment
variables via Settings.from_env().
"""
# --- DB mode / adapters ---
db_mode: str = "sqlite" # "sqlite" or "postgres"
postgres_dsn: str = ""
# --- Pipeline config ---
pipeline_config_path: str = str(DEFAULT_PIPELINE_CONFIG)
# --- SQLite uploaded DBs ---
db_upload_dir: str = "/tmp/nl2sql_dbs"
db_ttl_seconds: int = 7200 # 2 hours
# --- Upload constraints ---
upload_max_bytes: int = 20 * 1024 * 1024 # 20MB
# --- Cache settings ---
cache_ttl_sec: int = 300
cache_max_entries: int = 256
# --- Default SQLite path (demo DB) ---
default_sqlite_path: str = str(DEFAULT_DEMO_DB)
# --- API keys (comma-separated) ---
api_keys_raw: str = ""
# --- App version ---
app_version: str = "dev"
@classmethod
def from_env(cls) -> "Settings":
"""
Build Settings from environment variables with sane fallbacks.
- DEFAULT_SQLITE_PATH and PIPELINE_CONFIG can be absolute or relative.
- Relative paths are resolved against REPO_ROOT.
"""
def getenv_int(name: str, default: int) -> int:
raw = os.getenv(name)
if raw is None or raw.strip() == "":
return default
try:
return int(raw)
except ValueError:
return default
# --- Default SQLite path ---
raw_default_db = os.getenv("DEFAULT_SQLITE_PATH", "").strip()
if raw_default_db:
db_candidate = Path(raw_default_db)
if not db_candidate.is_absolute():
db_candidate = REPO_ROOT / raw_default_db
else:
db_candidate = DEFAULT_DEMO_DB
# --- Pipeline config path ---
raw_cfg = os.getenv("PIPELINE_CONFIG", "").strip()
if raw_cfg:
cfg_candidate = Path(raw_cfg)
if not cfg_candidate.is_absolute():
cfg_candidate = REPO_ROOT / raw_cfg
else:
cfg_candidate = DEFAULT_PIPELINE_CONFIG
return cls(
db_mode=os.getenv("DB_MODE", cls.db_mode),
postgres_dsn=os.getenv("POSTGRES_DSN", cls.postgres_dsn),
pipeline_config_path=str(cfg_candidate),
db_upload_dir=os.getenv("DB_UPLOAD_DIR", cls.db_upload_dir),
db_ttl_seconds=getenv_int("DB_TTL_SECONDS", cls.db_ttl_seconds),
upload_max_bytes=getenv_int("UPLOAD_MAX_BYTES", cls.upload_max_bytes),
cache_ttl_sec=getenv_int("NL2SQL_CACHE_TTL_SEC", cls.cache_ttl_sec),
cache_max_entries=getenv_int("NL2SQL_CACHE_MAX", cls.cache_max_entries),
default_sqlite_path=str(db_candidate),
api_keys_raw=os.getenv("API_KEYS", cls.api_keys_raw),
app_version=os.getenv("APP_VERSION", cls.app_version),
)
@lru_cache()
def get_settings() -> Settings:
return Settings.from_env()
|