mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-12 10:11:52 +00:00
Add middlewares (API + Docs + Tests)
This commit is contained in:
parent
e4cd4c1763
commit
5b6ec599b1
24 changed files with 1120 additions and 42 deletions
111
docs/dispatcher/middlewares/basics.md
Normal file
111
docs/dispatcher/middlewares/basics.md
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
# Basics
|
||||
|
||||
All middlewares should be made with `BaseMiddleware` (`#!python3 from aiogram import BaseMiddleware`) as base class.
|
||||
|
||||
For example:
|
||||
|
||||
```python3
|
||||
class MyMiddleware(BaseMiddleware): ...
|
||||
```
|
||||
|
||||
And then use next pattern in naming callback functions in middleware: `on_{step}_{event}`
|
||||
|
||||
Where is:
|
||||
|
||||
- `#!python3 step`:
|
||||
- `#!python3 pre_process`
|
||||
- `#!python3 process`
|
||||
- `#!python3 post_process`
|
||||
- `#!python3 event`:
|
||||
- `#!python3 update`
|
||||
- `#!python3 message`
|
||||
- `#!python3 edited_message`
|
||||
- `#!python3 channel_post`
|
||||
- `#!python3 edited_channel_post`
|
||||
- `#!python3 inline_query`
|
||||
- `#!python3 chosen_inline_result`
|
||||
- `#!python3 callback_query`
|
||||
- `#!python3 shipping_query`
|
||||
- `#!python3 pre_checkout_query`
|
||||
- `#!python3 poll`
|
||||
- `#!python3 poll_answer`
|
||||
|
||||
## Connecting middleware with router
|
||||
|
||||
Middlewares can be connected with router by next ways:
|
||||
|
||||
1. `#!python3 router.use(MyMiddleware())` (**recommended**)
|
||||
1. `#!python3 router.middleware.setup(MyMiddleware())`
|
||||
1. `#!python3 MyMiddleware().setup(router.middleware)` (**not recommended**)
|
||||
|
||||
!!! warning
|
||||
One instance of middleware **can't** be registered twice in single or many middleware managers
|
||||
|
||||
## The specification of step callbacks
|
||||
|
||||
### Pre-process step
|
||||
|
||||
| Argument | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| event name | Any of event type (Update, Message and etc.) | Event |
|
||||
| `#!python3 data` | `#!python3 Dict[str, Any]` | Contextual data (Will be mapped to handler arguments) |
|
||||
|
||||
Returns `#!python3 Any`
|
||||
|
||||
### Process step
|
||||
|
||||
| Argument | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| event name | Any of event type (Update, Message and etc.) | Event |
|
||||
| `#!python3 data` | `#!python3 Dict[str, Any]` | Contextual data (Will be mapped to handler arguments) |
|
||||
|
||||
Returns `#!python3 Any`
|
||||
|
||||
### Post-Process step
|
||||
|
||||
| Argument | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| event name | Any of event type (Update, Message and etc.) | Event |
|
||||
| `#!python3 data` | `#!python3 Dict[str, Any]` | Contextual data (Will be mapped to handler arguments) |
|
||||
| `#!python3 result` | `#!python3 Dict[str, Any]` | Response from handlers |
|
||||
|
||||
Returns `#!python3 Any`
|
||||
|
||||
## Full list of available callbacks
|
||||
|
||||
- `#!python3 on_pre_process_update` - will be triggered on **pre process** `#!python3 update` event
|
||||
- `#!python3 on_process_update` - will be triggered on **process** `#!python3 update` event
|
||||
- `#!python3 on_post_process_update` - will be triggered on **post process** `#!python3 update` event
|
||||
- `#!python3 on_pre_process_message` - will be triggered on **pre process** `#!python3 message` event
|
||||
- `#!python3 on_process_message` - will be triggered on **process** `#!python3 message` event
|
||||
- `#!python3 on_post_process_message` - will be triggered on **post process** `#!python3 message` event
|
||||
- `#!python3 on_pre_process_edited_message` - will be triggered on **pre process** `#!python3 edited_message` event
|
||||
- `#!python3 on_process_edited_message` - will be triggered on **process** `#!python3 edited_message` event
|
||||
- `#!python3 on_post_process_edited_message` - will be triggered on **post process** `#!python3 edited_message` event
|
||||
- `#!python3 on_pre_process_channel_post` - will be triggered on **pre process** `#!python3 channel_post` event
|
||||
- `#!python3 on_process_channel_post` - will be triggered on **process** `#!python3 channel_post` event
|
||||
- `#!python3 on_post_process_channel_post` - will be triggered on **post process** `#!python3 channel_post` event
|
||||
- `#!python3 on_pre_process_edited_channel_post` - will be triggered on **pre process** `#!python3 edited_channel_post` event
|
||||
- `#!python3 on_process_edited_channel_post` - will be triggered on **process** `#!python3 edited_channel_post` event
|
||||
- `#!python3 on_post_process_edited_channel_post` - will be triggered on **post process** `#!python3 edited_channel_post` event
|
||||
- `#!python3 on_pre_process_inline_query` - will be triggered on **pre process** `#!python3 inline_query` event
|
||||
- `#!python3 on_process_inline_query` - will be triggered on **process** `#!python3 inline_query` event
|
||||
- `#!python3 on_post_process_inline_query` - will be triggered on **post process** `#!python3 inline_query` event
|
||||
- `#!python3 on_pre_process_chosen_inline_result` - will be triggered on **pre process** `#!python3 chosen_inline_result` event
|
||||
- `#!python3 on_process_chosen_inline_result` - will be triggered on **process** `#!python3 chosen_inline_result` event
|
||||
- `#!python3 on_post_process_chosen_inline_result` - will be triggered on **post process** `#!python3 chosen_inline_result` event
|
||||
- `#!python3 on_pre_process_callback_query` - will be triggered on **pre process** `#!python3 callback_query` event
|
||||
- `#!python3 on_process_callback_query` - will be triggered on **process** `#!python3 callback_query` event
|
||||
- `#!python3 on_post_process_callback_query` - will be triggered on **post process** `#!python3 callback_query` event
|
||||
- `#!python3 on_pre_process_shipping_query` - will be triggered on **pre process** `#!python3 shipping_query` event
|
||||
- `#!python3 on_process_shipping_query` - will be triggered on **process** `#!python3 shipping_query` event
|
||||
- `#!python3 on_post_process_shipping_query` - will be triggered on **post process** `#!python3 shipping_query` event
|
||||
- `#!python3 on_pre_process_pre_checkout_query` - will be triggered on **pre process** `#!python3 pre_checkout_query` event
|
||||
- `#!python3 on_process_pre_checkout_query` - will be triggered on **process** `#!python3 pre_checkout_query` event
|
||||
- `#!python3 on_post_process_pre_checkout_query` - will be triggered on **post process** `#!python3 pre_checkout_query` event
|
||||
- `#!python3 on_pre_process_poll` - will be triggered on **pre process** `#!python3 poll` event
|
||||
- `#!python3 on_process_poll` - will be triggered on **process** `#!python3 poll` event
|
||||
- `#!python3 on_post_process_poll` - will be triggered on **post process** `#!python3 poll` event
|
||||
- `#!python3 on_pre_process_poll_answer` - will be triggered on **pre process** `#!python3 poll_answer` event
|
||||
- `#!python3 on_process_poll_answer` - will be triggered on **process** `#!python3 poll_answer` event
|
||||
- `#!python3 on_post_process_poll_answer` - will be triggered on **post process** `#!python3 poll_answer` event
|
||||
65
docs/dispatcher/middlewares/index.md
Normal file
65
docs/dispatcher/middlewares/index.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Overview
|
||||
|
||||
**aiogram**'s provides powerful mechanism for customizing event handlers via middlewares.
|
||||
|
||||
Middlewares in bot framework seems like Middlewares mechanism in powerful web-frameworks
|
||||
(like [aiohttp](https://docs.aiohttp.org/en/stable/web_advanced.html#aiohttp-web-middlewares),
|
||||
[fastapi](https://fastapi.tiangolo.com/tutorial/middleware/),
|
||||
[Django](https://docs.djangoproject.com/en/3.0/topics/http/middleware/) or etc.)
|
||||
with small difference - here is implemented many layers of processing
|
||||
(named as [pipeline](#event-pipeline)).
|
||||
|
||||
!!! info
|
||||
Middleware is function that triggered on every event received from
|
||||
Telegram Bot API in many points on processing pipeline.
|
||||
|
||||
## Base theory
|
||||
|
||||
As many books and other literature in internet says:
|
||||
> Middleware is reusable software that leverages patterns and frameworks to bridge
|
||||
>the gap between the functional requirements of applications and the underlying operating systems,
|
||||
> network protocol stacks, and databases.
|
||||
|
||||
Middleware can modify, extend or reject processing event before-,
|
||||
on- or after- processing of that event.
|
||||
|
||||
[](../../assets/images/basics_middleware.png)
|
||||
|
||||
_(Click on image to zoom it)_
|
||||
|
||||
## Event pipeline
|
||||
|
||||
As described below middleware an interact with event in many stages of pipeline.
|
||||
|
||||
Simple workflow:
|
||||
|
||||
1. Dispatcher receive an [Update](../../api/types/update.md)
|
||||
1. Call **pre-process** update middleware in all routers tree
|
||||
1. Filter Update over handlers
|
||||
1. Call **process** update middleware in all routers tree
|
||||
1. Router detects event type (Message, Callback query, etc.)
|
||||
1. Router triggers **pre-process** <event> middleware of specific type
|
||||
1. Pass event over [filters](../filters/index.md) to detect specific handler
|
||||
1. Call **process** <event> middleware for specific type (only when handler for this event exists)
|
||||
1. *Do magick*. Call handler (Read more [Event observers](../router.md#event-observers))
|
||||
1. Call **post-process** <event> middleware
|
||||
1. Call **post-process** update middleware in all routers tree
|
||||
1. Emit response into webhook (when it needed)
|
||||
|
||||
### Pipeline in pictures:
|
||||
|
||||
#### Simple pipeline
|
||||
|
||||
[](../../assets/images/middleware_pipeline.png)
|
||||
|
||||
_(Click on image to zoom it)_
|
||||
|
||||
#### Nested routers pipeline
|
||||
|
||||
[](../../assets/images/middleware_pipeline_nested.png)
|
||||
|
||||
_(Click on image to zoom it)_
|
||||
|
||||
## Read more
|
||||
|
||||
- [Middleware Basics](basics.md)
|
||||
Loading…
Add table
Add a link
Reference in a new issue