---
name: jupyter_run_all
kind: function
lang: py
domain: notebook
version: "1.0.0"
purity: impure
signature: "jupyter_run_all(notebook_path: str, server_url: str, token: str, restart_kernel: bool, stop_on_error: bool, timeout_per_cell_s: int) -> dict"
description: "Ejecuta todas las celdas de codigo de un notebook Jupyter en orden, con reinicio opcional del kernel antes de empezar. Equivalente al boton 'Run All' del UI pero invocable desde CLI/MCP/agente. Persiste outputs a disco via REST."
tags: [jupyter, notebook, kernel, run-all, smoke-test, ci, execution, notebook]
uses_functions: [jupyter_run_cells_py_notebook]
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [jupyter_kernel_client, urllib, json, time]
params:
  - name: notebook_path
    desc: "Ruta relativa al notebook desde la raiz del servidor Jupyter (ej: 'notebooks/analisis.ipynb')"
  - name: server_url
    desc: "URL base del servidor Jupyter (default http://localhost:8888)"
  - name: token
    desc: "Token de autenticacion del servidor. Vacio si no se requiere auth"
  - name: restart_kernel
    desc: "Si True, reinicia el kernel antes de ejecutar para garantizar estado limpio. Default True"
  - name: stop_on_error
    desc: "Si True, detiene la ejecucion cuando una celda produce error. Default True"
  - name: timeout_per_cell_s
    desc: "Timeout en segundos por celda. Default 600 (10 minutos)"
output: "Dict con notebook, code_cell_indices, executed (lista de resultados por celda con cell_index/execution_count/outputs/error/duration_s), stopped_at (indice de la celda donde se detuvo si hubo error), kernel_id y total_duration_s"
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/notebook/jupyter_run_all.py"
---

## Ejemplo

```bash
# CLI: ejecutar todas las celdas con kernel limpio
python -m notebook.jupyter_run_all notebooks/analisis.ipynb

# CLI: ejecutar sin reiniciar kernel y continuar si hay errores
python -m notebook.jupyter_run_all notebooks/analisis.ipynb --no-restart --continue-on-error

# CLI: salida JSON completa
python -m notebook.jupyter_run_all notebooks/analisis.ipynb --server http://localhost:8888
```

```python
# Importar y usar desde Python
import sys
sys.path.insert(0, "python/functions")

from notebook.jupyter_run_all import jupyter_run_all

result = jupyter_run_all(
    notebook_path="notebooks/analisis.ipynb",
    server_url="http://localhost:8888",
    token="",
    restart_kernel=True,
    stop_on_error=True,
)

print(f"Ejecutadas: {len(result['executed'])} celdas en {result['total_duration_s']}s")
if result["stopped_at"] is not None:
    print(f"ERROR en celda {result['stopped_at']}")
    failed = next(e for e in result["executed"] if e["cell_index"] == result["stopped_at"])
    print(failed["error"])
```

Salida ejemplo:
```json
{
  "notebook": "notebooks/analisis.ipynb",
  "code_cell_indices": [0, 1, 2, 4, 6],
  "executed": [
    {"cell_index": 0, "execution_count": 1, "outputs": ["pandas 2.2.1"], "error": null, "duration_s": 0.312},
    {"cell_index": 1, "execution_count": 2, "outputs": ["(1500, 12)"], "error": null, "duration_s": 0.085}
  ],
  "stopped_at": null,
  "kernel_id": "a1b2c3d4-...",
  "total_duration_s": 4.217
}
```

## Cuando usarla

Usar `jupyter_run_all` cuando necesitas:
- Smoke test de un notebook despues de cambiar dependencias (confirma que ejecuta de principio a fin).
- Validar un notebook en CI/CD o desde un agente sin abrir el UI de Jupyter Lab.
- Regenerar todos los outputs del notebook con estado limpio (restart_kernel=True).
- Detectar celdas que fallan antes de compartir o publicar el notebook.

No usar para ejecutar una sola celda — usar `jupyter_exec` (modo `cell` o `kernel`) para eso.

## Gotchas

- **Requiere sesion activa**: el kernel del notebook debe estar corriendo. Si el notebook no esta abierto en Jupyter Lab, llamar antes a `jupyter_exec` para crear la sesion, o abrir el notebook manualmente. Error: `RuntimeError: No hay sesion activa`.
- **restart_kernel=True limpia TODO el estado**: variables, imports, estado de modulos. Si el notebook depende de estado previo (interactivo), usar `restart_kernel=False`.
- **stop_on_error=True es el default**: una celda con error detiene el resto. Para runs de diagnostico donde quieres ver todos los errores, pasar `stop_on_error=False`.
- **Timeout por celda**: `timeout_per_cell_s=600` (10 min) es el maximo por celda individual. Celdas con operaciones largas (entrenamiento ML, queries pesadas) pueden necesitar valor mayor.
- **Outputs se persisten a disco**: al terminar, el notebook se guarda via REST con los nuevos outputs. Jupyter Lab puede pedir "Revert to disk" si el usuario tiene cambios no guardados en el browser.
- **Celdas vacias se saltan**: una celda de codigo cuyo `source` es solo espacios o saltos de linea se omite (execution_count queda None, outputs=[]).
- **`jupyter_run_cells` como dependencia futura**: cuando `jupyter_run_cells_py_notebook` este disponible, el batch de ejecucion puede delegarse a esa funcion. Hoy la logica es autonoma.
