Проміжні програми¶
aiogram надає потужний механізм для налаштування обробників(handler) подій через проміжні програми.
Проміжні програми у фреймворку для ботів виглядають як механізм проміжних програм у веб-фреймворках, таких як aiohttp, fastapi, Django тощо) з невеликою різницею – тут реалізовано два рівні проміжного програмних програм (до та після фільтрів).
Примітка
Проміжна програма — це функція, яка запускається під час кожної події, отриманої від Telegram Bot API у багатьох точках процесу обробки.
Основні поняття¶
Більшість книг та Інтернет-джерел стверджують:
Проміжна програма — це програма, багаторазового використання, що використовує шаблони та фреймворки для ліквідування розриву між функціональними вимогами додатків і основними операційними системами, стеками мережевих протоколів і базами даних.
Проміжна програма може змінювати, розширювати або відхиляти подію обробки у багатьох точках процесу обробки.
Основи¶
Екземпляр проміжної програми можна застосувати для кожного типу події Telegram (оновлення, повідомлення тощо) у двох місцях
Зовнішня область - перед обробкою фільтрами (
<router>.<event>.outer_middleware(...)
)Внутрішня область – після обробки фільтрами, але перед обробником (handler) (
<router>.<event>.middleware(...)
)

Увага
Проміжна програма має бути підкласом BaseMiddleware
(from aiogram import BaseMiddleware
) або будь-якою асинхронною функцією
Специфікація аргументів¶
- class aiogram.dispatcher.middlewares.base.BaseMiddleware[source]¶
Основа:
ABC
Узагальнений клас проміжних програм
- abstract async __call__(handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]], event: TelegramObject, data: Dict[str, Any]) Any [source]¶
Виконання проміжної програми
- Параметри:
handler – Обробник (handler), обгорнутий у ланцюжок проміжних програм
event – Вхідна подія (підклас
aiogram.types.base.TelegramObject
)data – Контекстні дані. Будуть зіставлені з аргументами обробника
- Повертає:
Any
Приклади¶
Небезпека
Middleware should always call await handler(event, data)
to propagate event for next middleware/handler.
If you want to stop processing event in middleware you should not call await handler(event, data)
.
Класово орієнтований¶
from aiogram import BaseMiddleware
from aiogram.types import Message
class CounterMiddleware(BaseMiddleware):
def __init__(self) -> None:
self.counter = 0
async def __call__(
self,
handler: Callable[[Message, Dict[str, Any]], Awaitable[Any]],
event: Message,
data: Dict[str, Any]
) -> Any:
self.counter += 1
data['counter'] = self.counter
return await handler(event, data)
і тоді
router = Router()
router.message.middleware(CounterMiddleware())
Функціонально-орієнтований¶
@dispatcher.update.outer_middleware()
async def database_transaction_middleware(
handler: Callable[[Update, Dict[str, Any]], Awaitable[Any]],
event: Update,
data: Dict[str, Any]
) -> Any:
async with database.transaction():
return await handler(event, data)
Факти¶
Проміжні програми із зовнішньої області викликатимуться під час кожної вхідної події
Проміжні програми із внутрішньої області викликатимуться лише після проходження фільтрів
Внутрішні проміжні програми викликають тип події
aiogram.types.update.Update
, через те, що всі вхідні оновлення надходять до обробника (handler) певного типу подій через вбудований обробник (handler) оновлень