--- name: render_automatic_eda_folder kind: pipeline lang: py domain: pipelines purity: impure version: "1.0.0" signature: "def render_automatic_eda_folder(path: str, out_dir: str = \"reports\", basename: str = None, profile_level: str = \"standard\", emit_pdf: bool = True, emit_pptx: bool = True, emit_md: bool = True, per_table_eda: bool = False, min_inclusion: float = 0.9, ctx_extra: dict = None) -> dict" description: "Informe AutomaticEDA a nivel de BASE one-shot de una CARPETA de archivos tabulares (CSV/Parquet/JSON) o de una DuckDB existente. Carga la carpeta a una DuckDB temporal con load_folder_to_duckdb (o usa la DuckDB dada directa), perfila TODA la base con profile_database (resumen de cada tabla + FK candidatas por containment + join graph con diagrama Mermaid), ENSAMBLA un documento-base por capitulos (portada-base con nombre/n tablas/totales/fecha/fuente, resumen de tablas con una fila por tabla, y relaciones inter-tabla con la tabla de FK candidatas + una Figure matplotlib REAL del join graph dibujada con draw_join_graph_figure mas el texto Mermaid) y lo renderiza con el motor AutomaticEDA a PDF (A5 movil), PPTX (16:9) y Markdown autocontenido a la vez. Con per_table_eda=True anexa los capitulos de mini-EDA de cada tabla (build_document por tabla). Es el hermano a nivel de base de render_automatic_eda (que perfila UNA tabla): aqui el informe es de la base y de sus relaciones. Devuelve las rutas de PDF/PPTX/MD, el manifiesto y el DatabaseProfile." tags: [eda, duckdb, database, profiling, relations, pipeline, dataops, report, pdf, pptx, launcher] uses_functions: - load_folder_to_duckdb_py_infra - profile_database_py_pipelines - render_automatic_eda_pdf_py_datascience - render_automatic_eda_pptx_py_datascience - render_automatic_eda_markdown_py_datascience - draw_join_graph_figure_py_datascience uses_types: [] returns: [] returns_optional: false error_type: error_go_core imports: [] tested: true tests: - "golden: carpeta con 3 CSV relacionados (customers/orders/products) emite PDF+PPTX+MD del documento-base con 3 tablas y la FK orders.customer_id->customers.id" - "edge: carpeta vacia -> status ok con documento minimo, sin lanzar" - "edge: 1 sola tabla -> funciona sin relaciones (capitulo relaciones dice 'sin FK')" test_file_path: "python/functions/pipelines/render_automatic_eda_folder_test.py" file_path: "python/functions/pipelines/render_automatic_eda_folder.py" params: - name: path desc: "DIRECTORIO con archivos tabulares (CSV/Parquet/JSON) que se cargan a una DuckDB temporal, o una DuckDB ya existente (.duckdb/.ddb/.db) que se perfila directa." - name: out_dir desc: "Directorio de salida de los informes (se crea si no existe). Default 'reports'." - name: basename desc: "Nombre base de los archivos sin extension. Default 'aeda_base__'." - name: profile_level desc: "Preset de coste del perfil por tabla ('lite'/'standard'/'full'); ajusta el sample que profile_database pasa a cada tabla (lite=2000, standard/full=5000)." - name: emit_pdf desc: "Emite el PDF A5 movil del documento-base. Default True." - name: emit_pptx desc: "Emite el PPTX 16:9 del documento-base. Default True." - name: emit_md desc: "Emite el Markdown autocontenido del documento-base. Default True." - name: per_table_eda desc: "Si True, anexa al documento-base los capitulos de mini-EDA de cada tabla (Heading 'Tabla: ' + build_document por tabla). Default False (solo documento-base: portada + resumen + relaciones)." - name: min_inclusion desc: "Umbral de inclusion (0-1) para emitir una FK candidata (se pasa a profile_database). Default 0.9." - name: ctx_extra desc: "Dict opcional de claves de presentacion (p.ej. dataset_name, description) que se mezclan en el contexto de la portada-base." output: "Dict dict-no-throw. En exito: {status:'ok', pdf_path, pptx_path, md_path, manifest_path, n_tables, n_pages, n_slides, md_chars, db_path, db_profile}. En error: {status:'error', error:str}." --- # render_automatic_eda_folder EDA de una **carpeta / base multi-tabla** → informe AutomaticEDA por capítulos en PDF (móvil A5) + PPTX (16:9) + Markdown, en una sola llamada. Es el hermano a nivel de **base** de `render_automatic_eda` (que perfila una sola tabla): aquí el documento resume **todas** las tablas y, sobre todo, sus **relaciones** inter-tabla (FK candidatas por containment + join graph con diagrama Mermaid). Compone, sin reimplementar su lógica: `load_folder_to_duckdb` (carga la carpeta), `profile_database` (perfila la base + infiere FK + join graph) y los tres renderers del motor AutomaticEDA (`render_automatic_eda_pdf`/`_pptx`/`_markdown`), que aceptan directamente la lista de capítulos del documento-base que este pipeline ensambla. El pipeline de tabla única (`render_automatic_eda`) queda intacto: esto es aditivo. ## Ejemplo ```bash # Carpeta con varios CSV/Parquet/JSON relacionados: ./fn run render_automatic_eda_folder /tmp/eda_folder_demo # Una DuckDB ya existente (rama directa): ./fn run render_automatic_eda_folder temp/bigdata/taxi.duckdb ``` ```python import sys, os sys.path.insert(0, os.path.join("python", "functions")) from pipelines.render_automatic_eda_folder import render_automatic_eda_folder r = render_automatic_eda_folder("/tmp/eda_folder_demo", out_dir="reports") # r["status"] == "ok"; r["pdf_path"], r["pptx_path"], r["md_path"] # r["n_tables"] == 3; r["db_profile"]["fk_candidates"] incluye # orders.customer_id -> customers.id ``` ## Cuando usarla Cuando quieras un EDA de una **base entera** (una carpeta de exports o una DuckDB con varias tablas), no de una sola tabla: para ver de un vistazo qué tablas hay, su tamaño y calidad, y cómo se relacionan (FK candidatas + diagrama), en el mismo formato rico por capítulos (PDF móvil + PPTX + MD) que el EDA de tabla. Usa `per_table_eda=True` cuando además quieras el mini-EDA de cada tabla anexado. ## Gotchas - Impuro: lee archivos del disco y escribe PDF/PPTX/MD en `out_dir`. En la rama "carpeta" crea una **DuckDB temporal** (su ruta sale en `db_path`); no se borra automáticamente (queda para reinspección). - `path` se interpreta así: directorio → se carga la carpeta; archivo con extensión `.duckdb`/`.ddb`/`.db` → se usa directo; cualquier otro archivo o un path inexistente → `{status:'error'}` (no lanza). - El escaneo de la carpeta es **no recursivo** (solo el primer nivel) y por defecto cubre `*.csv,*.parquet,*.json` (ver `load_folder_to_duckdb`). - El join graph se rasteriza a una **Figure matplotlib real** (vía `draw_join_graph_figure`) que aparece dibujada en PDF/PPTX (nodos = tablas, flechas = FK). Además, el **texto Mermaid** del grafo se incluye como bloque de código (en el Markdown queda como diagrama renderizable y es útil para pegar a un LLM). - Carpeta vacía o con 1 sola tabla: funciona igual; el capítulo de relaciones dice "sin FK". dict-no-throw en todos los caminos.