Проміжні програми#
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) оновлень