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>
Operaciones de escritura sobre celdas de un notebook Jupyter via colaboracion en tiempo real (WebSocket) y API REST. Expone siete operaciones: append_code, append_markdown, insert, edit, delete, create y batch. NO ejecuta celdas — solo modifica la estructura del notebook. create usa PUT /api/contents para crear notebooks nuevos sin necesidad de websocket. batch abre una unica conexion WebSocket para insertar N celdas en una sola operacion.
Todas las funciones son sincronas publicamente. Internamente usan asyncio.run() sobre corutinas async que se comunican via WebSocket con NbModelClient.
create es la excepcion: usa urllib (PUT /api/contents) sin WebSocket. Crea un nbformat 4 con celdas vacias. Lanza FileExistsError si el notebook ya existe y force=False.
batch es mucho mas eficiente que N llamadas a append-code/append-markdown: abre una sola conexion WebSocket y hace un unico asyncio.sleep(2) de sincronizacion al final.
El notebook_path es relativo al servidor Jupyter (no al filesystem local).
Si el servidor no esta corriendo o el token es incorrecto, lanza excepcion de conexion de jupyter_nbmodel_client.
NO ejecuta celdas — solo modifica la estructura. Para ejecutar, usar jupyter_exec.
server_url y token tienen defaults convenientes para desarrollo local (http://localhost:8888, token vacio).
El campo cell_index en el resultado refleja la posicion final de la celda en el notebook.
Patron tipico: create para crear el notebook, luego batch para poblar las celdas iniciales.