102 lines
3.9 KiB
Python
102 lines
3.9 KiB
Python
"""Configuración centralizada de la aplicación.
|
|
|
|
Usa Pydantic BaseSettings para cargar valores por defecto y variables de entorno.
|
|
Se lee automáticamente un archivo `.env` en la raíz del proyecto si existe.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Optional, Tuple
|
|
import logging
|
|
import os
|
|
|
|
# Cargar variables desde .env en el entorno (para que otros módulos que usan os.environ las vean)
|
|
try:
|
|
from dotenv import load_dotenv # type: ignore
|
|
# En desarrollo, dar precedencia al archivo .env sobre variables previas del entorno
|
|
load_dotenv(override=True)
|
|
except Exception:
|
|
pass
|
|
|
|
from pydantic import Field
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
from pydantic import AliasChoices
|
|
|
|
|
|
class ApiSettings(BaseSettings):
|
|
"""Parámetros del backend compatible con OpenAI/Ollama (usando os.getenv)."""
|
|
base_url: str = os.getenv("EXTRACTOR_BASE_URL", "http://10.8.0.4:11434/v1")
|
|
api_key: str = os.getenv("EXTRACTOR_API_KEY", "ollama")
|
|
model: str = os.getenv("EXTRACTOR_MODEL", "gpt-5.4")
|
|
request_timeout_s: int = int(os.getenv("EXTRACTOR_TIMEOUT_S", 120))
|
|
grok_api_key: str = os.getenv("GROK_API_KEY", "")
|
|
grok_base_url: str = os.getenv("GROK_BASE_URL", "https://api.x.ai/v1")
|
|
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
|
|
|
|
|
|
class ImagingSettings(BaseSettings):
|
|
"""Parámetros de conversión de documentos a imágenes."""
|
|
poppler_path: Optional[str] = Field(None, validation_alias=AliasChoices("POPPLER_PATH"))
|
|
pdf_dpi: int = Field(600, validation_alias=AliasChoices("PDF_DPI"))
|
|
pdf_thread_count: int = Field(10, validation_alias=AliasChoices("PDF_THREAD_COUNT"))
|
|
tiff_pages: Optional[Tuple[int, int]] = Field((2, 3), validation_alias=AliasChoices("TIFF_PAGES"))
|
|
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
|
|
|
|
|
|
class RetrySettings(BaseSettings):
|
|
"""Estrategia de reintentos para llamadas al backend."""
|
|
max_attempts: int = Field(3, validation_alias=AliasChoices("RETRY_MAX_ATTEMPTS"))
|
|
wait_min_s: float = Field(1.0, validation_alias=AliasChoices("RETRY_WAIT_MIN_S"))
|
|
wait_max_s: float = Field(8.0, validation_alias=AliasChoices("RETRY_WAIT_MAX_S"))
|
|
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
|
|
|
|
|
|
class ProcessingSettings(BaseSettings):
|
|
"""Configuración de procesamiento y concurrencia."""
|
|
concurrency_limit: int = Field(100, validation_alias=AliasChoices("CONCURRENCY_LIMIT"))
|
|
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
|
|
|
|
|
|
class AppSettings(BaseSettings):
|
|
"""Configuración raíz agrupada."""
|
|
api: ApiSettings = ApiSettings()
|
|
imaging: ImagingSettings = ImagingSettings()
|
|
retry: RetrySettings = RetrySettings()
|
|
processing: ProcessingSettings = ProcessingSettings()
|
|
csv_delimiter: str = Field("|", validation_alias=AliasChoices("CSV_DELIMITER"))
|
|
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
|
|
|
|
|
|
settings = AppSettings()
|
|
|
|
|
|
def extractor_credentials_for_model(model: str) -> tuple[str, str]:
|
|
"""Devuelve (api_key, base_url) para el extractor según el id de modelo."""
|
|
m = (model or "").strip()
|
|
api = settings.api
|
|
if m.lower().startswith("grok-"):
|
|
return (str(api.grok_api_key or "").strip(), str(api.grok_base_url or "").strip() or "https://api.x.ai/v1")
|
|
return (api.api_key, api.base_url)
|
|
|
|
|
|
def is_grok_extractor_model(model: str) -> bool:
|
|
"""True si el modelo de extracción debe usar la API de xAI (Grok)."""
|
|
return (model or "").strip().lower().startswith("grok-")
|
|
|
|
|
|
# Tipos documentales válidos por defecto para el campo especial `documento_forzate`.
|
|
# NIT se excluye explícitamente porque no debe tratarse como tipo de documento personal.
|
|
DEFAULT_ALLOWED_DOCUMENT_TYPES: Tuple[str, ...] = (
|
|
"CC",
|
|
"TI",
|
|
"CE",
|
|
"RC",
|
|
"PA",
|
|
"PPT",
|
|
"PEP",
|
|
"EPT",
|
|
"NUIP",
|
|
)
|
|
|
|
# Alias de compatibilidad.
|
|
ALLOWED_DOCUMENT_TYPES: Tuple[str, ...] = DEFAULT_ALLOWED_DOCUMENT_TYPES
|