jupyter_discover: soporte multi-servidor, detección de modo colaborativo mejorada. jupyter_write: operaciones batch (insert, edit, delete), manejo robusto de Y.js. jupyter_exec: mejoras en ejecución directa al kernel. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Jupyter Notebook Tools
Cinco funciones Python para operar notebooks Jupyter programaticamente via API REST y WebSocket colaborativo (CRDT/Y.js). Reemplazan al MCP jupyter y funcionan desde cualquier directorio.
Flujo tipico
discover → read → write/exec
- Descubrir que Jupyter esta corriendo y en que puerto
- Leer celdas del notebook (estado en memoria, no disco)
- Escribir celdas nuevas o ejecutar codigo
PYTHON="python/.venv/bin/python3"
# 1. Descubrir instancias activas
$PYTHON python/functions/notebook/jupyter_discover.py --json
# 2. Leer notebook
$PYTHON python/functions/notebook/jupyter_read.py notebooks/01.ipynb --json
# 3. Crear notebook nuevo (si no existe)
$PYTHON python/functions/notebook/jupyter_write.py create notebooks/02.ipynb
# 4. Escribir celdas en batch
$PYTHON python/functions/notebook/jupyter_write.py batch notebooks/02.ipynb --from cells.json
# 5. Ejecutar celda
$PYTHON python/functions/notebook/jupyter_exec.py cell notebooks/02.ipynb 0
Funciones
jupyter_discover
Descubre instancias de Jupyter Lab activas. Escanea .jupyter-port en analysis/ y puertos 8888-8892. Detecta el root_dir real parseando /proc/{pid}/cmdline.
| Subcomando | Descripcion |
|---|---|
| (sin subcomando) | Lista instancias con puerto, analysis, root_dir, kernels, sesiones |
$PYTHON jupyter_discover.py --json
$PYTHON jupyter_discover.py --port 8888 --port 8889
Retorna por instancia: url, port, analysis, root_dir, collaborative, kernels, sessions.
jupyter_read
Lee celdas de un notebook via protocolo CRDT (estado en memoria, incluye cambios no guardados).
| Subcomando | Descripcion |
|---|---|
| (sin subcomando) | Lee todas las celdas (formato legible) |
--cell N |
Lee solo la celda N |
--info |
Solo metadata (total celdas, conteo por tipo) |
--json |
Salida JSON |
$PYTHON jupyter_read.py notebooks/01.ipynb --json
$PYTHON jupyter_read.py notebooks/01.ipynb --cell 3
$PYTHON jupyter_read.py notebooks/01.ipynb --info
jupyter_write
Operaciones de escritura sobre celdas via WebSocket colaborativo. NO ejecuta celdas.
| Subcomando | Descripcion |
|---|---|
create |
Crea un notebook .ipynb nuevo (API REST PUT) |
append-code |
Anade celda de codigo al final |
append-markdown |
Anade celda markdown al final |
insert |
Inserta celda en posicion especifica |
edit |
Sobrescribe contenido de celda existente |
delete |
Elimina una celda |
batch |
Escribe multiples celdas en una sola conexion WebSocket |
# Crear notebook
$PYTHON jupyter_write.py create notebooks/02.ipynb
$PYTHON jupyter_write.py create notebooks/02.ipynb --kernel python3 --force
# Celdas individuales
$PYTHON jupyter_write.py append-code notebooks/02.ipynb "import pandas as pd"
$PYTHON jupyter_write.py append-markdown notebooks/02.ipynb "## Titulo"
$PYTHON jupyter_write.py insert notebooks/02.ipynb 0 "x = 42" --type code
$PYTHON jupyter_write.py edit notebooks/02.ipynb 0 "# Titulo actualizado"
$PYTHON jupyter_write.py delete notebooks/02.ipynb 3
# Batch (una sola conexion para N celdas)
$PYTHON jupyter_write.py batch notebooks/02.ipynb --from cells.json
cat cells.json | $PYTHON jupyter_write.py batch notebooks/02.ipynb --from -
Formato cells.json:
[
{"type": "markdown", "source": "# Titulo"},
{"type": "code", "source": "import pandas as pd"},
{"type": "code", "source": "df = pd.read_csv('data.csv')"}
]
jupyter_exec
Ejecuta codigo en kernels de Jupyter via WebSocket.
| Subcomando | Descripcion |
|---|---|
append |
Anade celda al notebook y la ejecuta |
cell |
Ejecuta celda existente por indice |
kernel |
Ejecuta en el kernel sin tocar notebook |
$PYTHON jupyter_exec.py append notebooks/01.ipynb "df.describe()"
$PYTHON jupyter_exec.py cell notebooks/01.ipynb 3
$PYTHON jupyter_exec.py kernel "print(df.shape)"
Normaliza automaticamente celdas sin outputs o execution_count (comun en notebooks creados programaticamente).
jupyter_kernel
CRUD de kernels Jupyter via API REST.
| Subcomando | Descripcion |
|---|---|
list |
Lista kernels activos |
start |
Inicia kernel nuevo |
restart |
Reinicia kernel |
interrupt |
Interrumpe ejecucion |
shutdown |
Apaga y elimina kernel |
sessions |
Lista sesiones (mapeo notebook-kernel) |
$PYTHON jupyter_kernel.py list
$PYTHON jupyter_kernel.py start --name python3
$PYTHON jupyter_kernel.py restart <kernel_id>
$PYTHON jupyter_kernel.py shutdown <kernel_id>
$PYTHON jupyter_kernel.py sessions
Troubleshooting
WebSocket 4404 — notebook no existe
El servidor no puede abrir un documento CRDT para un archivo que no existe en disco.
Solucion: Crear el notebook primero con jupyter_write.py create.
$PYTHON jupyter_write.py create notebooks/nuevo.ipynb
$PYTHON jupyter_write.py append-code notebooks/nuevo.ipynb "print('hola')"
KeyError 'outputs' — celda sin estructura completa
Notebooks creados manualmente (no via Jupyter UI) pueden tener celdas de codigo sin los campos outputs y execution_count que el protocolo CRDT requiere.
Solucion: jupyter_exec.py normaliza automaticamente estas celdas antes de ejecutar. Si el problema persiste, recrear la celda con jupyter_write.py edit.
"Kernel does not exist" — sesion stale
El kernel referenciado ya no existe (fue apagado o el servidor se reinicio).
Solucion:
# Ver kernels activos
$PYTHON jupyter_kernel.py list
# Ver sesiones (mapeo notebook-kernel)
$PYTHON jupyter_kernel.py sessions
# Reiniciar kernel si necesario
$PYTHON jupyter_kernel.py restart <kernel_id>
"Document not yet synced" — timing de colaboracion
El cliente WebSocket no pudo sincronizar el documento CRDT a tiempo.
Solucion: Reintentar. Si persiste, verificar que el servidor tiene jupyter-collaboration activo:
$PYTHON jupyter_discover.py --json | python3 -c "import sys,json; [print(i['collaborative']) for i in json.load(sys.stdin)]"
Discover muestra analysis incorrecto
Versiones anteriores podian confundir instancias. La deteccion actual parsea --ServerApp.root_dir del cmdline del proceso via /proc/{pid}/cmdline.
Solucion: Actualizar a la version actual de jupyter_discover.py.
Parametros comunes
Todos los subcomandos aceptan:
| Flag | Default | Descripcion |
|---|---|---|
--server |
http://localhost:8888 |
URL del servidor Jupyter |
--token |
"" (vacio) |
Token de autenticacion |
Los paths de notebooks son siempre relativos a la raiz del servidor Jupyter (normalmente analysis/{tema}/).
Dependencias
| Paquete | Usado por | Para que |
|---|---|---|
jupyter_nbmodel_client |
write, exec, read | WebSocket colaborativo (CRDT/Y.js) |
jupyter_kernel_client |
exec | Ejecucion de codigo en kernels |
stdlib (urllib, json) |
discover, kernel, write (create) | API REST |
Diferencias con MCP jupyter
| Aspecto | MCP jupyter | Estas funciones |
|---|---|---|
| Requiere registro | Si (.mcp.json) | No |
| Funciona desde cualquier dir | No (solo desde el dir del MCP) | Si |
| Protocolo | MCP sobre stdio | HTTP REST + WebSocket directo |
| Crear notebooks | No | Si (write create) |
| Batch de celdas | No | Si (write batch) |
| Multi-instancia | No | Si (discover detecta todas) |
Limitaciones
- Requiere Jupyter Lab >= 4 con
jupyter-collaborationpara las funciones que usan WebSocket (write, exec, read) - Las funciones REST (discover, kernel) funcionan con cualquier Jupyter Lab 3.x/4.x y Notebook 6.x/7.x
- La deteccion de root_dir via
/procsolo funciona en Linux - No soportan autenticacion por cookie, solo por token
jupyter_write batchrequiere JSON como entrada (no YAML)