"""Configuração central lida de variáveis de ambiente (com suporte a .env).""" from __future__ import annotations import os import secrets from functools import lru_cache from pathlib import Path try: # carregamento opcional do .env from dotenv import load_dotenv load_dotenv() except Exception: # pragma: no cover - dotenv é opcional pass BASE_DIR = Path(__file__).resolve().parent.parent DATA_DIR = BASE_DIR / "data" UPLOAD_DIR = DATA_DIR / "uploads" PREVIEW_DIR = DATA_DIR / "previews" ALLOWED_EXTENSIONS = {".pdf", ".jpg", ".jpeg", ".png"} def _env_bool(name: str, default: bool) -> bool: raw = os.environ.get(name) if raw is None: return default return raw.strip().lower() in {"1", "true", "yes", "on", "sim"} class Settings: """Configuração resolvida uma vez no start do processo.""" def __init__(self) -> None: self.base_dir = BASE_DIR self.data_dir = DATA_DIR self.upload_dir = UPLOAD_DIR self.preview_dir = PREVIEW_DIR self.db_path = Path(os.environ.get("DB_PATH", DATA_DIR / "app.sqlite3")) # Segredo da sessão. Em produção DEVE vir do ambiente; sem ele geramos um # efêmero (as sessões caem a cada restart) e avisamos no log. self.secret_key = os.environ.get("SECRET_KEY", "") self.secret_key_is_ephemeral = not self.secret_key if self.secret_key_is_ephemeral: self.secret_key = secrets.token_urlsafe(48) # OpenAI (opcional — sem chave o app cai no OCR/heurística local). self.openai_api_key = os.environ.get("OPENAI_API_KEY", "").strip() self.openai_model = os.environ.get("OPENAI_MODEL", "gpt-4o").strip() or "gpt-4o" self.openai_max_pages = int(os.environ.get("OPENAI_MAX_PAGES", "8")) # Admin semeado na primeira execução. self.admin_username = os.environ.get("ADMIN_USERNAME", "admin").strip() or "admin" self.admin_password = os.environ.get("ADMIN_PASSWORD", "").strip() self.max_upload_bytes = int(os.environ.get("MAX_UPLOAD_BYTES", str(12 * 1024 * 1024))) self.allowed_extensions = set(ALLOWED_EXTENSIONS) self.session_cookie = os.environ.get("SESSION_COOKIE", "lnf_session") self.session_https_only = _env_bool("SESSION_HTTPS_ONLY", False) self.session_max_age = int(os.environ.get("SESSION_MAX_AGE", str(60 * 60 * 12))) @property def openai_enabled(self) -> bool: return bool(self.openai_api_key) def ensure_storage(self) -> None: self.data_dir.mkdir(parents=True, exist_ok=True) self.upload_dir.mkdir(parents=True, exist_ok=True) self.preview_dir.mkdir(parents=True, exist_ok=True) @lru_cache(maxsize=1) def get_settings() -> Settings: settings = Settings() settings.ensure_storage() return settings