Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.8 KiB
Capability group: hoppscotch
Operar una instancia self-hosted de Hoppscotch (consola de APIs, alternativa open-source a Postman) desde el registry, vía su API GraphQL. El agente crea/edita requests, colecciones y environments por la API; el humano los ve en vivo en su GUI (subscriptions = hot-reload real). Las requests viven en la base de datos del self-host (Postgres), compartida entre el agente y la GUI.
Este es el flujo canónico. El antiguo modo "archivo .json local" (funciones
parse_* / run_* / add_hoppscotch_request) fue eliminado: escribía un .json en disco que
NO subía al workspace, así que el humano no lo veía en la GUI. No lo reintroduzcas.
Stack self-host
Vive en projects/web_scraping/hoppscotch/selfhost/ (docker compose: AIO + Postgres + mailpit).
| Servicio | URL | Para qué |
|---|---|---|
| App (cliente) | http://localhost:3009 |
la GUI donde el humano usa las colecciones (instalable como PWA) |
| Admin dashboard | http://localhost:3100 |
gestión (usuarios, config) |
| Backend GraphQL | http://localhost:3170/graphql |
la API que usan las funciones |
| Mailpit | http://localhost:8025 |
captura el magic link del login (SMTP de pruebas, sin correo real) |
Levantar: cd selfhost && docker compose up -d. Team de trabajo: "registry". Cuenta: admin@example.com.
Funciones
| ID | Firma corta | Qué hace |
|---|---|---|
hoppscotch_login_py_infra |
(email, *, backend_url, mailpit_url) -> {access_token,...} |
login por magic link headless (lee el link de mailpit) → JWT |
hoppscotch_create_request_py_infra |
(collection_id, method, url, *, title, headers, body, body_type, team_id, access_token) -> dict |
crea una request en una colección de la team |
hoppscotch_update_request_py_infra |
(request_id, method, url, *, title, headers, body, body_type, access_token) -> dict |
actualiza una request |
hoppscotch_delete_request_py_infra |
(request_id, *, access_token) -> dict |
borra una request |
hoppscotch_list_requests_py_infra |
(collection_id, *, access_token) -> {requests:[...]} |
lista las requests de una colección |
hoppscotch_set_environment_py_infra |
(team_id, name, variables, *, access_token) -> dict |
crea/actualiza (idempotente) el environment de la team; resuelve secretos pass: |
build_hoppscotch_collection_py_infra |
(calls, *, name, request_names) -> dict |
helper interno de create/update: serializa call specs al formato HoppRESTRequest. NO para escribir .json a mano |
pass_get_secret_py_infra |
(path, *, line) -> {value} |
lee un secreto de pass (lo consume set_environment para no hardcodear keys) |
access_token se pasa como cookie, no header Authorization. Caduca a 24h → re-login con hoppscotch_login.
Ejemplo canónico (end-to-end)
import sys, os
sys.path.insert(0, os.path.join(os.path.expanduser("~/fn_registry"), "python", "functions"))
from infra.hoppscotch_login import hoppscotch_login
from infra.hoppscotch_create_request import hoppscotch_create_request
from infra.hoppscotch_set_environment import hoppscotch_set_environment
TEAM = "cmq8kn0v500030xls1nvminjy" # team "registry"
COLL = "cmq8knppc00040xlskt4ist27" # colección registry_api (de hoppscotch_list/DB)
tok = hoppscotch_login("admin@example.com")["access_token"]
# 1. Variables del workspace (secreto resuelto desde pass, no hardcodeado)
hoppscotch_set_environment(TEAM, "registry", [
{"key": "baseURL", "value": "https://registry.organic-machine.com", "secret": False},
{"key": "api_key", "value": "pass:apis/registry", "secret": True}, # pass: -> pass_get_secret
], access_token=tok)
# 2. Crear una request → aparece EN VIVO en la GUI del humano (subscriptions)
hoppscotch_create_request(
COLL, "GET", "<<baseURL>>/api/status",
title="status", headers={"Accept": "application/json"},
team_id=TEAM, access_token=tok,
)
Fronteras (qué NO cubre)
- No es modo archivo: no escribe colecciones
.jsonlocales como fuente. Las requests viven en el Postgres del self-host. (Los.jsonencollections/son solo respaldo/semilla importable.) - No automatiza la GUI: opera por la API; la GUI la mira el humano.
- No gestiona usuarios/teams del dashboard: eso es el admin dashboard (
:3100). - No ejecuta los scripts pre/post-request JS de Hoppscotch.
Gotchas
access_tokencomo cookie (cookies={"access_token": tok}), noAuthorization. 24h de vida.createRequestInCollectionde esta instancia exigeteam_iden el input (no solo el collectionID).- Variables
<<var>>se resuelven con el environment de la team (subscriptions las propagan a la GUI). - Secretos: usa
value="pass:<ruta>"enset_environment→ se resuelve depass, nunca se hardcodea ni se logea en crudo. - El secreto viaja en claro al backend local por GraphQL — es local (
127.0.0.1), aceptable.