a1b7e5e143
Agentes especializados (fn-constructor, fn-executor, fn-recopilador) y comandos de usuario (analysis, app, create_functions). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
372 lines
13 KiB
Markdown
372 lines
13 KiB
Markdown
# /analysis — Trabajar con analisis Jupyter y notebooks del registry
|
|
|
|
Eres un agente de analisis de datos. Tienes acceso a funciones Python del fn_registry para **crear, gestionar y operar analisis Jupyter** completos: descubrir instancias, crear notebooks, escribir celdas, ejecutar codigo, leer resultados y gestionar kernels. Usa estas funciones directamente — no uses MCP jupyter ni manipules archivos .ipynb a mano.
|
|
|
|
---
|
|
|
|
## Como ejecutar funciones
|
|
|
|
```bash
|
|
PYTHON="python/.venv/bin/python3"
|
|
|
|
# Ejecutar codigo inline
|
|
$PYTHON -c "
|
|
import sys; sys.path.insert(0, 'python/functions')
|
|
from notebook import jupyter_discover
|
|
print(jupyter_discover.jupyter_discover())
|
|
"
|
|
|
|
# O via CLI (cada funcion tiene su propio CLI)
|
|
$PYTHON python/functions/notebook/jupyter_discover.py --json
|
|
$PYTHON python/functions/notebook/jupyter_write.py create notebooks/01.ipynb
|
|
$PYTHON python/functions/notebook/jupyter_exec.py append notebooks/01.ipynb "print('hola')"
|
|
$PYTHON python/functions/notebook/jupyter_kernel.py list
|
|
|
|
# Pipelines con fn run
|
|
./fn run init_jupyter_analysis mi_analisis
|
|
./fn run init_jupyter_analysis ml scikit-learn torch
|
|
./fn run export_analysis_pdfs mi_analisis
|
|
```
|
|
|
|
---
|
|
|
|
## CREAR UN ANALISIS NUEVO
|
|
|
|
```bash
|
|
# Basico (crea venv, launcher, MCP, reglas Claude, kernel startup)
|
|
./fn run init_jupyter_analysis nombre_analisis
|
|
|
|
# Con paquetes extra
|
|
./fn run init_jupyter_analysis nombre_analisis pandas scikit-learn matplotlib
|
|
|
|
# Despues de crear:
|
|
cd analysis/nombre_analisis && ./run-jupyter-lab.sh # Terminal 1: lanzar Jupyter
|
|
cd analysis/nombre_analisis && claude # Terminal 2: abrir Claude
|
|
# Navegador: http://localhost:8888
|
|
```
|
|
|
|
Estructura generada:
|
|
```
|
|
analysis/nombre_analisis/
|
|
.venv/ # Deps propias (gitignored)
|
|
.mcp.json # MCP jupyter (gitignored)
|
|
.claude/CLAUDE.md # Reglas para agentes
|
|
.ipython/profile_default/startup/
|
|
00_fn_registry.py # Helpers fn_search, fn_query, fn_code
|
|
notebooks/ # Notebooks aqui
|
|
data/ # Datos locales (gitignored)
|
|
run-jupyter-lab.sh # Launcher colaborativo
|
|
pyproject.toml # Deps con uv
|
|
```
|
|
|
|
---
|
|
|
|
## DISCOVER — Descubrir instancias Jupyter
|
|
|
|
```python
|
|
from notebook.jupyter_discover import jupyter_discover
|
|
|
|
# Descubrir todas las instancias activas
|
|
instances = jupyter_discover()
|
|
# [{"url": "http://localhost:8888", "status": "running", "collaborative": true,
|
|
# "root_dir": "/home/user/fn_registry/analysis/mi_analisis",
|
|
# "analysis_name": "mi_analisis", "kernels": 2, "sessions": 1, "pid": 12345}]
|
|
|
|
# Con registry_root explicito
|
|
instances = jupyter_discover(registry_root="/home/user/fn_registry")
|
|
```
|
|
|
|
```bash
|
|
$PYTHON python/functions/notebook/jupyter_discover.py --json
|
|
```
|
|
|
|
**SIEMPRE ejecutar discover primero** para confirmar que Jupyter esta activo antes de operar sobre notebooks.
|
|
|
|
---
|
|
|
|
## WRITE — Escribir en notebooks
|
|
|
|
Las funciones append y batch **crean el notebook automaticamente** si no existe. No es necesario abrir el notebook en el navegador primero.
|
|
|
|
```python
|
|
from notebook.jupyter_write import (
|
|
jupyter_create_notebook, # Crear notebook vacio (REST)
|
|
jupyter_append_code, # Anadir celda de codigo al final
|
|
jupyter_append_markdown, # Anadir celda markdown al final
|
|
jupyter_insert_cell, # Insertar celda en posicion especifica
|
|
jupyter_edit_cell, # Sobrescribir contenido de celda
|
|
jupyter_delete_cell, # Eliminar celda
|
|
jupyter_batch_write, # Anadir N celdas en una conexion
|
|
)
|
|
|
|
# Crear notebook y poblar celdas (una sola llamada)
|
|
jupyter_batch_write("notebooks/01.ipynb", [
|
|
{"type": "markdown", "source": "# Analisis exploratorio"},
|
|
{"type": "code", "source": "import pandas as pd\nimport matplotlib.pyplot as plt"},
|
|
{"type": "code", "source": "df = pd.read_csv('data/dataset.csv')\ndf.head()"},
|
|
])
|
|
# {"action": "batch", "cells_added": 3, "notebook": "notebooks/01.ipynb"}
|
|
|
|
# Crear notebook explicitamente (si se necesita control)
|
|
jupyter_create_notebook("notebooks/02.ipynb", kernel_name="python3")
|
|
# force=True para sobreescribir
|
|
|
|
# Anadir celdas individuales
|
|
jupyter_append_code("notebooks/01.ipynb", "df.describe()")
|
|
jupyter_append_markdown("notebooks/01.ipynb", "## Resultados")
|
|
|
|
# Insertar en posicion 2
|
|
jupyter_insert_cell("notebooks/01.ipynb", 2, "x = 42", cell_type="code")
|
|
|
|
# Editar celda existente
|
|
jupyter_edit_cell("notebooks/01.ipynb", 0, "# Titulo actualizado")
|
|
|
|
# Eliminar celda
|
|
jupyter_delete_cell("notebooks/01.ipynb", 3)
|
|
```
|
|
|
|
```bash
|
|
# CLI
|
|
$PYTHON python/functions/notebook/jupyter_write.py create notebooks/01.ipynb
|
|
$PYTHON python/functions/notebook/jupyter_write.py append-code notebooks/01.ipynb "print('hola')"
|
|
$PYTHON python/functions/notebook/jupyter_write.py append-markdown notebooks/01.ipynb "## Titulo"
|
|
$PYTHON python/functions/notebook/jupyter_write.py insert notebooks/01.ipynb 2 "x = 42" --type code
|
|
$PYTHON python/functions/notebook/jupyter_write.py edit notebooks/01.ipynb 0 "# Nuevo titulo"
|
|
$PYTHON python/functions/notebook/jupyter_write.py delete notebooks/01.ipynb 3
|
|
|
|
# Batch desde JSON
|
|
echo '[{"type":"code","source":"import pandas as pd"},{"type":"markdown","source":"## Datos"}]' | \
|
|
$PYTHON python/functions/notebook/jupyter_write.py batch notebooks/01.ipynb
|
|
```
|
|
|
|
---
|
|
|
|
## EXEC — Ejecutar codigo en notebooks
|
|
|
|
`jupyter_append_execute` **crea el notebook y arranca un kernel automaticamente** si no existen. No es necesario abrir el notebook manualmente.
|
|
|
|
```python
|
|
from notebook.jupyter_exec import (
|
|
jupyter_append_execute, # Anadir celda + ejecutar (auto-init)
|
|
jupyter_execute_cell, # Ejecutar celda existente por indice
|
|
jupyter_kernel_execute, # Ejecutar en kernel sin tocar notebook
|
|
)
|
|
|
|
# Crear notebook + kernel + ejecutar celda (todo automatico)
|
|
result = jupyter_append_execute("notebooks/01.ipynb", "import pandas as pd\nprint(pd.__version__)")
|
|
# {"cell_index": 0, "outputs": ["2.2.1"]}
|
|
|
|
# Ejecutar mas celdas
|
|
result = jupyter_append_execute("notebooks/01.ipynb", "df = pd.DataFrame({'a': [1,2,3]})\ndf.shape")
|
|
# {"cell_index": 1, "outputs": ["(3, 1)"]}
|
|
|
|
# Ejecutar celda existente por indice
|
|
result = jupyter_execute_cell("notebooks/01.ipynb", 0)
|
|
# {"cell_index": 0, "outputs": ["2.2.1"]}
|
|
|
|
# Ejecutar en kernel directamente (sin tocar notebook)
|
|
result = jupyter_kernel_execute("len(df)")
|
|
# {"outputs": ["3"], "status": "ok"}
|
|
```
|
|
|
|
```bash
|
|
# CLI
|
|
$PYTHON python/functions/notebook/jupyter_exec.py append notebooks/01.ipynb "print('hola')"
|
|
$PYTHON python/functions/notebook/jupyter_exec.py cell notebooks/01.ipynb 3
|
|
$PYTHON python/functions/notebook/jupyter_exec.py kernel "print(42)"
|
|
```
|
|
|
|
---
|
|
|
|
## READ — Leer notebooks
|
|
|
|
Lee el estado en memoria (CRDT), incluyendo cambios no guardados.
|
|
|
|
```python
|
|
from notebook.jupyter_read import (
|
|
jupyter_read_cells, # Leer todas las celdas o una especifica
|
|
jupyter_notebook_info, # Metadata rapida (conteo de celdas)
|
|
)
|
|
|
|
# Leer todas las celdas
|
|
cells = jupyter_read_cells("notebooks/01.ipynb")
|
|
# [{"index": 0, "type": "code", "source": "import pandas", "outputs": ["..."]}]
|
|
|
|
# Leer celda especifica
|
|
cell = jupyter_read_cells("notebooks/01.ipynb", cell_index=2)
|
|
|
|
# Info del notebook
|
|
info = jupyter_notebook_info("notebooks/01.ipynb")
|
|
# {"total_cells": 10, "code_cells": 7, "markdown_cells": 3}
|
|
```
|
|
|
|
```bash
|
|
$PYTHON python/functions/notebook/jupyter_read.py notebooks/01.ipynb --json
|
|
$PYTHON python/functions/notebook/jupyter_read.py notebooks/01.ipynb --cell 2 --json
|
|
$PYTHON python/functions/notebook/jupyter_read.py notebooks/01.ipynb --info --json
|
|
```
|
|
|
|
---
|
|
|
|
## KERNEL — Gestionar kernels
|
|
|
|
```python
|
|
from notebook.jupyter_kernel import (
|
|
jupyter_kernel_list, # Listar kernels activos
|
|
jupyter_kernel_start, # Iniciar kernel nuevo
|
|
jupyter_kernel_restart, # Reiniciar kernel
|
|
jupyter_kernel_interrupt, # Interrumpir ejecucion
|
|
jupyter_kernel_shutdown, # Apagar kernel individual
|
|
jupyter_kernel_sessions, # Listar sesiones (notebook <-> kernel)
|
|
jupyter_kernel_cleanup, # Apagar kernels inactivos
|
|
jupyter_kernel_shutdown_all, # Apagar todos los kernels
|
|
)
|
|
|
|
# Listar kernels activos
|
|
kernels = jupyter_kernel_list()
|
|
# [{"id": "abc123", "name": "python3", "execution_state": "idle",
|
|
# "last_activity": "2026-04-07T10:00:00Z", "connections": 1}]
|
|
|
|
# Iniciar kernel nuevo
|
|
kernel = jupyter_kernel_start(name="python3")
|
|
|
|
# Ver sesiones (que notebook usa que kernel)
|
|
sessions = jupyter_kernel_sessions()
|
|
# [{"id": "s1", "notebook": "notebooks/01.ipynb", "kernel_id": "abc123", "kernel_state": "idle"}]
|
|
|
|
# Reiniciar kernel
|
|
jupyter_kernel_restart(kernel_id="abc123")
|
|
|
|
# Interrumpir ejecucion larga
|
|
jupyter_kernel_interrupt(kernel_id="abc123")
|
|
|
|
# Apagar kernel individual
|
|
jupyter_kernel_shutdown(kernel_id="abc123")
|
|
|
|
# Limpiar kernels inactivos (default: 1h sin actividad)
|
|
cleaned = jupyter_kernel_cleanup(idle_seconds=1800)
|
|
# [{"id": "abc123", "name": "python3", "last_activity": "...", "idle_seconds": 3601}]
|
|
|
|
# Apagar TODOS los kernels
|
|
jupyter_kernel_shutdown_all()
|
|
```
|
|
|
|
```bash
|
|
$PYTHON python/functions/notebook/jupyter_kernel.py list
|
|
$PYTHON python/functions/notebook/jupyter_kernel.py start --name python3
|
|
$PYTHON python/functions/notebook/jupyter_kernel.py sessions
|
|
$PYTHON python/functions/notebook/jupyter_kernel.py restart <kernel_id>
|
|
$PYTHON python/functions/notebook/jupyter_kernel.py interrupt <kernel_id>
|
|
$PYTHON python/functions/notebook/jupyter_kernel.py shutdown <kernel_id>
|
|
$PYTHON python/functions/notebook/jupyter_kernel.py cleanup --idle-seconds 1800
|
|
$PYTHON python/functions/notebook/jupyter_kernel.py shutdown-all
|
|
```
|
|
|
|
---
|
|
|
|
## Flujos tipicos
|
|
|
|
### 1. Analisis desde cero (sin abrir navegador)
|
|
|
|
```python
|
|
import sys; sys.path.insert(0, "python/functions")
|
|
from notebook.jupyter_discover import jupyter_discover
|
|
from notebook.jupyter_exec import jupyter_append_execute
|
|
|
|
# 1. Verificar que Jupyter esta corriendo
|
|
instances = jupyter_discover()
|
|
assert instances, "Jupyter no esta corriendo. Ejecuta: cd analysis/mi_analisis && ./run-jupyter-lab.sh"
|
|
|
|
# 2. Crear notebook + kernel + ejecutar (todo automatico)
|
|
jupyter_append_execute("notebooks/01.ipynb", "import pandas as pd\nimport numpy as np")
|
|
jupyter_append_execute("notebooks/01.ipynb", "df = pd.read_csv('data/dataset.csv')\ndf.shape")
|
|
jupyter_append_execute("notebooks/01.ipynb", "df.describe()")
|
|
```
|
|
|
|
### 2. Poblar notebook con estructura y ejecutar
|
|
|
|
```python
|
|
from notebook.jupyter_write import jupyter_batch_write
|
|
from notebook.jupyter_exec import jupyter_append_execute
|
|
|
|
# 1. Crear estructura del notebook
|
|
jupyter_batch_write("notebooks/02.ipynb", [
|
|
{"type": "markdown", "source": "# Analisis de ventas Q1 2026"},
|
|
{"type": "markdown", "source": "## 1. Carga de datos"},
|
|
{"type": "code", "source": "import pandas as pd\ndf = pd.read_csv('data/ventas.csv')"},
|
|
{"type": "markdown", "source": "## 2. Exploracion"},
|
|
{"type": "code", "source": "df.info()"},
|
|
{"type": "code", "source": "df.describe()"},
|
|
{"type": "markdown", "source": "## 3. Visualizacion"},
|
|
])
|
|
|
|
# 2. Ejecutar celdas de codigo
|
|
from notebook.jupyter_exec import jupyter_execute_cell
|
|
jupyter_execute_cell("notebooks/02.ipynb", 2) # import + read_csv
|
|
jupyter_execute_cell("notebooks/02.ipynb", 4) # info
|
|
jupyter_execute_cell("notebooks/02.ipynb", 5) # describe
|
|
```
|
|
|
|
### 3. Limpiar recursos
|
|
|
|
```python
|
|
from notebook.jupyter_kernel import jupyter_kernel_cleanup, jupyter_kernel_sessions
|
|
|
|
# Ver que esta corriendo
|
|
sessions = jupyter_kernel_sessions()
|
|
for s in sessions:
|
|
print(f"{s['notebook']} -> kernel {s['kernel_id']} ({s['kernel_state']})")
|
|
|
|
# Apagar kernels inactivos (30 min sin actividad)
|
|
cleaned = jupyter_kernel_cleanup(idle_seconds=1800)
|
|
print(f"Apagados {len(cleaned)} kernels inactivos")
|
|
```
|
|
|
|
### 4. Exportar a PDF
|
|
|
|
```bash
|
|
./fn run export_analysis_pdfs mi_analisis
|
|
```
|
|
|
|
---
|
|
|
|
## Acceso al registry desde notebooks
|
|
|
|
El kernel startup (`00_fn_registry.py`) provee helpers automaticamente:
|
|
|
|
```python
|
|
# Disponibles sin importar nada:
|
|
fn_search("slice") # Busca funciones y tipos
|
|
fn_query("SELECT ...") # SQL directo sobre registry.db
|
|
fn_code("filter_list_py_core") # Codigo fuente de una funcion
|
|
|
|
# Importar funciones Python del registry:
|
|
from core import filter_list, map_list, reduce_list
|
|
from finance import sma, ema, rsi
|
|
```
|
|
|
|
---
|
|
|
|
## Pipelines disponibles
|
|
|
|
| Pipeline | Descripcion |
|
|
|----------|-------------|
|
|
| `init_jupyter_analysis` | Crea analisis completo (venv, launcher, MCP, reglas) |
|
|
| `export_analysis_pdfs` | Exporta notebooks de un analisis a PDF |
|
|
| `write_jupyter_launcher` | Genera script run-jupyter-lab.sh |
|
|
| `write_jupyter_registry_kernel` | Genera kernel startup con helpers del registry |
|
|
| `write_claude_jupyter_rules` | Genera .claude/CLAUDE.md con reglas para agentes |
|
|
| `write_mcp_jupyter_config` | Genera .mcp.json con config de jupyter-mcp-server |
|
|
|
|
---
|
|
|
|
## Buscar mas funciones
|
|
|
|
```bash
|
|
./fn search "jupyter"
|
|
./fn search "notebook"
|
|
sqlite3 registry.db "SELECT id, description FROM functions WHERE domain = 'notebook' ORDER BY name;"
|
|
```
|
|
|
|
$ARGUMENTS
|