Aiogram

Overview

Aiogram is an asynchronous Python framework for creating Telegram bots (Python 3.10+ per the earlier note). It targets the Telegram Bot API.

It is built on asyncio and aiohttp.

Installation

Install via pip:

pip install aiogram  

Core Features

Asynchronous Architecture

  • Built entirely on asyncio (PEP 492)
  • Non-blocking I/O throughout the framework

Type Hints

  • Type hints (PEP 484); IDE and mypy benefits are as described in the earlier note, not re-verified

Telegram Bot API Support

  • aiogram 3.31.0 (released 2026-08-25) supports Telegram Bot API 10.3 per docs.aiogram.dev; MIT licence; ~5.9k GitHub stars (2026-10-05)
  • Automatic code generation for rapid updates to new API versions

Finite State Machine (FSM)

  • Built-in state management for conversation flows
  • Complex multi-step dialogue handling
  • State persistence options
  • Context management for user sessions

Middleware System

  • Flexible middleware for processing incoming updates
  • API call manipulation and interception
  • Request/response processing pipeline
  • Custom middleware creation

Advanced Routing

  • Powerful routers (Blueprints) for organizing handlers
  • Extensible filters for commands and message matching
  • Hierarchical route organization
  • Modular bot structure

Webhook Support

  • Provide replies through webhooks as alternative to polling
  • Suitable for serverless deployments
  • Webhook verification and validation
  • Long polling and webhook coexistence

Internationalization (I18n/L10n)

  • GNU Gettext integration
  • Fluent localization support
  • Multi-language bot support
  • Translation management

Basic Usage

Minimal Bot Example

import asyncio  
import logging  
import sys  
from os import getenv  
from aiogram import Bot, Dispatcher, html  
from aiogram.client.default import DefaultBotProperties  
from aiogram.enums import ParseMode  
from aiogram.filters import CommandStart  
from aiogram.types import Message  
  
TOKEN = getenv("BOT_TOKEN")  
dp = Dispatcher()  
  
@dp.message(CommandStart())  
async def command_start_handler(message: Message) -> None:  
    await message.answer(f"Hello, {html.bold(message.from_user.full_name)}!")  
  
@dp.message()  
async def echo_handler(message: Message) -> None:  
    try:  
        await message.send_copy(chat_id=message.chat.id)  
    except TypeError:  
        await message.answer("Nice try!")  
  
async def main() -> None:  
    bot = Bot(  
        token=TOKEN,   
        default=DefaultBotProperties(parse_mode=ParseMode.HTML)  
    )  
    await dp.start_polling(bot)  
  
if __name__ == "__main__":  
    logging.basicConfig(level=logging.INFO, stream=sys.stdout)  
    asyncio.run(main())  

Command Handler with FSM

from aiogram.filters import Command  
from aiogram.fsm.context import FSMContext  
from aiogram.fsm.state import State, StatesGroup  
  
class UserRegistration(StatesGroup):  
    waiting_for_name = State()  
    waiting_for_email = State()  
  
@dp.message(Command("register"))  
async def cmd_register(message: Message, state: FSMContext) -> None:  
    await state.set_state(UserRegistration.waiting_for_name)  
    await message.answer("What's your name?")  
  
@dp.message(UserRegistration.waiting_for_name)  
async def process_name(message: Message, state: FSMContext) -> None:  
    await state.update_data(name=message.text)  
    await state.set_state(UserRegistration.waiting_for_email)  
    await message.answer("What's your email?")  
  
@dp.message(UserRegistration.waiting_for_email)  
async def process_email(message: Message, state: FSMContext) -> None:  
    await state.update_data(email=message.text)  
    data = await state.get_data()  
    await message.answer(f"Registered: {data['name']} ({data['email']})")  
    await state.clear()  

Custom Middleware

from aiogram import BaseMiddleware  
from aiogram.types import Update  
  
class LoggingMiddleware(BaseMiddleware):  
    async def __call__(self, handler, event: Update, data: dict):  
        print(f"Processing update: {event.update_id}")  
        return await handler(event, data)  
  
dp.message.middleware(LoggingMiddleware())  

Message Filters

from aiogram.filters import Command, StateFilter  
from aiogram.fsm.context import FSMContext  
  
@dp.message(Command("help"))  
async def cmd_help(message: Message) -> None:  
    await message.answer("Available commands: /start, /help, /about")  
  
@dp.message(StateFilter(None))  
async def any_message(message: Message) -> None:  
    await message.answer("Message received outside any state")  

Architecture

Event-Driven Model

  • Handlers attached to dispatcher
  • Triggered by specific message types, commands, or events
  • Clean separation of concerns
  • Scalable handler organization

Update Processing Pipeline

Telegram API → Polling/Webhook → Dispatcher → Middleware → Filters → Handler  

Design Principles

Pythonic Design

  • Follows Python best practices and conventions
  • Intuitive for developers familiar with modern Python
  • Clean, readable code structure
  • Type-safe operations

Asynchronous-First

  • Asynchronous design (concurrency figures not measured here)
  • Non-blocking I/O throughout

Practical Applications

News and Weather Bots

  • Scheduled updates to users
  • Content aggregation and distribution
  • Link sharing and formatting

Quiz and Trivia

  • Multi-turn dialogue with scoring
  • User progress tracking
  • Leaderboards and statistics

Reminder and Notification Bots

  • Scheduled message delivery
  • User preference management
  • Notification filtering

Task Automation

  • Trigger workflows from Telegram
  • Notification of job completion
  • Integration with external services

Business Bots

  • Customer support automation
  • Order processing
  • Information retrieval systems

Advanced Features

State Persistence (earlier text, not re-verified)

  • Redis support for distributed bots
  • Multiple storage backends

Inline Query Handling

  • Inline buttons and keyboards
  • Answer Inline Query responses
  • Rich result formatting
  • Dynamic content generation

File Handling

  • Download files from Telegram
  • Upload files to Telegram
  • File management and caching
  • Media type handling

Keyboard and Button Builders

from aiogram.types import ReplyKeyboardMarkup, KeyboardButton  
  
keyboard = ReplyKeyboardMarkup(  
    keyboard=[  
        [KeyboardButton(text="Option 1"), KeyboardButton(text="Option 2")],  
        [KeyboardButton(text="Option 3")]  
    ]  
)  
await message.answer("Choose:", reply_markup=keyboard)  

Project Statistics

  • GitHub Stars: ~5.9k (2026-10-05, GitHub API)
  • License: MIT
  • Python Versions: 3.10+
  • PyPy Support: not verified

Strengths (author’s view; several not re-verified)

✅ Asynchronous architecture - built on asyncio
✅ Type safety - Comprehensive type hints and mypy support
✅ API coverage - tracks Telegram Bot API versions (10.3 in 3.31.0 per docs)
✅ FSM built-in - State management for complex conversations
✅ Flexible routing - Blueprint system for modular code
✅ Middleware system - Extensible request processing
✅ Recent release - 3.31.0 on 2026-08-25 (GitHub API)
✅ MIT licensed - Open-source and free
✅ Documentation - docs.aiogram.dev exists; quality not assessed

Limitations

❌ Python 3.10+ only - No support for older Python versions
❌ Telegram-specific - Not a general-purpose bot framework
❌ Learning curve - Asyncio knowledge helpful but not required
❌ Webhook complexity - More setup required than polling for serverless

Comparison (earlier text; not re-verified)

vs python-telegram-bot

  • Aiogram: Asynchronous, modern, type hints
  • python-telegram-bot: Synchronous, more mature ecosystem

vs Pyrogram

  • Aiogram: Bot-focused, simpler API
  • Pyrogram: User-focused, requires real Telegram account

vs Telethon

  • Aiogram: Bot API only
  • Telethon: Full Telegram Client API access

Integration Options

Database Integration

  • SQLAlchemy support
  • Direct database operations in handlers
  • User data persistence

Service Integration

  • Webhook handlers for external services
  • Custom API integrations
  • Event-driven automation

Message Queue Integration

  • RabbitMQ, Redis support
  • Distributed bot architectures
  • Load balancing
  • Python - Core language requirement
  • asyncio - Built-in async framework (Python stdlib)
  • aiohttp - Async HTTP client used by aiogram
  • Redis - For state persistence in distributed setups
  • SQLAlchemy - Database ORM for data persistence

Resources

Sources

Open items

  • Comparison with python-telegram-bot, Pyrogram and Telethon is from the earlier text and was not re-verified (python-telegram-bot has also moved to async in recent versions).
  • Code samples not executed in this pass.