CreaRack-SL

bib_openapi.py — Script de reindexado OpenAPI para el grafo de conocimiento Biblioteca

scripts/bib_openapi.py — Reindexado OpenAPI → Grafo Biblioteca

Propósito

Script Python que extrae el spec OpenAPI de CreaRack Pro y lo ingesta en el grafo de conocimiento de la Biblioteca vía el handler MCP bib_index_openapi. Es invocado por el cron bib-reindex watchdog daily y por el script cron-bib-reindex.sh.

Se ejecuta en STAGE/producción bajo el usuario del cron. No requiere entorno Django — solo Python stdlib + acceso HTTP al endpoint /api/openapi-export y al endpoint MCP.

Responsabilidades

  1. Extracción del spec OpenAPI desde GET /api/openapi-export con Bearer token.
  2. Chunking del spec en lotes pequeños para respetar el límite de subrequests de CF Workers.
  3. Ingesta de cada chunk via POST /api/mcp → tool bib_index_openapi.
  4. Validación de respuestas (Regla 15): HTTP 200 no implica éxito; inspeccionar inner payload.
  5. Reporte de contadores agregados: paths, schemas, chunks, created, updated, edges.

Arquitectura de chunking

Implementada en s50-fix-3 (06-05-2026) para resolver el límite de ~1000 subrequests CF Workers.

Spec completo (414 paths + 199 schemas)
         │
         ▼
┌──────────────────────────────────────────┐
│  push_to_mcp(openapi_json, mcp_url, tok) │
│                                          │
│  1. Schemas en chunks de SCHEMAS_PER_CHUNK=50  │
│     → chunk = {paths:{}, components:{schemas: batch}}  │
│                                          │
│  2. Paths en chunks de PATHS_PER_CHUNK=50      │
│     → chunk = {paths: batch, components:{schemas:{}}}  │
│                                          │
│  Por cada chunk → _post_chunk() → inner  │
│  Agregar created/updated/edges           │
└──────────────────────────────────────────┘
         │
         ▼
  Counters totales impresos a stdout

Constantes clave

ConstanteValorMotivo
PATHS_PER_CHUNK50~250 subrequests D1 por chunk; <<1000 límite CF Workers
SCHEMAS_PER_CHUNK50~100 subrequests D1 por chunk
Timeout HTTP180 sPermite procesamiento secuencial de chunks

Flujo de ejecución

main()
  ├─ extract_openapi_via_http(url, token)  → openapi_json
  └─ push_to_mcp(openapi_json, mcp_url, token)
       ├─ _post_chunk(schemas_chunk_1, …)  → inner_1
       ├─ _post_chunk(schemas_chunk_2, …)  → inner_2
       ├─ …
       ├─ _post_chunk(paths_chunk_1, …)    → inner_N
       └─ _post_chunk(paths_chunk_M, …)    → inner_total

Detección de errores (Regla 15)

El handler MCP puede fallar silenciosamente devolviendo HTTP 200 con un payload de error. El script inspecciona dos formatos:

err_singular = inner.get("error")        # wrapper MCP externo (CF Workers abort)
err_plural   = inner.get("errors") or [] # handlers internos Django/D1

if err_singular or err_plural:
    print(f"MCP handler returned error: {err_singular or err_plural}", file=sys.stderr)
    sys.exit(2)  # rc=2 → cron detecta fallo (Regla 15)
FormatoOrigenEjemplo
{"error": "Unhandled: Too many API requests…"}Wrapper CF WorkersExceso subrequests
{"errors": ["Node not found", …]}Handlers internos D1Error de lógica

Códigos de salida

rcSignificado
0Éxito completo
1Error de conectividad / HTTP (no recoverable)
2Handler MCP devolvió error en payload (Regla 15)

Output esperado (éxito)

OK bib_index_openapi: paths=414 schemas=199 chunks=14 created=… updated=… edges=…

⚠️ Si ves endpoints=0, schemas=0 con rc=0, es un fallo — ver [[incident—20260506—bib-reindex-subrequest-limit]].

Variables de entorno requeridas

VariableDescripción
OPENAPI_URLURL base del endpoint /api/openapi-export
API_TOKENBearer token con permisos de lectura OpenAPI
MCP_URLURL del endpoint MCP CF Workers
MCP_TOKENBearer token para el MCP

Historial de cambios relevantes

FechaCommitCambio
05-05-2026s50Creación inicial del script (bib_openapi.py) como parte de la arquitectura bib-reindex
06-05-2026643c96f1s50-fix-3: Chunking + detección dual error/errors + timeout 180s

Véase también

  • [[incident—20260506—bib-reindex-subrequest-limit]]
  • [[runbook—biblioteca—bib-reindex]]
  • [[feature—biblioteca—bib-reindex-s50]]
  • [[concept—biblioteca—subrequest-limit-cf-workers]]