Skip to main content

matador 🗡️

A live, server-rendered dashboard for toro queues - watch queues, inspect jobs, and act on them (retry, remove, promote, pause…) from the browser.

Python
PyPI Downloads License
Coverage Quality Gate Status
Reliability Rating Maintainability Rating Security Rating

matador dashboard

pip install matador-dashboard   # the import name is `matador`

Installed as matador-dashboard on PyPI (the name matador was taken), but you import matador.

What it is

FastAPI + Jinja on the server, HTMX + Tailwind on the page - no SPA, no build step to run. Every queue / tab / page is a real URL, so reload, back/forward and deep-links all work. It reads straight from Redis through toro's async API.

Features

  • Queues sidebar with per-state counts, a per-queue activity sparkline (last hour, all queues on one shared scale, failures in red), and state tabs (active / waiting / held / delayed / completed / failed / cancelled) that swap the job list over HTMX.
  • Health chips per queue: latency (age of the next job in line, warns past 30s), completed/failed counts with failure share, and average duration over the last hour - server-rendered SVG, no chart library.
  • Flows - toro's parent/child job trees, shown root-first: a flow is its root job moving through the normal tabs (parked roots fold into active), with children hidden from the lists and a recursive tree on the job detail with per-node status pills and fan-in progress that counts completions only; destructive actions warn that removing a parent takes its whole subtree. The active tab also carries a flow-throughput strip - whole flows completed/ failed over the last hour, with end-to-end flow-duration percentiles.
  • Job detail lazy-loaded on expand: data, options, return value, timings, logs, and stack traces - syntax-highlighted server-side (Pygments, no client JS).
  • Search within a state by job id or a name/data substring.
  • Live updates over SSE - counts refresh as jobs complete, no reload.
  • Actions: pause/resume a queue, retry/remove/promote a job, retry-all, clean a state, and schedulers (run-now / remove) - each behind a styled confirm dialog (not window.confirm).
  • Numbered pagination, a Redis health bar (memory, clients, eviction policy), and a persistent dark / light theme.
  • /metrics for a Prometheus-compatible scraper: every watched queue in one OpenMetrics exposition, rendered by toro rather than by the dashboard. The gauges count every job in the state it is in, which is not what the tab badges count.
  • Read-only mode - pass can_mutate(request) and every action refuses, with the controls left out of the page rather than drawn and refused.

Run it

uv run python scripts/seed.py             # optional: populate demo data
uv run uvicorn scripts.run:app --reload   # http://localhost:8000

scripts/run.py watches a few demo queues; edit the list there, or wire it up yourself.

Integrate into an existing app

matador is an ASGI app - mount it into your FastAPI/Starlette service at any path. URLs are root_path-aware (Starlette url_for), so a sub-path mount just works.

from fastapi import Depends
from matador import create_app

app.mount(
    "/toro",
    create_app(
        ["emails", "billing"],
        connection=redis,                       # share your existing redis pool
        dependencies=[Depends(require_admin)],  # protect it with your auth
    ),
)
  • Mount anywhere - links, static assets and the SSE stream all carry the mount prefix automatically; works behind a path-stripping reverse proxy too.
  • connection= - pass your redis.asyncio.Redis so matador shares your pool (it never closes a connection it didn't open). Omit it to open its own from url=. This is also the right way to embed: a mounted sub-app's lifespan doesn't run, so the host should own the connection.
  • dependencies= - applied to every route, so your app's auth gates the dashboard. (The /static mount isn't covered - wrap the whole mount if the assets themselves need auth.)
  • can_mutate= - a predicate handed the raw request (matador has no identity of its own), deciding whether this caller may change anything. Read-only callers get a dashboard with no controls, not controls that refuse.
  • Other stacks (Django, Flask, non-Python): run matador standalone and reverse-proxy.

Security

matador ships no auth of its own - it inherits the host app's via dependencies=, or sits behind an authenticating reverse proxy. An app built without dependencies logs a warning at startup, because every route (including delete/retry/pause) is open to whoever can reach it.

  • CSRF: the same-origin guard turns on automatically when dependencies are configured (auth usually means cookies, and cookies are what make CSRF real). Pass require_same_origin= explicitly to override.
  • Stack traces are shown in job detail by default and can leak source paths or secrets from exception messages - show_stacktraces=False hides them when the audience shouldn't see internals.
  • The dashboard can do whatever its Redis connection can do; scope that Redis user/network accordingly. See toro's docs/security.md for the queue-side model.

Standalone is just the no-extras case:

app = create_app(["emails", "billing"], url="redis://localhost:6379")

It serves HTML (an HTMX UI), not a JSON API - point a browser at it.

Develop

Managed with uv; the Astral toolchain throughout.

uv sync                          # venv + deps + dev group
uv run ruff check . && uv run ruff format .   # lint (strict) + format
uv run ty check                  # type check
uv run pytest                    # unit + integration (needs Redis on :6379)
uv run pytest -m e2e             # Playwright browser tests (run separately)

# rebuild the stylesheet while editing templates/styles
./tailwindcss -i styles/input.css -o matador/static/app.css --watch

License

MIT

Release files for matador-dashboard 0.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for matador-dashboard 0.10.0
File Size Uploaded
matador_dashboard-0.10.0.tar.gz 649.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for matador-dashboard 0.10.0
File Interpreter ABI Platform
matador_dashboard-0.10.0-py3-none-any.whl Python 3 none any Details

Total release size: 806.5 kB

Release files / matador_dashboard-0.10.0.tar.gz

Download URL matador_dashboard-0.10.0.tar.gz
Size 649.7 kB
Tags Source
SHA-256 checksum
How to use checksums
8a13754d7d2fe3bf663ee28ae35482ca70721dc1bc601c43b2aaf19ccf84bcc9
BLAKE2b-256 checksum
How to use checksums
b6bfe4fd3b1538600249b099c288a05730927bcc26ec0f7acb37e93458c61044
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / matador_dashboard-0.10.0-py3-none-any.whl

Download URL matador_dashboard-0.10.0-py3-none-any.whl
Size 156.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
06ba1e49eac63031c2e369ac46b3183a9a4ac18151558a9bbfba5403c7f73302
BLAKE2b-256 checksum
How to use checksums
3f26d45aaec94969af419bfb45454fb7693acc45e6ae50ec0e1012545a3bf90a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.10.1

2 release files

This release

0.10.0 This release

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page