main.py
import logging import sys from pathlib import Path import importlib.util from typing import Any
RAIZ_PROYECTO = Path(file).parent sys.path.append(str(RAIZ_PROYECTO)) sys.path.append(str(RAIZ_PROYECTO / "src"))
Importamos tu pipeline optimizado por densidad NumPy
from core.pipeline import ETLDocumentPipeline
Configuración limpia de logs en consola
logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", handlers=[logging.StreamHandler(sys.stdout)] ) logger = logging.getLogger("Main")
def cargar_clase_contrato_judicial(ruta_contrato: Path) -> Any: """ Carga dinámicamente el archivo contrato.py desde el disco D: y extrae la clase decorada lista para ser procesada por el Core. """ if not ruta_contrato.exists(): raise FileNotFoundError(f"No se encontró el archivo de contrato en: {ruta_contrato}")
# Proceso oficial de importación dinámica en tiempo de ejecución
spec = importlib.util.spec_from_file_location("contrato_modulo", str(ruta_contrato))
modulo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(modulo)
# 1. Intento de carga directa por el nombre explícito definido
if hasattr(modulo, "MiContratoRemate"):
clase_contrato = getattr(modulo, "MiContratoRemate")
logger.info("[Contrato] Clase 'MiContratoRemate' localizada e importada con éxito.")
return clase_contrato
# 2. Fallback de barrido reflexivo en caso de que cambies el nombre de la clase
for atributo_nombre in dir(modulo):
atributo = getattr(modulo, atributo_nombre)
# Buscamos clases que tengan el atributo inyectado por tu decorador @contract
if isinstance(atributo, type) and hasattr(atributo, "_extraction_contract"):
logger.info(f"[Contrato] Detectada clase con contrato declarativo válido: '{atributo_nombre}'")
return atributo
raise AttributeError("No se localizó ninguna clase decorada con @contract en contrato.py")
def main(): # Parámetros e infraestructura de rutas fijas solicitadas ruta_pdf = Path(r"d:\betl\testpdf.pdf") ruta_contrato = Path(r"d:\betl\contrato.py")
logger.info("=== INICIANDO ENTORNO DE PRUEBAS DE INFRAESTRUCTURA ETL ===")
try:
# 1. Extraer la Clase del Contrato (sin instanciar con paréntesis)
contrato_clase = cargar_clase_contrato_judicial(ruta_contrato)
# 2. Inicializar el Pipeline Persistente (Carga pesada de memoria en caché una única vez)
pipeline = ETLDocumentPipeline(
modelo_llm="qwen3:8b",
timeout_llm=250,
chunk_size=8000,
ocr_lang="es"
)
# 3. Lanzar procesamiento automático (OCR Regional + Densidad Vectorizada por NumPy)
logger.info(f"[Pipeline] Enviando documento {ruta_pdf.name} al motor analítico...")
resultado_final = pipeline.ejecutar(
pdf_path=ruta_pdf,
contrato=contrato_clase, # Pasamos la clase directamente al orquestador
captcha_path=None,
modo_pdf="auto" # Automatización por análisis de píxeles activa
)
# 4. Impresión estructurada del DTO procesado
if resultado_final:
logger.info("¡Pipeline ETL procesado y consolidado con éxito!")
print("\n================ DTO ESTRUCTURADO FINAL (FUSIÓN) ================")
import json
print(json.dumps(resultado_final, indent=4, ensure_ascii=False))
print("=================================================================\n")
else:
logger.error("[Pipeline] El flujo terminó pero el MergerService o el OCR devolvieron vacío.")
except Exception as e:
logger.error(f"Error crítico abortivo en el punto de entrada principal: {e}", exc_info=True)
if name == "main": main()
Metadata
Release files for betl 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| betl-0.1.6.tar.gz | 1.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| betl-0.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.3 MB
Release files / betl-0.1.6.tar.gz
| Download URL | betl-0.1.6.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
05621b797591198892b4d825f0f82cbc84777d546c16ea3dcb53919206fec39b
|
|
BLAKE2b-256 checksum How to use checksums |
a72170635d24f38768f639cada292da6bebc6995c92a01cd8976ff62db1b8874
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.21
|
Release files / betl-0.1.6-py3-none-any.whl
| Download URL | betl-0.1.6-py3-none-any.whl |
|---|---|
| Size | 37.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4b487d66dedd6f5daf6230df3bf3c7b19fb4126ba387f76f99b99834823b8025
|
|
BLAKE2b-256 checksum How to use checksums |
177ae6f58410af7c6060e29d5c1716dd821764f8f4019f1614dc1267d1a66da2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.21
|