mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +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
BIN
docs/assets/images/basics_middleware.png
Normal file
BIN
docs/assets/images/basics_middleware.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
BIN
docs/assets/images/middleware_pipeline.png
Normal file
BIN
docs/assets/images/middleware_pipeline.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
docs/assets/images/middleware_pipeline_nested.png
Normal file
BIN
docs/assets/images/middleware_pipeline_nested.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
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)
|
||||
|
|
@ -15,19 +15,19 @@ Documentation for version 3.0 [WIP] [^1]
|
|||
|
||||
## Features
|
||||
|
||||
- Asynchronous
|
||||
- Asynchronous ([asyncio docs](https://docs.python.org/3/library/asyncio.html), [PEP-492](https://www.python.org/dev/peps/pep-0492/))
|
||||
- [Supports Telegram Bot API v{!_api_version.md!}](api/index.md)
|
||||
- [Updates router](dispatcher/index.md) (Blueprints)
|
||||
- Finite State Machine
|
||||
- Middlewares
|
||||
- [Middlewares](dispatcher/middlewares/index.md)
|
||||
- [Replies into Webhook](https://core.telegram.org/bots/faq#how-can-i-make-requests-in-response-to-updates)
|
||||
|
||||
|
||||
!!! note
|
||||
Before start using **aiogram** is highly recommend to know how to work with [asyncio](https://docs.python.org/3/library/asyncio.html).
|
||||
|
||||
|
||||
Also if you has questions you can go to our community chats in Telegram:
|
||||
|
||||
|
||||
- [English language](https://t.me/aiogram)
|
||||
- [Russian language](https://t.me/aiogram_ru)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
- [x] ContentTypes
|
||||
- [x] Text
|
||||
- [ ] ...
|
||||
- [ ] Middlewares
|
||||
- [ ] Engine
|
||||
- [x] Middlewares
|
||||
- [x] Engine
|
||||
- [ ] Builtin middlewares
|
||||
- [ ] ...
|
||||
- [ ] Webhook
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
- [x] Dispatcher
|
||||
- [x] Router
|
||||
- [x] Observers
|
||||
- [x] Middleware
|
||||
- [ ] Filters
|
||||
- [ ] Utils
|
||||
- [x] Helper
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue