--- name: jupyter_run_cells kind: function lang: py domain: notebook version: "1.0.0" purity: impure signature: "jupyter_run_cells(notebook_path: str, cell_indices: list[int], server_url: str, token: str, stop_on_error: bool, timeout_per_cell_s: int) -> dict" description: "Ejecuta un lote de celdas existentes (por indice) en una sola conexion WebSocket. Un GET inicial + un PUT final. Latencia fija ~3s en vez de ~3s * N de jupyter_execute_cell individual." tags: [jupyter, notebook, kernel, websocket, execution, cells, batch, notebook] uses_functions: [jupyter_exec_py_notebook] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [jupyter_kernel_client, notebook.jupyter_exec] params: - name: notebook_path desc: "Ruta relativa al notebook (relativa a la raiz del servidor Jupyter)" - name: cell_indices desc: "Lista de indices de celdas a ejecutar (0-based, en orden). Solo celdas de tipo code." - name: server_url desc: "URL del servidor Jupyter (default http://localhost:8888)" - name: token desc: "Token de autenticacion (default vacio = sin auth)" - name: stop_on_error desc: "Si True, para al primer output de tipo error. El PUT se hace con lo ejecutado hasta ese punto." - name: timeout_per_cell_s desc: "Timeout en segundos por cada ejecucion individual de celda (default 600)" output: "Dict con notebook, executed (lista de resultados por celda), stopped_at, kernel_id y total_duration_s" tested: true tests: - "test_run_cells_single_cell_returns_output" - "test_run_cells_stops_on_error_by_default" - "test_run_cells_no_stop_on_error_continues" - "test_run_cells_invalid_index_raises" - "test_run_cells_non_code_cell_raises" - "e2e: test_e2e_run_cells_batch" - "e2e: test_e2e_run_cells_stop_on_error" test_file_path: "python/functions/notebook/tests/test_jupyter_run_cells.py" file_path: "python/functions/notebook/jupyter_run_cells.py" --- ## Ejemplo ```python from notebook.jupyter_run_cells import jupyter_run_cells result = jupyter_run_cells( notebook_path="notebooks/analisis.ipynb", cell_indices=[0, 1, 2, 5], server_url="http://localhost:8888", token="", stop_on_error=True, ) # { # "notebook": "notebooks/analisis.ipynb", # "executed": [ # {"cell_index": 0, "execution_count": 1, "outputs": ["import ok"], "error": None, "duration_s": 1.2}, # {"cell_index": 1, "execution_count": 2, "outputs": ["42"], "error": None, "duration_s": 0.1}, # ... # ], # "stopped_at": None, # "kernel_id": "abc-123", # "total_duration_s": 4.8, # } ``` CLI: ```bash # Indices como argumentos posicionales python python/functions/notebook/jupyter_run_cells.py notebooks/analisis.ipynb 0 1 2 5 # Indices via stdin JSON (util desde scripts) echo '[0, 1, 2, 5]' | python python/functions/notebook/jupyter_run_cells.py notebooks/analisis.ipynb # No parar en error + timeout custom python python/functions/notebook/jupyter_run_cells.py notebooks/analisis.ipynb 0 1 2 \ --no-stop-on-error --timeout 120 ``` ## Cuando usarla Cuando necesites re-ejecutar varias celdas de un notebook existente y el overhead de abrir/cerrar N conexiones WS sea inaceptable (>3 celdas, celdas pesadas, o en pipelines automatizados). Sustituye a llamar `jupyter_execute_cell` N veces en bucle desde el agente. ## Gotchas - Las celdas deben existir previamente en el notebook. Para anadir y ejecutar celdas nuevas, usar `jupyter_append_execute` de `jupyter_exec`. - Solo ejecuta celdas de tipo `code`. Pasar el indice de una celda markdown lanza `ValueError` antes de abrir el WS. - El `PUT` final se hace siempre, incluso si `stop_on_error` detiene el lote. El notebook queda con los outputs de las celdas ejecutadas hasta el punto de parada. - `KernelClient` ignora `timeout_per_cell_s` si la implementacion subyacente no lo soporta (depende de la version de `jupyter-kernel-client`). En ese caso el timeout global del proceso es el unico limite. - Si el servidor Jupyter no esta corriendo, `_ensure_session` lanza `URLError` inmediatamente (no hay retry incorporado). - El WS se abre con el `kernel_id` de la sesion activa del notebook. Si el kernel muere entre el `_ensure_session` y la ejecucion, `KernelClient` lanzara una excepcion.