Skip to main content

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.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for betl 0.1.5
File Size Uploaded
betl-0.1.5.tar.gz 1.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for betl 0.1.5
File Interpreter ABI Platform
betl-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 1.3 MB

Release files / betl-0.1.5.tar.gz

Download URL betl-0.1.5.tar.gz
Size 1.2 MB
Tags Source
SHA-256 checksum
How to use checksums
874d496779f629f926d8b4ec4cb25f876ded0ae61df5d0a6ab1e23efa594be11
BLAKE2b-256 checksum
How to use checksums
519e0c6a83216db56aa5316960a5ba63d354c6d2c7e30e2803c12b0f5bf1ab33
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.5-py3-none-any.whl

Download URL betl-0.1.5-py3-none-any.whl
Size 37.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8c0239874f856e6d18d6aae27eab7d72aea1e087f4f0470cff2bedfd1dea3ecc
BLAKE2b-256 checksum
How to use checksums
fd9b01aaba2d2375f56bf16ba919040393d42323fb434cd81ccf44411ad1db2b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.21

Release history Release notifications | RSS feed

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page