Files
fn_registry/python/functions/pipelines/render_automatic_eda.md
T
egutierrez 54a9ab70c7 feat(eda): render AutomaticEDA por capítulos sueltos con resolución de dependencias
Permite renderizar un SUBCONJUNTO de capítulos del informe AutomaticEDA
(only_chapters=[...]) para iterar/testear un capítulo concreto sin generar el
documento entero, garantizando que el capítulo pedido SIEMPRE llegue poblado.

- Nuevo módulo automatic_eda/chapter_deps.py: mapa central CHAPTER_DEPS (fuente
  de verdad) que declara, por capítulo de CHAPTER_ORDER, qué flags de cómputo
  (run_models/run_series/run_llm) y qué piezas de ctx (raw_numeric, timeseries_raw,
  geo_points, head_rows, db_path/table) necesita para no salir degradado. Helpers
  puros: resolve_requirements, resolve_profile_flags, needs_render_ctx,
  resolve_ctx_data_keys, validate_chapter_ids.
- build_document(profile, ctx, only=None): parámetro only opcional que restringe
  el cuerpo a esos capítulos (portada primera + glosario última siempre). Lee la
  clave reservada ctx['_only_chapters'] cuando only es None, para propagar la
  selección a través de los renderers sin modificarlos. Retrocompatible.
- render_automatic_eda(..., only_chapters=None): valida los ids (error claro
  dict-no-throw), resuelve las dependencias activando el cómputo necesario aunque
  el caller no lo pidiera (un flag explícito siempre prima) y construyendo solo
  las piezas de ctx que los capítulos pedidos leen (salta build_eda_render_ctx
  entero si ninguno necesita datos crudos). only_chapters=None produce el
  documento completo idéntico al de hoy.
- Tests: chapter_deps_test.py (resolución pura), build_document_only_test.py
  (filtro), render_automatic_eda_only_test.py (golden con DuckDB: outliers suelto
  con IsolationForest poblado por resolución; timeseries activa run_series;
  eficiencia geospatial sin modelos; edge cases).
- .md del pipeline: documenta only_chapters + emit_md; version 1.1.0 -> 1.2.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 21:35:46 +02:00

13 KiB

name, kind, lang, domain, purity, version, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, tested, tests, test_file_path, file_path, params, output
name kind lang domain purity version signature description tags uses_functions uses_types returns returns_optional error_type imports tested tests test_file_path file_path params output
render_automatic_eda pipeline py pipelines impure 1.2.0 def render_automatic_eda(db_path: str, table: str, backend: str = "duckdb", sample: int = None, run_models: bool = None, run_series: bool = None, run_llm: bool = None, profile_level: str = "standard", out_dir: str = "reports", basename: str = None, ctx_extra: dict = None, emit_md: bool = True, only_chapters: list = None) -> dict Informe AutomaticEDA COMPLETO one-shot de una tabla DuckDB/PostgreSQL: perfila con profile_table, construye el ctx con los datos crudos (build_eda_render_ctx: raw_numeric para modelos/geo, timeseries_raw para series, geo_points para el mapa, db_path/table para la agregacion push-down) y emite PDF (A5 movil) Y PPTX (16:9) del mismo documento por capitulos, con los 11 capitulos POBLADOS de verdad (clusters pintados sobre el PCA, evolucion temporal, mapa geografico y tablas de agregacion), no degradados. El parametro profile_level es un preset de consumo CPU/LLM (lite/standard/full) que mapea a los flags run_models/run_series/run_llm/sample; un flag explicito siempre prima sobre el preset. lite=bajo consumo (sin LLM, sin serie, modelos solo PCA+normalidad sin KMeans/IsolationForest, sample reducido); standard=comportamiento historico; full=standard+narrativa LLM. Devuelve las rutas de PDF/PPTX y el manifiesto de versiones por capitulo.
eda
duckdb
postgres
profiling
pipeline
dataops
report
pdf
pptx
profile_table_py_pipelines
build_eda_render_ctx_py_datascience
render_automatic_eda_pdf_py_datascience
render_automatic_eda_pptx_py_datascience
false error_go_core
true
render end-to-end sobre DuckDB sintetico con categoricas + fecha + lat/lon emite PDF y PPTX con paginas/slides
python/functions/pipelines/render_automatic_eda_test.py python/functions/pipelines/render_automatic_eda.py
name desc
db_path Ruta al archivo DuckDB (read-only, debe existir) o DSN PostgreSQL si backend='postgres'.
name desc
table Nombre de la tabla a perfilar e informar.
name desc
backend 'duckdb' (default) o 'postgres'. Selecciona el motor de perfilado y muestreo.
name desc
sample Maximo de filas/valores muestreados por columna para el perfil y para los datos crudos del ctx (LIMIT). Default None => lo fija el preset de profile_level (lite=2000, standard/full=5000). Un valor explicito prima sobre el preset.
name desc
run_models Corre los modelos baratos (PCA/KMeans/IsolationForest/normalidad); necesario para que el capitulo modelos pinte los clusters sobre el plano PCA. Default None => lo fija el preset (True en los tres niveles); en lite los modelos se limitan a PCA+normalidad. Un valor explicito prima sobre el preset.
name desc
run_series Calcula el analisis de serie temporal por columna numerica; necesario para el analisis del capitulo timeseries. Default None => lo fija el preset (standard/full=True, lite=False). Un valor explicito prima sobre el preset.
name desc
run_llm Hace la interpretacion LLM del perfil y ACTIVA la narrativa LLM de los capitulos modelos/geospatial/agregacion (titulos de segmento, descripcion de zona, seleccion de agregaciones). Con False usan su derivacion cuantitativa sin red. Default None => lo fija el preset (full=True, lite/standard=False). Un valor explicito prima sobre el preset.
name desc
profile_level Preset de consumo CPU/LLM (default 'standard'). Mapea a defaults de run_models/run_series/run_llm/sample; un flag explicito SIEMPRE prima. 'lite'=bajo consumo (run_llm=False, run_series=False, sample=2000, modelos solo PCA+normalidad sin KMeans/IsolationForest); 'standard'=comportamiento historico (modelos completos, serie, sin LLM); 'full'=standard+narrativa LLM. Un nivel desconocido cae a 'standard'.
name desc
out_dir Directorio de salida (se crea si no existe). Default 'reports'.
name desc
basename Nombre base de los archivos sin extension. Default 'aeda_<table>_<timestamp>'.
name desc
ctx_extra Dict opcional con claves de presentacion/contexto extra que se mezclan en el ctx (dataset_name, description, source_origin, ...); no pisan las claves de datos calculadas por build_eda_render_ctx.
name desc
emit_md Ademas del PDF y el PPTX, emite un Markdown autocontenido del mismo documento por capitulos (texto + tablas markdown, sin binarios) para pegar a un LLM. Default True. La ruta sale en aeda_md_path.
name desc
only_chapters Lista opcional de ids de capitulo a renderizar (subconjunto de CHAPTER_ORDER) para iterar/testear un capitulo suelto sin generar el documento entero. Default None => documento COMPLETO (retrocompatible). Cuando se pasa una lista: (1) se VALIDA contra CHAPTER_ORDER, un id desconocido o lista vacia devuelve error claro listando los validos; (2) se RESUELVEN las dependencias de computo de esos capitulos (automatic_eda.chapter_deps) activando los flags que necesiten (run_models/run_series/run_llm) aunque el caller no los pidiera y construyendo SOLO las piezas de ctx que leen, de modo que el capitulo suelto SIEMPRE llega poblado (p.ej. ['outliers'] activa run_models y conserva raw_numeric -> Isolation Forest completo) sin malgastar CPU/LLM en lo que ningun capitulo pedido usa; (3) el documento y su manifest contienen SOLO esos capitulos MAS portada (primera) y glosario (ultima, cuando hay terminos clicables). Un flag explicito del caller prima sobre la resolucion de dependencias.
dict {status:'ok', pdf_path:str, pptx_path:str, manifest_path:str|None, n_pages:int, n_slides:int, pdf_note:str, pptx_note:str, profile:<TableProfile>} o {status:'error', error:str} (dict-no-throw).

Ejemplo

from pipelines.render_automatic_eda import render_automatic_eda

# Informe completo a reports/ (standard = comportamiento por defecto historico).
r = render_automatic_eda("/tmp/ventas.duckdb", "ventas", out_dir="reports")
print(r["status"], r["pdf_path"], r["pptx_path"], r["n_pages"], r["n_slides"])
# ok reports/aeda_ventas_20260630-120500.pdf reports/aeda_ventas_20260630-120500.pptx 37 39

# Bajo consumo (CPU/LLM): vistazo rapido y barato — sin LLM, sin serie, modelos
# solo PCA + normalidad (sin KMeans/IsolationForest), sample reducido.
r = render_automatic_eda("/tmp/ventas.duckdb", "ventas", profile_level="lite")

# Maximo: standard + narrativa LLM por capitulo (titulos de segmento, etc.).
r = render_automatic_eda("/tmp/ventas.duckdb", "ventas", profile_level="full")

# Precedencia: el flag explicito SIEMPRE prima sobre el preset. lite pero con LLM:
r = render_automatic_eda("/tmp/ventas.duckdb", "ventas",
                         profile_level="lite", run_llm=True)  # el LLM SI se ejecuta

# Capitulo SUELTO: itera/testea un capitulo sin generar el documento entero. La
# resolucion de dependencias activa el computo que el capitulo necesita aunque no
# se pase explicito. Pedir solo 'outliers' activa run_models y conserva
# raw_numeric -> el bloque Isolation Forest sale COMPLETO. Documento = portada +
# outliers + glosario.
r = render_automatic_eda("/tmp/ventas.duckdb", "ventas", only_chapters=["outliers"])

# Varios capitulos sueltos a la vez (se unen sus dependencias):
r = render_automatic_eda("/tmp/ventas.duckdb", "ventas",
                         only_chapters=["correlacion", "missingness"])

# id desconocido -> error claro listando los validos (dict-no-throw, no lanza):
r = render_automatic_eda("/tmp/ventas.duckdb", "ventas", only_chapters=["nope"])
# {'status': 'error', 'error': 'only_chapters con ids desconocidos: nope. Capitulos validos: portada, overview, ...'}

Cuando usarla

Cuando quieras el informe AutomaticEDA COMPLETO (PDF + PPTX) de una tabla en una sola llamada, con los capitulos de modelos, series, geoespacial y agregacion ya poblados (no degradados). Es el reemplazo de "perfila + monta el ctx a mano + llama a los dos renderers": este pipeline orquesta profile_table -> build_eda_render_ctx -> render_automatic_eda_pdf/_pptx. Usalo como entregable para compartir un EDA, o como el motor detras de profile_table( emit_automatic=True) y del skill /eda.

Para un EDA barato/rapido (CI, vistazo previo, maquina sin GPU o sin red) usa profile_level="lite": evita KMeans + IsolationForest (lo caro en CPU), la serie temporal y el LLM. Para el maximo con interpretacion narrativa por capitulo, profile_level="full". El default "standard" mantiene el comportamiento previo.

Cuando estes iterando o testeando UN capitulo concreto (afinar el render de outliers, comprobar el mapa geoespacial, depurar la agregacion) usa only_chapters=[...]: genera el documento con solo esos capitulos (+ portada y glosario), pero resuelve sus dependencias de computo para que el capitulo suelto nunca salga degradado — pedir ['outliers'] activa run_models y conserva raw_numeric aunque no los pases, y a la vez no malgasta CPU/LLM en lo que ningun capitulo pedido necesita (pedir ['geospatial'] no corre modelos). Es mucho mas rapido que renderizar el informe entero en cada iteracion. El mapa central de dependencias vive en automatic_eda/chapter_deps.py (fuente de verdad).

Gotchas

  • Impura: ESCRIBE el PDF, el PPTX y automatic_eda_manifest.json en out_dir.
  • db_path debe existir: DuckDB read-only no crea la base.
  • Precedencia de flags vs preset: profile_level solo fija los DEFAULTS de run_models/run_series/run_llm/sample (los que quedan en None). Cualquiera de esos flags pasado explicito gana al preset. Ej: profile_level="lite", run_llm=True ejecuta el LLM pese a que lite lo apaga por defecto.
  • lite y la seleccion de features de modelo: en lite los modelos (PCA + normalidad) corren sobre la muestra numerica cruda (ctx['raw_numeric']), sin la poda fina de features que aplica el modo standard (que excluye ids enteros y columnas de baja cardinalidad antes de PCA/KMeans). Es el coste de mantener el cableado minimo y barato; para el analisis fino de modelos usa standard/full.
  • profile_level="standard"/"full" corren PCA/KMeans/IsolationForest + ADF/KPSS/STL por columna (caro). Para un informe mas barato usa "lite" (o pon los flags a False a mano): los capitulos modelos/timeseries se reducen pero el resto del informe sale igual.
  • run_llm=True (preset full o flag explicito) hace llamadas de red (interpretacion del perfil + narrativa por capitulo). Sin red, usa lite/standard: los capitulos siguen completos con su derivacion cuantitativa.
  • El PPTX requiere python-pptx; si no esta instalado, pptx_path sera None y pptx_note lo explica (el PDF se emite igual).
  • Los datos crudos del ctx se muestrean con sample (LIMIT), no se trae la tabla entera a RAM; con tablas enormes sube sample si quieres mas representatividad (coste: mas memoria).
  • only_chapters y el glosario: el glosario (ultimo capitulo) solo aparece si algun capitulo del cuerpo registro terminos clicables. Un capitulo suelto que no registra terminos (p.ej. timeseries, geospatial) sale como portada + ese capitulo, sin glosario, porque no hay nada que enlazar — es correcto, no un fallo.
  • only_chapters con profile_level="lite": en capitulos sueltos el preset solo gobierna sample; los modelos NO usan el camino "lite" (que podaria ctx['raw_numeric'] y dejaria a outliers sin su multivariante en vivo). Quien manda en capitulos sueltos es la resolucion de dependencias, no el preset de coste de modelos.

Capability growth log

  • v1.2.0 (2026-06-30) — anade el parametro only_chapters: renderiza un SUBCONJUNTO de capitulos (para iterar/testear uno suelto) resolviendo sus dependencias de computo via automatic_eda/chapter_deps.py (mapa central CHAPTER_DEPS): activa los flags de coste que el capitulo necesita (run_models/ run_series/run_llm) aunque el caller no los pase y construye solo las piezas de ctx que lee, de modo que el capitulo suelto SIEMPRE llega poblado (golden: ['outliers'] -> Isolation Forest completo) sin malgastar en lo que no usa. La seleccion viaja a build_document por la clave reservada ctx['_only_chapters'] (los renderers no cambian). Valida ids (error claro dict-no-throw). Cambio aditivo y retro-compatible: only_chapters=None produce el documento completo identico a v1.1.0.
  • v1.1.0 (2026-06-30) — anade el parametro profile_level (lite/standard/full), preset de consumo CPU/LLM que mapea a los flags run_models/run_series/run_llm/ sample. lite limita los modelos a PCA+normalidad (cableado a run_eda_models con run_kmeans=False/run_isolation=False) y apaga LLM/serie. Cambio aditivo y retro-compatible: sin profile_level el comportamiento es identico al de v1.0.0.