--- name: jupyter_discover kind: function lang: py domain: notebook version: "1.0.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] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [json, os, urllib.error, urllib.request, pathlib] tested: false tests: [] test_file_path: "" file_path: "python/functions/notebook/jupyter_discover.py" --- ## Ejemplo ```python from notebook.jupyter_discover import jupyter_discover # Descubrir con deteccion automatica de puertos instances = jupyter_discover(registry_root="/home/lucas/fn_registry") # Escanear puertos especificos instances = jupyter_discover(ports=[8888, 8900]) for inst in instances: print(inst["url"], inst["collaborative"], len(inst["kernels"])) # http://localhost:8888 True 2 ``` ## Estructura del dict retornado Cada elemento de la lista tiene la siguiente forma: ```python { "url": "http://localhost:8888", "port": 8888, "analysis": "finanzas_personales", # nombre del subdirectorio en analysis/, o "" "collaborative": True, # True si YDocExtension esta activo "kernels": [ { "id": "abc123...", "name": "python3", "execution_state": "idle", "last_activity": "2026-04-01T10:00:00.000Z" } ], "sessions": [ { "notebook": "notebooks/01_exploracion.ipynb", "kernel_id": "abc123...", "kernel_state": "idle" } ] } ``` ## CLI ```bash # Descubrir con deteccion automatica python python/functions/notebook/jupyter_discover.py --registry-root /home/lucas/fn_registry # Puertos especificos, salida JSON python python/functions/notebook/jupyter_discover.py --port 8888 --port 8889 --json # Usando variable de entorno FN_REGISTRY_ROOT=/home/lucas/fn_registry python python/functions/notebook/jupyter_discover.py ``` ## 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. 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.