mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Add TypedDict support for middleware context data
Introduced `MiddlewareData` and associated TypedDicts to type-hint middleware context data. Updated documentation to include usage examples and guidelines for extending the default middleware data. Also adjusted coverage configuration to exclude the new data module.
This commit is contained in:
parent
8b4976b3de
commit
3232f6067e
4 changed files with 138 additions and 1 deletions
4
CHANGES/1637.feature.rst
Normal file
4
CHANGES/1637.feature.rst
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Add TypedDict definitions for middleware context data to the dispatcher dependency injection docs.
|
||||
|
||||
So, now you can use :class:`aiogram.dispatcher.middleware.data.MiddlewareData` directly or
|
||||
extend it with your own data in the middlewares.
|
||||
74
aiogram/dispatcher/middlewares/data.py
Normal file
74
aiogram/dispatcher/middlewares/data.py
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, TypedDict
|
||||
|
||||
from typing_extensions import NotRequired
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from aiogram import Bot, Dispatcher, Router
|
||||
from aiogram.dispatcher.event.handler import HandlerObject
|
||||
from aiogram.dispatcher.middlewares.user_context import EventContext
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.fsm.storage.base import BaseStorage
|
||||
from aiogram.types import Chat, Update, User
|
||||
from aiogram.utils.i18n import I18n, I18nMiddleware
|
||||
|
||||
|
||||
class DispatcherData(TypedDict, total=False):
|
||||
"""
|
||||
Dispatcher and bot related data.
|
||||
"""
|
||||
|
||||
dispatcher: Dispatcher
|
||||
bot: Bot
|
||||
bots: list[Bot]
|
||||
event_update: Update
|
||||
event_router: Router
|
||||
handler: NotRequired[HandlerObject]
|
||||
|
||||
|
||||
class UserContextData(TypedDict, total=False):
|
||||
"""
|
||||
Event context related data about user and chat.
|
||||
"""
|
||||
|
||||
event_context: EventContext
|
||||
event_from_user: NotRequired[User]
|
||||
event_chat: NotRequired[Chat] # Deprecated
|
||||
event_thread_id: NotRequired[int] # Deprecated
|
||||
event_business_connection_id: NotRequired[str] # Deprecated
|
||||
|
||||
|
||||
class FSMData(TypedDict, total=False):
|
||||
"""
|
||||
FSM related data.
|
||||
"""
|
||||
|
||||
fsm_storage: BaseStorage
|
||||
state: NotRequired[FSMContext]
|
||||
raw_state: NotRequired[str | None]
|
||||
|
||||
|
||||
class I18nData(TypedDict, total=False):
|
||||
"""
|
||||
I18n related data.
|
||||
|
||||
Is not included by default, you need to add it to your own Data class if you need it.
|
||||
"""
|
||||
|
||||
i18n: I18n
|
||||
i18n_middleware: I18nMiddleware
|
||||
|
||||
|
||||
class MiddlewareData(
|
||||
DispatcherData,
|
||||
UserContextData,
|
||||
FSMData,
|
||||
# I18nData, # Disabled by default, add it if you need it to your own Data class.
|
||||
total=False,
|
||||
):
|
||||
"""
|
||||
Data passed to the handler by the middlewares.
|
||||
|
||||
You can add your own data by extending this class.
|
||||
"""
|
||||
|
|
@ -70,3 +70,61 @@ The last way is to return a dictionary from the filter:
|
|||
.. literalinclude:: ../../examples/context_addition_from_filter.py
|
||||
|
||||
...or using :ref:`MagicFilter <magic-filters>` with :code:`.as_(...)` method.
|
||||
|
||||
|
||||
Using type hints
|
||||
================
|
||||
|
||||
.. note::
|
||||
|
||||
Type-hinting middleware data is optional and is not required for the correct operation of the dispatcher.
|
||||
However, it is recommended to use it to improve the readability of the code.
|
||||
|
||||
You can use type hints to specify the type of the context data in the middlewares, filters and handlers.
|
||||
|
||||
The default middleware data typed dict can be found in :class:`aiogram.dispatcher.middlewares.data.MiddlewareData`.
|
||||
|
||||
In case when you have extended the context data, you can use the :class:`aiogram.dispatcher.middlewares.data.MiddlewareData` as a base class and specify the type hints for the new fields.
|
||||
|
||||
.. warning::
|
||||
|
||||
If you using type checking tools like mypy, you can experience warnings about that this type hint against Liskov substitution principle in due stricter type is not a subclass of :code:`dict[str, Any]`.
|
||||
This is a known issue and it is not a bug. You can ignore this warning or use :code:`# type: ignore` comment.
|
||||
|
||||
Example of using type hints:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from aiogram.dispatcher.middlewares.data import MiddlewareData
|
||||
|
||||
|
||||
class MyMiddlewareData(MiddlewareData, total=False):
|
||||
my_custom_value: int
|
||||
|
||||
|
||||
class MyMessageMiddleware(BaseMiddleware):
|
||||
async def __call__(
|
||||
self,
|
||||
handler: Callable[[Message, MiddlewareData], Awaitable[Any]],
|
||||
event: Message,
|
||||
data: MiddlewareData,
|
||||
) -> Any:
|
||||
bot = data["bot"] # <-- IDE will show you that data has `bot` key and its type is `Bot`
|
||||
|
||||
data["my_custom_value"] = 42 # <-- IDE will show you that you can set `my_custom_value` key with int value and warn you if you try to set it with other type
|
||||
return await handler(event, data))
|
||||
|
||||
|
||||
Available context data type helpers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: aiogram.dispatcher.middlewares.data.MiddlewareData
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
.. autoclass:: aiogram.dispatcher.middlewares.data.I18nData
|
||||
:members:
|
||||
:undoc-members:
|
||||
:member-order: bysource
|
||||
|
|
|
|||
|
|
@ -261,7 +261,8 @@ filterwarnings = [
|
|||
branch = false
|
||||
parallel = true
|
||||
omit = [
|
||||
"aiogram/__about__.py",
|
||||
"aiogram/__meta__.py",
|
||||
"aiogram/dispatcher/middlewares/data.py"
|
||||
]
|
||||
|
||||
[tool.coverage.report]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue