Development-time debugging and introspection toolbar for aiogram 3 bots
Project description
aiogram-devtools
A live debugging toolbar for aiogram 3 bots. Attach it in one line, open a local web panel, and watch everything happening inside your bot in real time — updates, routing, filters, middleware timings, FSM state, dependency injection, SQL queries, outbound HTTP calls and errors.
Why
Debugging an aiogram bot usually means scattering print() and logging
calls and guessing why an update didn't reach a handler. aiogram-devtools makes
the bot's internals visible: which filters ran, which handler matched, how
long each middleware took, what changed in the FSM, what SQL and HTTP fired —
all correlated per update, streamed live to a browser.
It is observe-only. It hooks into aiogram's public extension points and a small instrumentation layer, and never changes how your bot behaves. Turn it off with a single flag and it adds zero overhead.
Features
- One-line setup —
setup_devtools(dp, bot). - Live web panel at
http://127.0.0.1:8001with a tab per concern. - Per-update correlation — every record carries a
trace_id, so you can follow one update through its whole lifecycle. - Interactive diagrams — collapsible router tree, routing path, and an FSM state-transition timeline.
- Auto-detected integrations — SQLAlchemy and the common HTTP clients (httpx, aiohttp, requests, urllib). Missing libraries are skipped silently.
- Telegram traffic filtered out — your bot's own Bot API calls never clutter the HTTP tab.
- Secret redaction — the bot token and any keys you list are stripped before data leaves the process.
- Reversible — stopping devtools restores your dispatcher exactly as it was.
- Master switch —
enabled=Falsemakes it a complete no-op for production.
Install
pip install aiogram-devtools
# with optional integrations
pip install "aiogram-devtools[sqlalchemy,httpx]"
The browser panel loads Vue 3 and Tailwind from a CDN, so rendering the UI needs internet access.
Quick start
from aiogram import Bot, Dispatcher
from aiogram_devtools import setup_devtools
dp = Dispatcher()
bot = Bot(token="YOUR_TOKEN")
# Attach the toolbar.
setup_devtools(dp, bot)
# ... register your routers and handlers as usual ...
dp.run_polling(bot)
Run the bot and open http://127.0.0.1:8001.
To monitor SQL, register your engine:
dt = setup_devtools(dp, bot)
dt.add_sqlalchemy_engine(engine) # sync Engine or AsyncEngine
A full demo bot exercising every feature lives in
examples/demo_bot.py.
What the panel shows
| Tab | What it tells you |
|---|---|
| Updates | Every incoming update: summary, outcome (handled / unhandled / error) and total duration. Click to see the raw JSON and a keyboard preview. |
| Router Tree | The static structure of your routers and handlers — the "map" of your bot. |
| Routing | For each update, which handlers were tried and which one matched, shown as a path. |
| Filters | Each individual filter check (match / skip) — explains why a handler did or didn't fire. |
| Middleware | Per-middleware timing and the workflow-data keys each one added. |
| FSM | State-transition timeline per user, plus git-style diffs of state data. |
| DI | Which dependencies were injected into each handler and which middleware provided them. |
| SQL | Each SQLAlchemy statement with parameters, duration and row count. |
| HTTP | Outbound requests (method, URL, status, duration, client), Telegram calls excluded. |
| Errors | Handler exceptions with redacted message and traceback. |
| Heatmap / Profiler | Handler call counts and p95 durations — find hot and slow spots. |
How it works
Telegram update → Dispatcher → routers → middleware → handler
│
probes observe (never modify)
│
records (one trace_id per update)
│
EventBus ──┬── Store (bounded history + aggregates)
└── WebSocketHub → browser panel
- Probes are small, single-purpose instrumentation units installed in a fixed order (capture → middleware → filters → FSM → DI). Each wraps a public aiogram extension point and knows exactly how to undo itself.
- Collectors handle optional integrations: SQLAlchemy engine listeners and the HTTP client adapters. The HTTP collector auto-detects available clients, filters Telegram traffic, and de-duplicates layered clients so one request produces exactly one record.
- A
contextvars-based trace ties every record produced while handling a single update to the sametrace_id, with no plumbing through call signatures. - The EventBus fans records out synchronously to the bounded Store and the WebSocketHub. A failing consumer is logged and never breaks the bot.
- The web server is built on aiohttp (already a dependency of aiogram), so the panel adds no heavy runtime dependency.
Because instrumentation is applied by walking the dispatcher's router tree at
startup, your handlers are never rewritten, and stop() restores every wrapped
internal to its original state.
Configuration
Pass options as keyword arguments to setup_devtools(...):
setup_devtools(
dp, bot,
host="127.0.0.1",
port=8001,
history_size=1000, # records kept per type
capture_update_json=True, # include raw update JSON
redact_bot_token=True,
secret_keys=["password", "api_key"],
enable_sqlalchemy=True,
enable_http=True,
telegram_api_hosts=["api.telegram.org"],
enabled=True, # set False in production
)
| Option | Default | Description |
|---|---|---|
host / port |
127.0.0.1 / 8001 |
Panel bind address. Non-loopback hosts log a warning. |
history_size |
1000 |
Records retained per type before the oldest is evicted. |
capture_update_json |
True |
Store the full (redacted) update JSON. |
redact_bot_token |
True |
Replace the bot token with [REDACTED] everywhere. |
secret_keys |
[] |
Extra keys whose values are redacted. |
enable_sqlalchemy |
True |
Enable SQL monitoring (needs registered engines). |
enable_http |
True |
Auto-instrument available HTTP clients. |
telegram_api_hosts |
["api.telegram.org"] |
Hosts excluded from the HTTP tab. |
enabled |
True |
Master switch. False = complete no-op. |
Security
This is a development tool, not a production service. The panel has no
authentication and binds to loopback by default. Don't expose it to the network
or run it in production — use enabled=False there. The bot token and any
configured secret_keys are redacted before leaving the process, but treat the
panel as trusted-local only.
Requirements
- Python 3.11+
- aiogram 3.x, aiohttp 3.9+
- Optional: SQLAlchemy 2.x, httpx / requests (aiohttp and urllib are detected too)
Development
git clone https://github.com/jzombie971/aiogram-devtools
cd aiogram-devtools
pip install -e ".[dev,sqlalchemy,httpx]"
pytest
License
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 aiogram_devtools-0.1.1.tar.gz.
File metadata
- Download URL: aiogram_devtools-0.1.1.tar.gz
- Upload date:
- Size: 59.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f33431ec8e0beeef855776a8603e4db7e3b3fcd263939a7f3a26349824399ee8
|
|
| MD5 |
657e802ae01459c40b71b335e93dda20
|
|
| BLAKE2b-256 |
11c3485b65f0173f42e7bd90ea4a0a418e5f9ad078ad8d6b1cf069b7d32229ae
|
File details
Details for the file aiogram_devtools-0.1.1-py3-none-any.whl.
File metadata
- Download URL: aiogram_devtools-0.1.1-py3-none-any.whl
- Upload date:
- Size: 44.6 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 |
2b1c3027ab50425b3320a6a6b43703de9449f7412177cb5927326d3b680f0a68
|
|
| MD5 |
0c757e4a63c518390c9deb51fe0c55b6
|
|
| BLAKE2b-256 |
5acd68b7028f2c25e082b0cc1e680af5f6582c87832e8c6d5f3f3276afaba10d
|