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>
This commit is contained in:
2026-06-11 00:16:47 +02:00
parent 0b3a1313c2
commit 65ca2b3d43
12 changed files with 745 additions and 1 deletions
+145
View File
@@ -0,0 +1,145 @@
# 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.