WUP Browser Dashboard — FastAPI backend for WUP regression watcher
Project description
wupbro
FastAPI backend + minimal HTML dashboard for the WUP regression watcher.
Architecture
┌──────────────────────┐ POST /events ┌──────────────────────┐
│ WUP agent (shell) │ ───────────────▶ │ wupbro (FastAPI) │
│ - file watcher │ │ - /events (sink) │
│ - testql runner │ │ - /drivers/* │
│ - visual diff │ │ - /dashboard (UI) │
└──────────────────────┘ └──────────────────────┘
│
▼
┌─────────────────┐
│ Browser UI │
│ (auto-refresh) │
└─────────────────┘
Endpoints
| Path | Method | Purpose |
|---|---|---|
/events |
POST | Receive event from a WUP agent |
/events |
GET | List recent events (filter by type/service) |
/events/stats |
GET | Aggregate counts by type |
/events |
DELETE | Clear store (admin/debug) |
/drivers/dom-diff/capture |
POST | One-shot Playwright DOM snapshot + diff |
/drivers/browserless/screenshot |
POST | Proxy to a browserless/chrome container |
/drivers/anomaly/report |
POST | Record numeric anomaly as ANOMALY event |
/drivers/health |
GET | Driver capability discovery |
/, /dashboard |
GET | HTML dashboard |
/healthz |
GET | Liveness probe |
/openapi.json, /docs |
GET | OpenAPI spec + Swagger UI |
Event types
REGRESSION, PASS, ANOMALY, VISUAL_DIFF, HEALTH_TRANSITION.
Schema (Pydantic):
{
"type": "REGRESSION",
"service": "users-web",
"file": "app/users/routes.py",
"endpoint": "/api/users",
"status": "fail",
"stage": "quick",
"reason": "TestQL exit code 1",
"timestamp": 1730000000
}
Extra fields are preserved via model_config = {"extra": "allow"}.
Run
# Install
pip install -e wupbro/
# Dev server (auto-reload)
wupbro --reload --port 8000
# Or directly
uvicorn wupbro.main:app --host 0.0.0.0 --port 8000 --reload
Dashboard: http://localhost:8000/
OpenAPI docs: http://localhost:8000/docs
Configure WUP agent to send events
In your wup.yaml:
web:
enabled: true
endpoint: "http://localhost:8000"
endpoint_env: "WUPBRO_ENDPOINT" # fallback if endpoint is empty
timeout_s: 2.0 # short — must not block watcher
api_key: "" # optional bearer token
Or via environment variable:
export WUPBRO_ENDPOINT=http://localhost:8000
wup watch . --mode testql
The agent will POST events fire-and-forget on:
- service health transitions (up ↔ down)
- regressions (when TestQL fails)
- visual DOM diffs (when significant changes detected)
Browserless integration
docker run -d --name browserless -p 3000:3000 browserless/chrome
export BROWSERLESS_URL=http://localhost:3000
wupbro
Then:
curl -X POST http://localhost:8000/drivers/browserless/screenshot \
-H "Content-Type: application/json" \
-d '{"url": "http://example.com", "full_page": true}'
Storage
Events are kept in an in-memory ring buffer (capacity 1000) and persisted to .wupbro/events.jsonl for restart durability.
Tests
PYTHONPATH=wupbro python3 -m pytest wupbro/tests/ -v
17 tests covering events router, drivers (anomaly, browserless, dom-diff, health), dashboard HTML, OpenAPI schema.
License
Licensed under Apache-2.0.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wupbro-0.1.3.tar.gz.
File metadata
- Download URL: wupbro-0.1.3.tar.gz
- Upload date:
- Size: 21.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18b3d68c474b08e727d53602aceec97b9fc5a44d6e9cb3defd6b5746850dd243
|
|
| MD5 |
dda3b6d246937e739b770668418f95ee
|
|
| BLAKE2b-256 |
8595e0cbdb3c15d0060913517933b1eec002e44ad7c4b15d0ed0496c98c55198
|
File details
Details for the file wupbro-0.1.3-py3-none-any.whl.
File metadata
- Download URL: wupbro-0.1.3-py3-none-any.whl
- Upload date:
- Size: 21.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95d77b4e2fbd13f9a13c3df8b927372fab472dc5eb5bc5ec77877bdf016e2a04
|
|
| MD5 |
1504422a36888b6699521c6da8c545f9
|
|
| BLAKE2b-256 |
45dbab33c4831cbf8f1eaccc934ec9cfa156d8057a032facc8030274f73c6c45
|