fc8062bade
Auto-create notebooks y sesiones en jupyter_exec (append y cell). Auto-create en jupyter_write (append_code, append_markdown, batch). Nuevos subcomandos cleanup y shutdown-all en jupyter_kernel. README.md renombrado a README.txt para evitar error de parseo del indexer. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
232 lines
7.6 KiB
Plaintext
232 lines
7.6 KiB
Plaintext
# 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
|
|
```
|
|
|
|
1. **Descubrir** que Jupyter esta corriendo y en que puerto
|
|
2. **Leer** celdas del notebook (estado en memoria, no disco)
|
|
3. **Escribir** celdas nuevas o **ejecutar** codigo
|
|
|
|
```bash
|
|
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 |
|
|
|
|
```bash
|
|
$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 |
|
|
|
|
```bash
|
|
$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 |
|
|
|
|
```bash
|
|
# 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`:
|
|
```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 |
|
|
|
|
```bash
|
|
$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) |
|
|
|
|
```bash
|
|
$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`.
|
|
|
|
```bash
|
|
$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:**
|
|
```bash
|
|
# 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:
|
|
```bash
|
|
$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-collaboration` para 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 `/proc` solo funciona en Linux
|
|
- No soportan autenticacion por cookie, solo por token
|
|
- `jupyter_write batch` requiere JSON como entrada (no YAML)
|