Files
web_scraping/hoppscotch/README.md
T
egutierrez 65ca2b3d43 chore: auto-commit (4 archivos)
- .gitignore
- CAPABILITIES_TODO.md
- CHROMIUM_SYSTEM.md
- hoppscotch/

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-11 00:16:47 +02:00

146 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`, y `run_hoppscotch_collection` las 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_collection` te da un `.json` importable 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:
```bash
systemd-run --user --unit=hoppscotch-gui --setenv=DISPLAY=:0 /usr/bin/hoppscotch-desktop
```
### Importar una colección en la GUI
1. Panel **Collections** (izquierda) → menú **Import / Export**.
2. **Import****Hoppscotch****Import from File**.
3. Selecciona `collections/registry_api.json`.
4. (Opcional) Importa también el environment: panel **Environments** → Import →
`environments/registry_api.example.json` y rellena los valores reales (no se versionan).
5. 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:
```python
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):
```python
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):
```bash
# 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_collection` traduce automáticamente. Si compones a mano con
`http_replay_sequence`, traduce tú (`<<x>>``{{x}}`).
- **Endpoints con efecto** (POST/DELETE destructivos): filtra con `only` para 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 marca `body_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 CLI `hopp` v0.31.2 quiere un **objeto plano**
`{name,variables:[{key,value}]}` SIN `v` ni `secret` (`registry_api.cli.json`). Pasar el array a
`hopp test -e` da `MALFORMED_ENV_FILE`. `run_hoppscotch_collection` (registry) usa el array.