- .gitignore - CAPABILITIES_TODO.md - CHROMIUM_SYSTEM.md - hoppscotch/ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.2 KiB
Hoppscotch — consola de APIs + colecciones versionadas
GUI para explorar/probar APIs a mano (Hoppscotch Desktop) con las consultas guardadas como JSON versionado en este sub-repo, y un puente bidireccional con el motor de replay del registry para lanzar y automatizar esas mismas peticiones desde terminal o scripts.
Grupo de capacidad: hoppscotch. Página madre: docs/capabilities/hoppscotch.md.
El ciclo
GUI Hoppscotch ──export .json──▶ parse_hoppscotch_collection ──call specs──▶ run_hoppscotch_collection ──▶ http_replay_sequence
▲ (automatiza, headless)
└──── build_hoppscotch_collection ◀── call specs (de HAR destilado, o a mano) ────────────────────────────┘
- GUI → automatización: editas/creas requests en la app, exportas la colección a
collections/<algo>.json, yrun_hoppscotch_collectionlas ejecuta sin tocar la GUI. - Automatización → GUI: tienes call specs (p.ej. de un flujo grabado con HAR y destilado
con
har_extract_calls),build_hoppscotch_collectionte da un.jsonimportable en la app para inspeccionarlas visualmente.
Estructura
hoppscotch/
collections/ # Colecciones .json VERSIONADAS (sin secretos)
registry_api.json # ejemplo: 4 endpoints GET del registry_api
environments/ # Variables de entorno Hoppscotch
.gitignore # ignora *.json (secretos) salvo *.example.json
registry_api.example.json # plantilla VERSIONADA (valores placeholder)
registry_api.json # real, GITIGNORED (puede llevar tokens)
README.md
Regla de secretos: las colecciones se versionan; los environments reales no (llevan
tokens/basicAuth). Solo la plantilla *.example.json viaja en git. En las requests, los valores
sensibles van como variable de environment con la sintaxis Hoppscotch <<nombre>>, nunca
hardcodeados.
Lanzar la app Desktop
Binario instalado por el .deb: /usr/bin/hoppscotch-desktop (menú de aplicaciones: "Hoppscotch").
Lanzado desde una sesión gráfica normal o, de forma aislada:
systemd-run --user --unit=hoppscotch-gui --setenv=DISPLAY=:0 /usr/bin/hoppscotch-desktop
Importar una colección en la GUI
- Panel Collections (izquierda) → menú Import / Export.
- Import → Hoppscotch → Import from File.
- Selecciona
collections/registry_api.json. - (Opcional) Importa también el environment: panel Environments → Import →
environments/registry_api.example.jsony rellena los valores reales (no se versionan). - Selecciona el environment activo arriba a la derecha y pulsa Send en cualquier request.
Exportar / ver el JSON que genera la GUI
Collections → menú → Export → Hoppscotch → guarda en collections/. Así se ve el
esquema nativo de la versión instalada (la app migra al esquema más reciente al importar/exportar).
parse_hoppscotch_collection lee cualquier versión v1..v12 por campos estables.
Automatizar desde el registry
Lanzar toda una colección o un subconjunto, headless, con sustitución de variables:
import sys, os
sys.path.insert(0, os.path.join(os.path.expanduser("~/fn_registry"), "python", "functions"))
from infra.run_hoppscotch_collection import run_hoppscotch_collection
res = run_hoppscotch_collection(
"projects/web_scraping/hoppscotch/collections/registry_api.json",
environment_path="projects/web_scraping/hoppscotch/environments/registry_api.json",
params={"baseURL": "https://registry.organic-machine.com"}, # pisa el environment
only=["status", "locations"], # filtra por nombre de request; None = todas
)
print(res["status"])
for s in res["steps"]:
print(s["method"], s["url"], "->", s["status_code"], "ok" if s["ok"] else "FAIL")
run_hoppscotch_collection convierte la sintaxis Hoppscotch <<var>> a la del motor de replay
{{var}}, mergea environment + params (params del caller ganan), filtra por only, y reproduce
las peticiones sobre una sesión HTTP compartida (cookie jar entre pasos).
Añadir peticiones rápido
Sin editar el .json a mano, con add_hoppscotch_request (reusa el mapeo de build, no
destruye el archivo si el JSON es inválido):
from infra.add_hoppscotch_request import add_hoppscotch_request
r = add_hoppscotch_request(
"projects/web_scraping/hoppscotch/collections/registry_api.json",
"GET", "<<baseURL>>/api/search?q=metabase&kind=function",
name="search metabase", headers={"Accept": "application/json"})
print(r["status"], r["total_requests"]) # ok 8
Tras añadir, re-importa la colección en la app Desktop (no recarga el .json en caliente) o
córrela headless con run_hoppscotch_collection / hopp test.
Validar la colección
Dos motores independientes, ambos verde sobre registry_api.json (7 requests → 7×200):
# Motor nativo Hoppscotch (corre también preRequestScript/testScript JS):
hopp test collections/registry_api.json -e environments/registry_api.cli.json
# Motor del registry (integrado, telemetría, params/extract):
python3 -c 'from infra.run_hoppscotch_collection import run_hoppscotch_collection as r; \
print(r("collections/registry_api.json", environment_path="environments/registry_api.json")["status"])'
Funciones del registry
| ID | Qué hace |
|---|---|
build_hoppscotch_collection_py_infra |
call specs → dict de colección Hoppscotch (importable en la GUI) |
parse_hoppscotch_collection_py_infra |
dict de colección Hoppscotch (v1..v12) → call specs |
run_hoppscotch_collection_py_infra |
lee colección + environment .json y ejecuta vía http_replay_sequence |
add_hoppscotch_request_py_infra |
añade una petición a una colección .json existente (reusa build, no destructivo) |
http_replay_sequence_py_infra |
motor de replay HTTP (secuencia con sesión, {{param}}, extract) |
har_extract_calls_py_cybersecurity |
HAR destilado → call specs (origen del lado izquierdo del ciclo) |
Gotchas
- Sintaxis de variables: la GUI usa
<<var>>; el motor de replay usa{{var}}.run_hoppscotch_collectiontraduce automáticamente. Si compones a mano conhttp_replay_sequence, traduce tú (<<x>>→{{x}}). - Endpoints con efecto (POST/DELETE destructivos): filtra con
onlypara no ejecutar a ciegas toda la colección. El replay reproduce lo que haya; la responsabilidad de no disparar acciones irreversibles es del caller. - Esquema de versión:
build_*genera el formato canónico estable v1/v2 que la app migra al importar.parse_*lee cualquier versión por campos. No fijamos v12/v17 a mano para no romper con cambios de esquema upstream. - multipart/form-data:
parse_*lo marcabody_type="raw"y no reconstruye el cuerpo binario. - Formato dual de environment: la GUI Desktop importa el array
[{v,name,variables:[{key,value,secret}]}](registry_api.json/.example.json); el CLIhoppv0.31.2 quiere un objeto plano{name,variables:[{key,value}]}SINvnisecret(registry_api.cli.json). Pasar el array ahopp test -edaMALFORMED_ENV_FILE.run_hoppscotch_collection(registry) usa el array.