---
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_<nombre>_<timestamp>'."
  - 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: <n>' + 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.
