feat: mejoras notebook functions — discover multi-servidor, write batch ops
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>
This commit is contained in:
@@ -3,11 +3,11 @@ name: jupyter_discover
|
||||
kind: function
|
||||
lang: py
|
||||
domain: notebook
|
||||
version: "1.0.0"
|
||||
version: "1.1.0"
|
||||
purity: impure
|
||||
signature: "def jupyter_discover(registry_root: str = \"\", ports: list[int] | None = None) -> list[dict]"
|
||||
description: "Descubre instancias de Jupyter Lab activas escaneando archivos .jupyter-port en analysis/ y puertos comunes (8888-8892). Para cada instancia consulta /api/status, /api/config, /api/kernels y /api/sessions via HTTP REST."
|
||||
tags: [jupyter, notebook, discovery, api, http, kernels, sessions, analysis]
|
||||
description: "Descubre instancias de Jupyter Lab activas escaneando archivos .jupyter-port en analysis/ y puertos comunes (8888-8892). Detecta el root_dir real de cada instancia via /proc/pid/cmdline (Linux) para identificar correctamente el analisis en escenarios multi-instancia. Para cada instancia consulta /api/status, /api/config, /api/kernels y /api/sessions via HTTP REST."
|
||||
tags: [jupyter, notebook, discovery, api, http, kernels, sessions, analysis, multi-instance, proc]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
@@ -32,8 +32,8 @@ instances = jupyter_discover(registry_root="/home/lucas/fn_registry")
|
||||
instances = jupyter_discover(ports=[8888, 8900])
|
||||
|
||||
for inst in instances:
|
||||
print(inst["url"], inst["collaborative"], len(inst["kernels"]))
|
||||
# http://localhost:8888 True 2
|
||||
print(inst["url"], inst["analysis"], inst["root_dir"], inst["collaborative"])
|
||||
# http://localhost:8888 estudio_mercados /home/lucas/fn_registry/analysis/estudio_mercados True
|
||||
```
|
||||
|
||||
## Estructura del dict retornado
|
||||
@@ -44,8 +44,9 @@ Cada elemento de la lista tiene la siguiente forma:
|
||||
{
|
||||
"url": "http://localhost:8888",
|
||||
"port": 8888,
|
||||
"analysis": "finanzas_personales", # nombre del subdirectorio en analysis/, o ""
|
||||
"collaborative": True, # True si YDocExtension esta activo
|
||||
"analysis": "estudio_mercados", # nombre del subdirectorio en analysis/, detectado via /proc
|
||||
"root_dir": "/home/lucas/fn_registry/analysis/estudio_mercados", # path absoluto real del proceso
|
||||
"collaborative": True, # True si YDocExtension esta activo
|
||||
"kernels": [
|
||||
{
|
||||
"id": "abc123...",
|
||||
@@ -77,12 +78,50 @@ python python/functions/notebook/jupyter_discover.py --port 8888 --port 8889 --j
|
||||
FN_REGISTRY_ROOT=/home/lucas/fn_registry python python/functions/notebook/jupyter_discover.py
|
||||
```
|
||||
|
||||
Ejemplo de salida en modo texto con multi-instancia:
|
||||
|
||||
```
|
||||
Puerto 8888 [colaborativo]
|
||||
url: http://localhost:8888
|
||||
analysis: estudio_mercados
|
||||
root_dir: /home/lucas/fn_registry/analysis/estudio_mercados
|
||||
kernels (1):
|
||||
- python3 estado=idle id=abc12345...
|
||||
sesiones (1):
|
||||
- notebooks/01.ipynb kernel=abc12345... estado=idle
|
||||
|
||||
Puerto 8889 [estandar]
|
||||
url: http://localhost:8889
|
||||
analysis: estudio_embeddings
|
||||
root_dir: /home/lucas/fn_registry/analysis/estudio_embeddings
|
||||
kernels: ninguno
|
||||
sesiones: ninguna
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Solo usa stdlib: `urllib`, `json`, `pathlib`, `os`. No requiere `requests` ni clientes Jupyter especializados.
|
||||
|
||||
El escaneo de puertos tiene un timeout de 2 segundos por instancia para no bloquear en puertos cerrados.
|
||||
|
||||
### Deteccion de root_dir via /proc
|
||||
|
||||
En Linux, `_find_jupyter_pid_for_port()` escanea `/proc/*/cmdline` buscando el proceso Jupyter que tenga `--port=N` o `--ServerApp.port=N` en sus argumentos. Para el puerto default 8888, acepta cualquier proceso jupyter sin `--port` explicito.
|
||||
|
||||
Una vez encontrado el PID, `_get_root_dir_from_proc()` lee los argumentos buscando `--ServerApp.root_dir=` o `--notebook-dir=`. Si ninguno esta presente, usa el cwd del proceso (`/proc/{pid}/cwd`) como fallback.
|
||||
|
||||
La funcion `_extract_analysis_name()` extrae el nombre del analisis del root_dir: si el path contiene `analysis/{nombre}`, retorna `{nombre}`; en caso contrario retorna el ultimo componente del path.
|
||||
|
||||
Esta cadena es mas fiable que confiar solo en `.jupyter-port` porque detecta el directorio real del proceso, no el registrado al arranque.
|
||||
|
||||
### Prioridad de fuentes para analysis name
|
||||
|
||||
1. root_dir detectado via /proc (mas fiable)
|
||||
2. Hint del archivo .jupyter-port (fallback si /proc no esta disponible)
|
||||
3. Cadena vacia si ninguno funciona
|
||||
|
||||
### Modo colaborativo
|
||||
|
||||
La deteccion de modo colaborativo busca `YDocExtension` o `collaborative` en el JSON de `/api/config`. Esto cubre tanto jupyter-collaboration >= 2.x (que expone la extension bajo `LabApp`) como configuraciones antiguas.
|
||||
|
||||
Archivos `.jupyter-port`: el pipeline `init_jupyter_analysis` escribe este archivo en cada analisis al lanzar Jupyter, permitiendo que `jupyter_discover` los encuentre sin escanear todos los puertos.
|
||||
|
||||
Reference in New Issue
Block a user