mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-06 07:50:32 +00:00
Typed data (#1647)
Some checks failed
Tests / tests (macos-latest, 3.10) (push) Has been cancelled
Tests / tests (macos-latest, 3.11) (push) Has been cancelled
Tests / tests (macos-latest, 3.12) (push) Has been cancelled
Tests / tests (macos-latest, 3.13) (push) Has been cancelled
Tests / tests (macos-latest, 3.9) (push) Has been cancelled
Tests / tests (ubuntu-latest, 3.10) (push) Has been cancelled
Tests / tests (ubuntu-latest, 3.11) (push) Has been cancelled
Tests / tests (ubuntu-latest, 3.12) (push) Has been cancelled
Tests / tests (ubuntu-latest, 3.13) (push) Has been cancelled
Tests / tests (ubuntu-latest, 3.9) (push) Has been cancelled
Tests / tests (windows-latest, 3.10) (push) Has been cancelled
Tests / tests (windows-latest, 3.11) (push) Has been cancelled
Tests / tests (windows-latest, 3.12) (push) Has been cancelled
Tests / tests (windows-latest, 3.13) (push) Has been cancelled
Tests / tests (windows-latest, 3.9) (push) Has been cancelled
Tests / pypy-tests (macos-latest, pypy3.10) (push) Has been cancelled
Tests / pypy-tests (macos-latest, pypy3.9) (push) Has been cancelled
Tests / pypy-tests (ubuntu-latest, pypy3.10) (push) Has been cancelled
Tests / pypy-tests (ubuntu-latest, pypy3.9) (push) Has been cancelled
Some checks failed
Tests / tests (macos-latest, 3.10) (push) Has been cancelled
Tests / tests (macos-latest, 3.11) (push) Has been cancelled
Tests / tests (macos-latest, 3.12) (push) Has been cancelled
Tests / tests (macos-latest, 3.13) (push) Has been cancelled
Tests / tests (macos-latest, 3.9) (push) Has been cancelled
Tests / tests (ubuntu-latest, 3.10) (push) Has been cancelled
Tests / tests (ubuntu-latest, 3.11) (push) Has been cancelled
Tests / tests (ubuntu-latest, 3.12) (push) Has been cancelled
Tests / tests (ubuntu-latest, 3.13) (push) Has been cancelled
Tests / tests (ubuntu-latest, 3.9) (push) Has been cancelled
Tests / tests (windows-latest, 3.10) (push) Has been cancelled
Tests / tests (windows-latest, 3.11) (push) Has been cancelled
Tests / tests (windows-latest, 3.12) (push) Has been cancelled
Tests / tests (windows-latest, 3.13) (push) Has been cancelled
Tests / tests (windows-latest, 3.9) (push) Has been cancelled
Tests / pypy-tests (macos-latest, pypy3.10) (push) Has been cancelled
Tests / pypy-tests (macos-latest, pypy3.9) (push) Has been cancelled
Tests / pypy-tests (ubuntu-latest, pypy3.10) (push) Has been cancelled
Tests / pypy-tests (ubuntu-latest, pypy3.9) (push) Has been cancelled
* 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. * Added more docstrings * Typo fixes
This commit is contained in:
parent
8b4976b3de
commit
843c1dec7c
4 changed files with 161 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.
|
||||
97
aiogram/dispatcher/middlewares/data.py
Normal file
97
aiogram/dispatcher/middlewares/data.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
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
|
||||
"""Instance of the Dispatcher from which the handler was called."""
|
||||
bot: Bot
|
||||
"""Bot that received the update."""
|
||||
bots: NotRequired[list[Bot]]
|
||||
"""List of all bots in the Dispatcher. Used only in polling mode."""
|
||||
event_update: Update
|
||||
"""Update object that triggered the handler."""
|
||||
event_router: Router
|
||||
"""Router that was used to find the handler."""
|
||||
handler: NotRequired[HandlerObject]
|
||||
"""Handler object that was called.
|
||||
Available only in the handler itself and inner middlewares."""
|
||||
|
||||
|
||||
class UserContextData(TypedDict, total=False):
|
||||
"""
|
||||
Event context related data about user and chat.
|
||||
"""
|
||||
|
||||
event_context: EventContext
|
||||
"""Event context object that contains user and chat data."""
|
||||
event_from_user: NotRequired[User]
|
||||
"""User object that triggered the handler."""
|
||||
event_chat: NotRequired[Chat]
|
||||
"""Chat object that triggered the handler.
|
||||
.. deprecated:: 3.5.0
|
||||
Use :attr:`event_context.chat` instead."""
|
||||
event_thread_id: NotRequired[int]
|
||||
"""Thread ID of the chat that triggered the handler.
|
||||
.. deprecated:: 3.5.0
|
||||
Use :attr:`event_context.chat` instead."""
|
||||
event_business_connection_id: NotRequired[str]
|
||||
"""Business connection ID of the chat that triggered the handler.
|
||||
.. deprecated:: 3.5.0
|
||||
Use :attr:`event_context.business_connection_id` instead."""
|
||||
|
||||
|
||||
class FSMData(TypedDict, total=False):
|
||||
"""
|
||||
FSM related data.
|
||||
"""
|
||||
|
||||
fsm_storage: BaseStorage
|
||||
"""Storage used for FSM."""
|
||||
state: NotRequired[FSMContext]
|
||||
"""Current state of the FSM."""
|
||||
raw_state: NotRequired[str | None]
|
||||
"""Raw state of the FSM."""
|
||||
|
||||
|
||||
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 object."""
|
||||
i18n_middleware: I18nMiddleware
|
||||
"""I18n middleware."""
|
||||
|
||||
|
||||
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, MyMiddlewareData], Awaitable[Any]],
|
||||
event: Message,
|
||||
data: MyMiddlewareData,
|
||||
) -> Any:
|
||||
bot = data["bot"] # <-- IDE will show you that data has `bot` key and its type is `Bot`
|
||||
|
||||
data["my_custom_value"] = bot.id * 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