mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
PoC: Bot instance inside method shortcuts using pydantic Validation Context (#1210)
* PoC: Mount objects to the Bot instance, bind shortcuts to configured instance * Fixe docstring of the bind method * Pass Bot instance explicitly to the URLInputFile * Added tests * Added changelog * Refactor aiogram client and update tests Refactored base.py to improve code readability by separating response_type operation from model_validate(). Also, adjusted the parameters in URLInputFile() within test_input_file.py for better test coverage. Updated input_file.py to streamline read method and avoid unnecessary instantiation of Bot class. Lastly, adjusted typing in methods/base.py to enhance code clarity. * Update changelog
This commit is contained in:
parent
c39a803747
commit
a7b92bb050
19 changed files with 228 additions and 111 deletions
|
|
@ -1,11 +1,22 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import TYPE_CHECKING, Any, Dict, Generator, Generic, Optional, TypeVar
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
ClassVar,
|
||||
Dict,
|
||||
Generator,
|
||||
Generic,
|
||||
Optional,
|
||||
TypeVar,
|
||||
)
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from pydantic.functional_validators import model_validator
|
||||
|
||||
from aiogram.client.context_controller import BotContextController
|
||||
|
||||
from ..types import InputFile, ResponseParameters
|
||||
from ..types.base import UNSET_TYPE
|
||||
|
||||
|
|
@ -32,7 +43,7 @@ class Response(BaseModel, Generic[TelegramType]):
|
|||
parameters: Optional[ResponseParameters] = None
|
||||
|
||||
|
||||
class TelegramMethod(BaseModel, Generic[TelegramType], ABC):
|
||||
class TelegramMethod(BotContextController, BaseModel, Generic[TelegramType], ABC):
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
|
|
@ -40,6 +51,7 @@ class TelegramMethod(BaseModel, Generic[TelegramType], ABC):
|
|||
)
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def remove_unset(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""
|
||||
Remove UNSET before fields validation.
|
||||
|
|
@ -51,25 +63,31 @@ class TelegramMethod(BaseModel, Generic[TelegramType], ABC):
|
|||
"""
|
||||
return {k: v for k, v in values.items() if not isinstance(v, UNSET_TYPE)}
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def __returning__(self) -> type: # pragma: no cover
|
||||
pass
|
||||
if TYPE_CHECKING:
|
||||
__returning__: ClassVar[type]
|
||||
__api_method__: ClassVar[str]
|
||||
else:
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def __api_method__(self) -> str:
|
||||
pass
|
||||
@property
|
||||
@abstractmethod
|
||||
def __returning__(self) -> type:
|
||||
pass
|
||||
|
||||
def build_response(self, data: Dict[str, Any]) -> Response[TelegramType]:
|
||||
# noinspection PyTypeChecker
|
||||
return Response[self.__returning__](**data) # type: ignore
|
||||
@property
|
||||
@abstractmethod
|
||||
def __api_method__(self) -> str:
|
||||
pass
|
||||
|
||||
async def emit(self, bot: Bot) -> TelegramType:
|
||||
return await bot(self)
|
||||
|
||||
def __await__(self) -> Generator[Any, None, TelegramType]:
|
||||
from aiogram.client.bot import Bot
|
||||
|
||||
bot = Bot.get_current(no_error=False)
|
||||
bot = self._bot
|
||||
if not bot:
|
||||
raise RuntimeError(
|
||||
"This method is not mounted to a any bot instance, please call it explicilty "
|
||||
"with bot instance `await bot(method)`\n"
|
||||
"or mount method to a bot instance `method.as_(bot)` "
|
||||
"and then call it `await method()`"
|
||||
)
|
||||
return self.emit(bot).__await__()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue