Metadata-Version: 2.4
Name: aiogram-devtools
Version: 0.1.1
Summary: Development-time debugging and introspection toolbar for aiogram 3 bots
Author: aiogram-devtools contributors
License: MIT
Project-URL: Homepage, https://github.com/jzombie971/aiogram-devtools
Project-URL: Repository, https://github.com/jzombie971/aiogram-devtools
Project-URL: Issues, https://github.com/jzombie971/aiogram-devtools/issues
Keywords: aiogram,telegram,bot,debug,devtools,toolbar,introspection
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Debuggers
Classifier: Topic :: Communications :: Chat
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiogram>=3.0
Requires-Dist: aiohttp>=3.9
Provides-Extra: sqlalchemy
Requires-Dist: sqlalchemy>=2.0; extra == "sqlalchemy"
Provides-Extra: httpx
Requires-Dist: httpx>=0.27; extra == "httpx"
Provides-Extra: dev
Requires-Dist: pytest>=8.2; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: hypothesis>=6.100; extra == "dev"
Dynamic: license-file

# aiogram-devtools

**A live debugging toolbar for [aiogram 3](https://docs.aiogram.dev) 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.

[Русская версия](README.ru.md)

![Python](https://img.shields.io/badge/python-3.11%2B-blue)
![aiogram](https://img.shields.io/badge/aiogram-3.x-blue)
![PyPI](https://img.shields.io/pypi/v/aiogram-devtools)
![License](https://img.shields.io/badge/license-MIT-green)

---

## 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:8001` with 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=False` makes it a complete no-op for production.

## Install

```bash
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

```python
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:

```python
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`](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 same `trace_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(...)`:

```python
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

```bash
git clone https://github.com/jzombie971/aiogram-devtools
cd aiogram-devtools
pip install -e ".[dev,sqlalchemy,httpx]"
pytest
```

## License

[MIT](LICENSE)
