django-aiogram
Run aiogram next to Django: write handlers as ordinary Django app code, and send Telegram messages from anywhere in the project.
One container runs the bot. Every other process — web, Celery, a management
command — hands the call to a broker and returns, so a request never waits on
Telegram. Four transports can carry it, and BROKER says which:
┌─ Redis list ────┐
web, celery ──bot.send()──▶ ├─ Redis Streams ─┤ ──▶ start_tgbot ──▶ Telegram
├─ RabbitMQ ──────┤
└─ Kafka ─────────┘
| transport | BROKER |
extra | its own required settings |
|---|---|---|---|
| Redis list (default) | django_aiogram.broker.redis_list.RedisListBroker |
[redis] |
— |
| Redis Streams | django_aiogram.broker.redis_streams.RedisStreamsBroker |
[redis] |
REDIS_STREAM_KEY |
| RabbitMQ | django_aiogram.broker.rabbitmq.RabbitMQBroker |
[rabbitmq] |
RABBITMQ_URL, RABBITMQ_QUEUE |
| Kafka | django_aiogram.broker.kafka.KafkaBroker |
[kafka] |
KAFKA_BOOTSTRAP, KAFKA_TOPIC |
Your code does not change with the row: the same bot.send(), handlers, event log and
manage.py start_tgbot. What differs is what becomes of a message whose worker was
killed mid-send, and what recovery is — a command, a clock, or the broker's own doing.
Delivery compares them;
each transport has a page of its own below.
Install
pip install 'django-aiogram[redis]' # Redis list, the default, or Redis Streams
pip install 'django-aiogram[rabbitmq,redis]' # RabbitMQ
pip install 'django-aiogram[kafka,redis]' # Kafka
One extra per transport, so a deployment downloads only the queue driver it uses.
redis is in the other two lines for the FSM store, not the queue: FSM_STORAGE
defaults to aiogram's Redis store, so a bot keeping chat state needs that driver whichever
transport carries its messages, and FSM_STORAGE: 'memory' is what drops it.
Nothing is inferred from what happens to be installed: BROKER names the transport, and a
base pip install django-aiogram imports and runs manage.py but carries no message.
manage.py check names every extra that is missing, with the pip install line;
Installation has the
exceptions.
# settings.py
import os
INSTALLED_APPS = [..., 'django_aiogram']
TELEGRAM_BOT = {
'TOKEN': os.environ.get('TELEGRAM_BOT_TOKEN', ''),
# unset, BROKER resolves to RedisListBroker; the table above has the other three,
# and each transport reads its own settings on top of these two
'REDIS_URL': os.environ.get('REDIS_URL', ''),
}
Both may be empty: nothing connects or validates credentials at import time, so tests and migrations run without them. Requires Python 3.10–3.14, Django 5.2+ and aiogram 3.30+; each transport then pins its own driver and asks for its own server — Installation has both, per row.
Use it
# myapp/tg_router.py — imported automatically from every installed app
from aiogram import F, types
from django_aiogram import bot
@bot.message(F.text == '/start')
async def start(message: types.Message) -> None:
await message.answer('hi')
# anywhere else in the project
from django_aiogram import bot
bot.send(chat_id=CHAT_ID, text='Order approved')
python manage.py start_tgbot
A router module, a call, and one process running the bot. That process gets Django's
between-requests connection handling without having any requests — every update is bracketed
with close_old_connections(), so a database that restarts under a long-running bot does not
leave every handler raising InterfaceError until somebody notices. Nothing to configure;
Deployment says what the
healthcheck can and cannot see about it.
Everything else — rate limits, per-process opt-out, healthchecks — is configuration, documented rather than required. Webhook mode is the one alternative that also asks for a URL route: Webhook has the four steps.
Documentation
The documentation site is the
documentation. Pages live in docs/wiki/, so they are reviewed in
the same pull request as the code they describe and published from master.
| Installation | install, configure, run |
| Settings | every setting, with defaults and check ids |
| Handlers | routers, filters, FSM, the async ORM |
| Sending messages | routes, keyboards, files, errors |
| Testing | your suite without a broker, asserting what was queued |
| API | the instance, its internals, and what stays public |
| Delivery | how queued messages reach Telegram |
| Redis list | the default transport: what it guarantees, and why the worker's name matters |
| Redis Streams | the same server, a consumer group, and no worker identity to keep |
| RabbitMQ | a broker that tracks its own consumers, and one thread per connection |
| Kafka | offsets settle a prefix, ordering is per partition, a refusal rewinds |
| Webhook | receiving updates over HTTP instead of polling |
| Rate limits | staying inside Telegram's published limits |
| Deployment | compose recipes, healthchecks, per-process opt-out |
| Logging | the logger and its structured fields |
| Event log | recording what the bot did to a table, and a signal to count it without one |
| Serialization | what can be queued |
| Troubleshooting | symptoms and their usual causes |
| Upgrading | what each major release changed, and what you must do |
| AI assistants | the brief to hand a coding agent |
Upgrading from 3.x: the distribution is django-aiogram and the import path is
django_aiogram, the driver is an extra you now name, and the event log has a table of its
own. The upgrading page walks it in order, migrate included.
Contributing
CONTRIBUTING.md for the workflow, AGENTS.md for the same ground in the form coding agents read. Changes are in CHANGELOG.md; security reports go through SECURITY.md.
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 django_aiogram-4.0.0.post1.tar.gz.
File metadata
- Download URL: django_aiogram-4.0.0.post1.tar.gz
- Upload date:
- Size: 937.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9137eb1bab1abf2da3da42dfb4f76c4295f06d6f1e497e3685f2fb8ece74b2c
|
|
| MD5 |
678c8e0299d0a90b294c57e4fe1e635d
|
|
| BLAKE2b-256 |
53d84d5b49eb9761188e7e500729d8da608c755ee4d1885f9fb7a4c9a7b6ca41
|
Provenance
The following attestation bundles were made for django_aiogram-4.0.0.post1.tar.gz:
Publisher:
publish.yml on CorneiZeR/django-aiogram
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_aiogram-4.0.0.post1.tar.gz -
Subject digest:
d9137eb1bab1abf2da3da42dfb4f76c4295f06d6f1e497e3685f2fb8ece74b2c - Sigstore transparency entry: 2677545654
- Sigstore integration time:
-
Permalink:
CorneiZeR/django-aiogram@8a544e13769ec3ce059a4abc604005d4ece5b709 -
Branch / Tag:
refs/tags/v4.0.0.post1 - Owner: https://github.com/CorneiZeR
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8a544e13769ec3ce059a4abc604005d4ece5b709 -
Trigger Event:
release
-
Statement type:
File details
Details for the file django_aiogram-4.0.0.post1-py3-none-any.whl.
File metadata
- Download URL: django_aiogram-4.0.0.post1-py3-none-any.whl
- Upload date:
- Size: 270.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12b21a85a5120fd45280539c36f0e5e05b0cc6dc1e63fce0e429bc76c35f7d3b
|
|
| MD5 |
1d99b9c2c03c686552e2fe1da006e721
|
|
| BLAKE2b-256 |
4c94b15e3d358ad36981a3070adf130d4b957a2f18322a8f975470b7223795ff
|
Provenance
The following attestation bundles were made for django_aiogram-4.0.0.post1-py3-none-any.whl:
Publisher:
publish.yml on CorneiZeR/django-aiogram
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_aiogram-4.0.0.post1-py3-none-any.whl -
Subject digest:
12b21a85a5120fd45280539c36f0e5e05b0cc6dc1e63fce0e429bc76c35f7d3b - Sigstore transparency entry: 2677545759
- Sigstore integration time:
-
Permalink:
CorneiZeR/django-aiogram@8a544e13769ec3ce059a4abc604005d4ece5b709 -
Branch / Tag:
refs/tags/v4.0.0.post1 - Owner: https://github.com/CorneiZeR
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8a544e13769ec3ce059a4abc604005d4ece5b709 -
Trigger Event:
release
-
Statement type: