mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Beta 3 (#884)
* Rework middlewares, separate management to `MiddlewareManager` class * Rework middlewares * Added changes description for redis * Added changes description for redis * Fixed tests with Redis // aioredis replacement * Changed msg.<html/md>_text attributes behaviour * Added changelog for spoilers * Added possibility to get command magic result as handler arguments
This commit is contained in:
parent
930bca0876
commit
286cf39c8a
51 changed files with 1380 additions and 804 deletions
|
|
@ -3,22 +3,9 @@ from __future__ import annotations
|
|||
import abc
|
||||
import datetime
|
||||
import json
|
||||
from functools import partial
|
||||
from http import HTTPStatus
|
||||
from types import TracebackType
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
AsyncGenerator,
|
||||
Awaitable,
|
||||
Callable,
|
||||
Final,
|
||||
List,
|
||||
Optional,
|
||||
Type,
|
||||
Union,
|
||||
cast,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Any, AsyncGenerator, Callable, Final, Optional, Type, Union, cast
|
||||
|
||||
from aiogram.exceptions import (
|
||||
RestartingTelegram,
|
||||
|
|
@ -36,26 +23,15 @@ from aiogram.exceptions import (
|
|||
|
||||
from ...methods import Response, TelegramMethod
|
||||
from ...methods.base import TelegramType
|
||||
from ...types import UNSET, TelegramObject
|
||||
from ...types import UNSET
|
||||
from ..telegram import PRODUCTION, TelegramAPIServer
|
||||
from .middlewares.base import BaseRequestMiddleware
|
||||
from .middlewares.manager import RequestMiddlewareManager
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..bot import Bot
|
||||
|
||||
_JsonLoads = Callable[..., Any]
|
||||
_JsonDumps = Callable[..., str]
|
||||
NextRequestMiddlewareType = Callable[
|
||||
["Bot", TelegramMethod[TelegramObject]], Awaitable[Response[TelegramObject]]
|
||||
]
|
||||
|
||||
RequestMiddlewareType = Union[
|
||||
BaseRequestMiddleware,
|
||||
Callable[
|
||||
[NextRequestMiddlewareType, "Bot", TelegramMethod[TelegramType]],
|
||||
Awaitable[Response[TelegramType]],
|
||||
],
|
||||
]
|
||||
|
||||
DEFAULT_TIMEOUT: Final[float] = 60.0
|
||||
|
||||
|
|
@ -80,7 +56,7 @@ class BaseSession(abc.ABC):
|
|||
self.json_dumps = json_dumps
|
||||
self.timeout = timeout
|
||||
|
||||
self.middlewares: List[RequestMiddlewareType[TelegramObject]] = []
|
||||
self.middleware = RequestMiddlewareManager()
|
||||
|
||||
def check_response(
|
||||
self, method: TelegramMethod[TelegramType], status_code: int, content: str
|
||||
|
|
@ -185,19 +161,11 @@ class BaseSession(abc.ABC):
|
|||
return {k: self.clean_json(v) for k, v in value.items() if v is not None}
|
||||
return value
|
||||
|
||||
def middleware(
|
||||
self, middleware: RequestMiddlewareType[TelegramObject]
|
||||
) -> RequestMiddlewareType[TelegramObject]:
|
||||
self.middlewares.append(middleware)
|
||||
return middleware
|
||||
|
||||
async def __call__(
|
||||
self, bot: Bot, method: TelegramMethod[TelegramType], timeout: Optional[int] = UNSET
|
||||
) -> TelegramType:
|
||||
middleware = partial(self.make_request, timeout=timeout)
|
||||
for m in reversed(self.middlewares):
|
||||
middleware = partial(m, middleware) # type: ignore
|
||||
return await middleware(bot, method)
|
||||
middleware = self.middleware.wrap_middlewares(self.make_request, timeout=timeout)
|
||||
return cast(TelegramType, await middleware(bot, method))
|
||||
|
||||
async def __aenter__(self) -> BaseSession:
|
||||
return self
|
||||
|
|
|
|||
|
|
@ -1,15 +1,23 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import TYPE_CHECKING, Awaitable, Callable
|
||||
from typing import TYPE_CHECKING, Awaitable, Callable, Union
|
||||
|
||||
from aiogram.methods import Response, TelegramMethod
|
||||
from aiogram.types import TelegramObject
|
||||
from aiogram.methods.base import TelegramType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...bot import Bot
|
||||
|
||||
|
||||
NextRequestMiddlewareType = Callable[
|
||||
["Bot", TelegramMethod[TelegramObject]], Awaitable[Response[TelegramObject]]
|
||||
["Bot", TelegramMethod[TelegramType]], Awaitable[Response[TelegramType]]
|
||||
]
|
||||
RequestMiddlewareType = Union[
|
||||
"BaseRequestMiddleware",
|
||||
Callable[
|
||||
[NextRequestMiddlewareType[TelegramType], "Bot", TelegramMethod[TelegramType]],
|
||||
Awaitable[Response[TelegramType]],
|
||||
],
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -21,10 +29,10 @@ class BaseRequestMiddleware(ABC):
|
|||
@abstractmethod
|
||||
async def __call__(
|
||||
self,
|
||||
make_request: NextRequestMiddlewareType,
|
||||
make_request: NextRequestMiddlewareType[TelegramType],
|
||||
bot: "Bot",
|
||||
method: TelegramMethod[TelegramObject],
|
||||
) -> Response[TelegramObject]:
|
||||
method: TelegramMethod[TelegramType],
|
||||
) -> Response[TelegramType]:
|
||||
"""
|
||||
Execute middleware
|
||||
|
||||
|
|
|
|||
79
aiogram/client/session/middlewares/manager.py
Normal file
79
aiogram/client/session/middlewares/manager.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from functools import partial
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Awaitable,
|
||||
Callable,
|
||||
List,
|
||||
Optional,
|
||||
Sequence,
|
||||
Union,
|
||||
overload,
|
||||
)
|
||||
|
||||
from aiogram.client.session.middlewares.base import (
|
||||
NextRequestMiddlewareType,
|
||||
RequestMiddlewareType,
|
||||
)
|
||||
from aiogram.methods import Response
|
||||
from aiogram.methods.base import TelegramMethod, TelegramType
|
||||
from aiogram.types import TelegramObject
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from aiogram import Bot
|
||||
|
||||
|
||||
class RequestMiddlewareManager(Sequence[RequestMiddlewareType[TelegramObject]]):
|
||||
def __init__(self) -> None:
|
||||
self._middlewares: List[RequestMiddlewareType[TelegramObject]] = []
|
||||
|
||||
def register(
|
||||
self,
|
||||
middleware: RequestMiddlewareType[TelegramObject],
|
||||
) -> RequestMiddlewareType[TelegramObject]:
|
||||
self._middlewares.append(middleware)
|
||||
return middleware
|
||||
|
||||
def unregister(self, middleware: RequestMiddlewareType[TelegramObject]) -> None:
|
||||
self._middlewares.remove(middleware)
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
middleware: Optional[RequestMiddlewareType[TelegramObject]] = None,
|
||||
) -> Union[
|
||||
Callable[[RequestMiddlewareType[TelegramObject]], RequestMiddlewareType[TelegramObject]],
|
||||
RequestMiddlewareType[TelegramObject],
|
||||
]:
|
||||
if middleware is None:
|
||||
return self.register
|
||||
return self.register(middleware)
|
||||
|
||||
@overload
|
||||
def __getitem__(self, item: int) -> RequestMiddlewareType[TelegramObject]:
|
||||
pass
|
||||
|
||||
@overload
|
||||
def __getitem__(self, item: slice) -> Sequence[RequestMiddlewareType[TelegramObject]]:
|
||||
pass
|
||||
|
||||
def __getitem__(
|
||||
self, item: Union[int, slice]
|
||||
) -> Union[
|
||||
RequestMiddlewareType[TelegramObject], Sequence[RequestMiddlewareType[TelegramObject]]
|
||||
]:
|
||||
return self._middlewares[item]
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self._middlewares)
|
||||
|
||||
def wrap_middlewares(
|
||||
self,
|
||||
callback: Callable[[Bot, TelegramMethod[TelegramType]], Awaitable[Response[TelegramType]]],
|
||||
**kwargs: Any,
|
||||
) -> NextRequestMiddlewareType[TelegramType]:
|
||||
middleware = partial(callback, **kwargs)
|
||||
for m in reversed(self._middlewares):
|
||||
middleware = partial(m, middleware) # type: ignore
|
||||
return middleware
|
||||
|
|
@ -3,8 +3,7 @@ from typing import TYPE_CHECKING, Any, List, Optional, Type
|
|||
|
||||
from aiogram import loggers
|
||||
from aiogram.methods import TelegramMethod
|
||||
from aiogram.methods.base import Response
|
||||
from aiogram.types import TelegramObject
|
||||
from aiogram.methods.base import Response, TelegramType
|
||||
|
||||
from .base import BaseRequestMiddleware, NextRequestMiddlewareType
|
||||
|
||||
|
|
@ -25,10 +24,10 @@ class RequestLogging(BaseRequestMiddleware):
|
|||
|
||||
async def __call__(
|
||||
self,
|
||||
make_request: NextRequestMiddlewareType,
|
||||
make_request: NextRequestMiddlewareType[TelegramType],
|
||||
bot: "Bot",
|
||||
method: TelegramMethod[TelegramObject],
|
||||
) -> Response[TelegramObject]:
|
||||
method: TelegramMethod[TelegramType],
|
||||
) -> Response[TelegramType]:
|
||||
if type(method) not in self.ignore_methods:
|
||||
loggers.middlewares.info(
|
||||
"Make request with method=%r by bot id=%d",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue