Files
IPSExtractor/docs/application/flows.md
T

3.6 KiB

application/flows.py

Propósito

Orquesta el procesamiento por radicado para:

  • Calcular encabezados CSV unificados a partir de muestras y selección de campos.
  • Extraer información de factura y, opcionalmente, preformato.
  • Escribir filas en CSV y emitir JSON a la interfaz gráfica mediante callbacks.

Incluye una heurística para inferir qué listas deben expandirse por filas y cuáles agregarse como columnas (en preformato).

API pública

compute_csv_header_union(...) -> tuple[list[str] | None, dict[str, str]]

Calcula el encabezado CSV común (unión) desde datos de muestra y paths seleccionados, aplicando alias y resolviendo duplicados.

Parámetros clave:

  • sample_fact, sample_pre: ejemplos (dict o compatible) para derivar columnas.
  • selected_fields_fact, selected_fields_pre: paths seleccionados por documento.
  • pre_enabled: habilita el cálculo para preformato.
  • alias_map_fact, alias_map_pre: alias opcionales path->nombre.

Devuelve:

  • Lista de encabezados finales (o None si no hay columnas).
  • Mapa path -> alias final aplicado.

Notas:

  • radicado siempre se incluye como columna.
  • Duplicados de alias se desambiguarán con sufijos (n).

process_radicados_parallel(...) -> None

Procesa en paralelo los radicados, realizando:

  1. Extracción de datos de factura y preformato (si está habilitado).
  2. Emisión de JSON via on_output.
  3. Escritura incremental en CSV con encabezado dado (csv_header_union) o derivado.

Parámetros clave:

  • service: Debe exponer extract_full_from_pdf(...) y _append_rows_to_csv(...).
  • root, keywords, pre_keywords: Búsqueda de documentos por radicado.
  • selected_fields_fact, selected_fields_pre: paths de salida.
  • csv_path: Archivo CSV destino (si None, no escribe).
  • on_output: Callback que recibe texto JSON por radicado.
  • on_progress: Callback (radicado, done, total) para progreso.
  • instruction_invoice, instruction_pre: instrucciones LLM.
  • alias_final_map: alias finales a aplicar a encabezados/filas.

Concurrencia:

  • Usa ThreadPoolExecutor con max_workers=4 para balancear IO/CPU.
  • Los errores por documento se capturan y se registran sin detener el flujo.

Consideraciones

  • Si se define csv_header_union, éste manda sobre encabezados derivados por radicado.
  • Para preformato, la heurística _infer_aggregate_list_paths_from_selected selecciona la lista principal y las listas a agregar; si no hay inferencia, se consulta profiles.
  • on_output y on_progress son opcionales y tolerantes a errores (capturados).

Ejemplos

Cálculo de encabezado

from application.flows import compute_csv_header_union

header, alias_map = compute_csv_header_union(
    sample_fact={'radicado': 'x', 'items': [{'codigo': 'A1', 'cantidad': 2}]},
    sample_pre=None,
    selected_fields_fact=['radicado', 'items/*/codigo', 'items/*/cantidad'],
    selected_fields_pre=None,
    pre_enabled=False,
)
# header ~= ['radicado', 'items/*/codigo', 'items/*/cantidad']

Proceso por radicado (escritura CSV)

from application.flows import process_radicados_parallel

process_radicados_parallel(
    service=my_service,                  # Debe implementar extract_full_from_pdf y _append_rows_to_csv
    root="C:/carpeta/raiz",
    keywords=["FACTURA", "RADICADO"],
    pre_enabled=True,
    pre_keywords=["PREFORMATO"],
    selected_fields_fact=['radicado', 'items/*/codigo', 'items/*/cantidad'],
    selected_fields_pre=['radicado', 'dx/*/descripcion'],
    csv_path="salida.csv",
    on_output=lambda txt: print(txt),
    on_progress=lambda r,d,t: print(f"{d}/{t} -> {r}"),
)