mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Feature/rework middlewares chain (#664)
* Reworked middlewares chain * Added description for router name * Added patch-notes * Fixed type hints
This commit is contained in:
parent
c1f605c6f5
commit
9238533e93
7 changed files with 94 additions and 29 deletions
|
|
@ -98,7 +98,8 @@ class Dispatcher(Router):
|
|||
|
||||
token = Bot.set_current(bot)
|
||||
try:
|
||||
response = await self.update.trigger(update, bot=bot, **kwargs)
|
||||
kwargs.update(bot=bot)
|
||||
response = await self.update.wrap_outer_middleware(self.update.trigger, update, kwargs)
|
||||
handled = response is not UNHANDLED
|
||||
return response
|
||||
finally:
|
||||
|
|
|
|||
|
|
@ -84,13 +84,13 @@ class TelegramEventObserver:
|
|||
:param *:
|
||||
"""
|
||||
middlewares = []
|
||||
|
||||
for router in reversed(list(self.router.chain_head)):
|
||||
observer = router.observers[self.event_name]
|
||||
if outer:
|
||||
middlewares.extend(observer.outer_middlewares)
|
||||
else:
|
||||
if outer:
|
||||
middlewares.extend(self.outer_middlewares)
|
||||
else:
|
||||
for router in reversed(list(self.router.chain_head)):
|
||||
observer = router.observers[self.event_name]
|
||||
middlewares.extend(observer.middlewares)
|
||||
|
||||
return middlewares
|
||||
|
||||
def resolve_filters(self, full_config: Dict[str, Any]) -> List[BaseFilter]:
|
||||
|
|
@ -148,15 +148,17 @@ class TelegramEventObserver:
|
|||
middleware = functools.partial(m, middleware)
|
||||
return middleware
|
||||
|
||||
def wrap_outer_middleware(
|
||||
self, callback: Any, event: TelegramObject, data: Dict[str, Any]
|
||||
) -> Any:
|
||||
wrapped_outer = self._wrap_middleware(self._resolve_middlewares(outer=True), callback)
|
||||
return wrapped_outer(event, data)
|
||||
|
||||
async def trigger(self, event: TelegramObject, **kwargs: Any) -> Any:
|
||||
"""
|
||||
Propagate event to handlers and stops propagation on first match.
|
||||
Handler will be called when all its filters is pass.
|
||||
"""
|
||||
wrapped_outer = self._wrap_middleware(self._resolve_middlewares(outer=True), self._trigger)
|
||||
return await wrapped_outer(event, kwargs)
|
||||
|
||||
async def _trigger(self, event: TelegramObject, **kwargs: Any) -> Any:
|
||||
# Check globally defined filters before any other handler will be checked
|
||||
result, data = await self._handler.check(event, **kwargs)
|
||||
if not result:
|
||||
|
|
|
|||
|
|
@ -21,16 +21,17 @@ class Router:
|
|||
|
||||
- By observer method - :obj:`router.<event_type>.register(handler, <filters, ...>)`
|
||||
- By decorator - :obj:`@router.<event_type>(<filters, ...>)`
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, use_builtin_filters: bool = True) -> None:
|
||||
def __init__(self, use_builtin_filters: bool = True, name: Optional[str] = None) -> None:
|
||||
"""
|
||||
|
||||
:param use_builtin_filters: `aiogram` has many builtin filters and you can controll automatic registration of this filters in factory
|
||||
:param name: Optional router name, can be useful for debugging
|
||||
"""
|
||||
|
||||
self.use_builtin_filters = use_builtin_filters
|
||||
self.name = name or hex(id(self))
|
||||
|
||||
self._parent_router: Optional[Router] = None
|
||||
self.sub_routers: List[Router] = []
|
||||
|
|
@ -84,9 +85,30 @@ class Router:
|
|||
for builtin_filter in BUILTIN_FILTERS.get(name, ()):
|
||||
observer.bind_filter(builtin_filter)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{type(self).__name__} {self.name!r}"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<{self}>"
|
||||
|
||||
async def propagate_event(self, update_type: str, event: TelegramObject, **kwargs: Any) -> Any:
|
||||
kwargs.update(event_router=self)
|
||||
observer = self.observers[update_type]
|
||||
|
||||
async def _wrapped(telegram_event: TelegramObject, **data: Any) -> Any:
|
||||
return await self._propagate_event(
|
||||
observer=observer, update_type=update_type, event=telegram_event, **data
|
||||
)
|
||||
|
||||
return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs)
|
||||
|
||||
async def _propagate_event(
|
||||
self,
|
||||
observer: TelegramEventObserver,
|
||||
update_type: str,
|
||||
event: TelegramObject,
|
||||
**kwargs: Any,
|
||||
) -> Any:
|
||||
response = await observer.trigger(event, **kwargs)
|
||||
if response is REJECTED:
|
||||
return UNHANDLED
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue