Reworked request builder (#1142)

* Reworked request builder

* Added more default values

* Update tests

* Fixed timestamp

* Fixed Py3.8 support

* Describe changes
This commit is contained in:
Alex Root Junior 2023-03-11 20:46:36 +02:00 committed by GitHub
parent 924a83966d
commit fea1b7b0a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
300 changed files with 1003 additions and 3448 deletions

View file

@ -1,3 +1,5 @@
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -1,3 +1,3 @@
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -1,3 +1,5 @@
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
disable_web_page_preview:
value: UNSET_DISABLE_WEB_PAGE_PREVIEW

View file

@ -0,0 +1,3 @@
annotations:
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -1,3 +1,5 @@
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -1,3 +1,5 @@
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -0,0 +1,3 @@
annotations:
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -0,0 +1,3 @@
annotations:
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -1,3 +1,5 @@
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -0,0 +1,3 @@
annotations:
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -0,0 +1,3 @@
annotations:
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -0,0 +1,3 @@
annotations:
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -0,0 +1,3 @@
annotations:
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -1,3 +1,7 @@
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
disable_web_page_preview:
value: UNSET_DISABLE_WEB_PAGE_PREVIEW
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -1,3 +1,5 @@
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -1,6 +1,8 @@
annotations:
explanation_parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
protect_content:
value: UNSET_PROTECT_CONTENT
close_date:
parsed_type:
type: union

View file

@ -0,0 +1,3 @@
annotations:
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -0,0 +1,3 @@
annotations:
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -1,3 +1,5 @@
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -0,0 +1,3 @@
annotations:
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -1,3 +1,5 @@
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
protect_content:
value: UNSET_PROTECT_CONTENT

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,4 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -2,4 +2,4 @@ bases:
- InlineQueryResult
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -12,4 +12,4 @@ annotations:
category: types
name: InputFile
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -12,4 +12,4 @@ annotations:
category: types
name: InputFile
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -12,4 +12,4 @@ annotations:
category: types
name: InputFile
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -12,4 +12,4 @@ annotations:
category: types
name: InputFile
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -12,4 +12,4 @@ annotations:
category: types
name: InputFile
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE

View file

@ -3,4 +3,6 @@ bases:
annotations:
parse_mode:
value: UNSET
value: UNSET_PARSE_MODE
disable_web_page_preview:
value: UNSET_DISABLE_WEB_PAGE_PREVIEW

2
CHANGES/1142.misc.rst Normal file
View file

@ -0,0 +1,2 @@
Added global defaults `disable_web_page_preview` and `protect_content` in addition to `parse_mode` to the Bot instance,
reworked internal request builder mechanism.

View file

@ -136,7 +136,7 @@ from ..methods import (
UploadStickerFile,
)
from ..types import (
UNSET,
UNSET_PARSE_MODE,
BotCommand,
BotCommandScope,
BotDescription,
@ -186,6 +186,7 @@ from ..types import (
UserProfilePhotos,
WebhookInfo,
)
from ..types.base import UNSET_DISABLE_WEB_PAGE_PREVIEW, UNSET_PROTECT_CONTENT
from .session.aiohttp import AiohttpSession
from .session.base import BaseSession
@ -198,6 +199,8 @@ class Bot(ContextInstanceMixin["Bot"]):
token: str,
session: Optional[BaseSession] = None,
parse_mode: Optional[str] = None,
disable_web_page_preview: Optional[bool] = None,
protect_content: Optional[bool] = None,
) -> None:
"""
Bot class
@ -207,6 +210,10 @@ class Bot(ContextInstanceMixin["Bot"]):
If not specified it will be automatically created.
:param parse_mode: Default parse mode.
If specified it will be propagated into the API methods at runtime.
:param disable_web_page_preview: Default disable_web_page_preview mode.
If specified it will be propagated into the API methods at runtime.
:param protect_content: Default protect_content mode.
If specified it will be propagated into the API methods at runtime.
:raise TokenValidationError: When token has invalid format this exception will be raised
"""
@ -217,6 +224,8 @@ class Bot(ContextInstanceMixin["Bot"]):
self.session = session
self.parse_mode = parse_mode
self.disable_web_page_preview = disable_web_page_preview
self.protect_content = protect_content
self.__token = token
self._me: Optional[User] = None
@ -704,10 +713,10 @@ class Bot(ContextInstanceMixin["Bot"]):
message_id: int,
message_thread_id: Optional[int] = None,
caption: Optional[str] = None,
parse_mode: Optional[str] = UNSET,
parse_mode: Optional[str] = UNSET_PARSE_MODE,
caption_entities: Optional[List[MessageEntity]] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -1188,7 +1197,7 @@ class Bot(ContextInstanceMixin["Bot"]):
message_id: Optional[int] = None,
inline_message_id: Optional[str] = None,
caption: Optional[str] = None,
parse_mode: Optional[str] = UNSET,
parse_mode: Optional[str] = UNSET_PARSE_MODE,
caption_entities: Optional[List[MessageEntity]] = None,
reply_markup: Optional[InlineKeyboardMarkup] = None,
request_timeout: Optional[int] = None,
@ -1331,9 +1340,9 @@ class Bot(ContextInstanceMixin["Bot"]):
chat_id: Optional[Union[int, str]] = None,
message_id: Optional[int] = None,
inline_message_id: Optional[str] = None,
parse_mode: Optional[str] = UNSET,
parse_mode: Optional[str] = UNSET_PARSE_MODE,
entities: Optional[List[MessageEntity]] = None,
disable_web_page_preview: Optional[bool] = None,
disable_web_page_preview: Optional[bool] = UNSET_DISABLE_WEB_PAGE_PREVIEW,
reply_markup: Optional[InlineKeyboardMarkup] = None,
request_timeout: Optional[int] = None,
) -> Union[Message, bool]:
@ -1395,7 +1404,7 @@ class Bot(ContextInstanceMixin["Bot"]):
message_id: int,
message_thread_id: Optional[int] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
request_timeout: Optional[int] = None,
) -> Message:
"""
@ -1995,11 +2004,11 @@ class Bot(ContextInstanceMixin["Bot"]):
height: Optional[int] = None,
thumbnail: Optional[Union[InputFile, str]] = None,
caption: Optional[str] = None,
parse_mode: Optional[str] = UNSET,
parse_mode: Optional[str] = UNSET_PARSE_MODE,
caption_entities: Optional[List[MessageEntity]] = None,
has_spoiler: Optional[bool] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2058,14 +2067,14 @@ class Bot(ContextInstanceMixin["Bot"]):
audio: Union[InputFile, str],
message_thread_id: Optional[int] = None,
caption: Optional[str] = None,
parse_mode: Optional[str] = UNSET,
parse_mode: Optional[str] = UNSET_PARSE_MODE,
caption_entities: Optional[List[MessageEntity]] = None,
duration: Optional[int] = None,
performer: Optional[str] = None,
title: Optional[str] = None,
thumbnail: Optional[Union[InputFile, str]] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2156,7 +2165,7 @@ class Bot(ContextInstanceMixin["Bot"]):
last_name: Optional[str] = None,
vcard: Optional[str] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2205,7 +2214,7 @@ class Bot(ContextInstanceMixin["Bot"]):
message_thread_id: Optional[int] = None,
emoji: Optional[str] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2249,11 +2258,11 @@ class Bot(ContextInstanceMixin["Bot"]):
message_thread_id: Optional[int] = None,
thumbnail: Optional[Union[InputFile, str]] = None,
caption: Optional[str] = None,
parse_mode: Optional[str] = UNSET,
parse_mode: Optional[str] = UNSET_PARSE_MODE,
caption_entities: Optional[List[MessageEntity]] = None,
disable_content_type_detection: Optional[bool] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2306,7 +2315,7 @@ class Bot(ContextInstanceMixin["Bot"]):
game_short_name: str,
message_thread_id: Optional[int] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[InlineKeyboardMarkup] = None,
@ -2367,7 +2376,7 @@ class Bot(ContextInstanceMixin["Bot"]):
send_email_to_provider: Optional[bool] = None,
is_flexible: Optional[bool] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[InlineKeyboardMarkup] = None,
@ -2453,7 +2462,7 @@ class Bot(ContextInstanceMixin["Bot"]):
heading: Optional[int] = None,
proximity_alert_radius: Optional[int] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2506,7 +2515,7 @@ class Bot(ContextInstanceMixin["Bot"]):
media: List[Union[InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo]],
message_thread_id: Optional[int] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
request_timeout: Optional[int] = None,
@ -2543,11 +2552,11 @@ class Bot(ContextInstanceMixin["Bot"]):
chat_id: Union[int, str],
text: str,
message_thread_id: Optional[int] = None,
parse_mode: Optional[str] = UNSET,
parse_mode: Optional[str] = UNSET_PARSE_MODE,
entities: Optional[List[MessageEntity]] = None,
disable_web_page_preview: Optional[bool] = None,
disable_web_page_preview: Optional[bool] = UNSET_DISABLE_WEB_PAGE_PREVIEW,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2596,11 +2605,11 @@ class Bot(ContextInstanceMixin["Bot"]):
photo: Union[InputFile, str],
message_thread_id: Optional[int] = None,
caption: Optional[str] = None,
parse_mode: Optional[str] = UNSET,
parse_mode: Optional[str] = UNSET_PARSE_MODE,
caption_entities: Optional[List[MessageEntity]] = None,
has_spoiler: Optional[bool] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2656,13 +2665,13 @@ class Bot(ContextInstanceMixin["Bot"]):
allows_multiple_answers: Optional[bool] = None,
correct_option_id: Optional[int] = None,
explanation: Optional[str] = None,
explanation_parse_mode: Optional[str] = UNSET,
explanation_parse_mode: Optional[str] = UNSET_PARSE_MODE,
explanation_entities: Optional[List[MessageEntity]] = None,
open_period: Optional[int] = None,
close_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None,
is_closed: Optional[bool] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2728,7 +2737,7 @@ class Bot(ContextInstanceMixin["Bot"]):
message_thread_id: Optional[int] = None,
emoji: Optional[str] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2780,7 +2789,7 @@ class Bot(ContextInstanceMixin["Bot"]):
google_place_id: Optional[str] = None,
google_place_type: Optional[str] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2841,12 +2850,12 @@ class Bot(ContextInstanceMixin["Bot"]):
height: Optional[int] = None,
thumbnail: Optional[Union[InputFile, str]] = None,
caption: Optional[str] = None,
parse_mode: Optional[str] = UNSET,
parse_mode: Optional[str] = UNSET_PARSE_MODE,
caption_entities: Optional[List[MessageEntity]] = None,
has_spoiler: Optional[bool] = None,
supports_streaming: Optional[bool] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2910,7 +2919,7 @@ class Bot(ContextInstanceMixin["Bot"]):
length: Optional[int] = None,
thumbnail: Optional[Union[InputFile, str]] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[
@ -2959,11 +2968,11 @@ class Bot(ContextInstanceMixin["Bot"]):
voice: Union[InputFile, str],
message_thread_id: Optional[int] = None,
caption: Optional[str] = None,
parse_mode: Optional[str] = UNSET,
parse_mode: Optional[str] = UNSET_PARSE_MODE,
caption_entities: Optional[List[MessageEntity]] = None,
duration: Optional[int] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: Optional[bool] = None,
reply_markup: Optional[

View file

@ -19,12 +19,12 @@ from typing import (
import certifi
from aiohttp import BasicAuth, ClientError, ClientSession, FormData, TCPConnector
from aiogram.methods import Request, TelegramMethod
from aiogram.methods import TelegramMethod
from ...exceptions import TelegramNetworkError
from ...methods.base import TelegramType
from ...types import InputFile
from .base import UNSET, BaseSession
from .base import BaseSession
if TYPE_CHECKING:
from ..bot import Bot
@ -130,14 +130,15 @@ class AiohttpSession(BaseSession):
if self._session is not None and not self._session.closed:
await self._session.close()
def build_form_data(self, request: Request) -> FormData:
def build_form_data(self, bot: Bot, method: TelegramMethod[TelegramType]) -> FormData:
form = FormData(quote_fields=False)
for key, value in request.data.items():
if value is None or value is UNSET:
files: Dict[str, InputFile] = {}
for key, value in method.dict().items():
value = self.prepare_value(value, bot=bot, files=files)
if not value:
continue
form.add_field(key, self.prepare_value(value))
if request.files:
for key, value in request.files.items():
form.add_field(key, value)
for key, value in files.items():
form.add_field(key, value, filename=value.filename or key)
return form
@ -146,9 +147,8 @@ class AiohttpSession(BaseSession):
) -> TelegramType:
session = await self.create_session()
request = method.build_request(bot)
url = self.api.api_url(token=bot.token, method=request.method)
form = self.build_form_data(request)
url = self.api.api_url(token=bot.token, method=method.__api_method__)
form = self.build_form_data(bot=bot, method=method)
try:
async with session.post(

View file

@ -3,6 +3,7 @@ from __future__ import annotations
import abc
import datetime
import json
import secrets
from enum import Enum
from http import HTTPStatus
from types import TracebackType
@ -11,10 +12,10 @@ from typing import (
Any,
AsyncGenerator,
Callable,
Dict,
Final,
Optional,
Type,
Union,
cast,
)
@ -37,7 +38,8 @@ from aiogram.exceptions import (
from ...methods import Response, TelegramMethod
from ...methods.base import TelegramType
from ...types import UNSET
from ...types import UNSET_PARSE_MODE, InputFile
from ...types.base import UNSET_DISABLE_WEB_PAGE_PREVIEW, UNSET_PROTECT_CONTENT
from ..telegram import PRODUCTION, TelegramAPIServer
from .middlewares.manager import RequestMiddlewareManager
@ -138,7 +140,10 @@ class BaseSession(abc.ABC):
@abc.abstractmethod
async def make_request(
self, bot: Bot, method: TelegramMethod[TelegramType], timeout: Optional[int] = UNSET
self,
bot: Bot,
method: TelegramMethod[TelegramType],
timeout: Optional[int] = None,
) -> TelegramType: # pragma: no cover
"""
Make request to Telegram Bot API
@ -160,35 +165,81 @@ class BaseSession(abc.ABC):
"""
yield b""
def prepare_value(self, value: Any) -> Union[str, int, bool]:
def prepare_value(
self,
value: Any,
bot: Bot,
files: Dict[str, Any],
_dumps_json: bool = True,
) -> Any:
"""
Prepare value before send
"""
if value is None:
return None
if isinstance(value, str):
return value
if isinstance(value, (list, dict)):
return self.json_dumps(self.clean_json(value))
if value is UNSET_PARSE_MODE:
return self.prepare_value(
bot.parse_mode, bot=bot, files=files, _dumps_json=_dumps_json
)
if value is UNSET_DISABLE_WEB_PAGE_PREVIEW:
return self.prepare_value(
bot.disable_web_page_preview, bot=bot, files=files, _dumps_json=_dumps_json
)
if value is UNSET_PROTECT_CONTENT:
return self.prepare_value(
bot.protect_content, bot=bot, files=files, _dumps_json=_dumps_json
)
if isinstance(value, InputFile):
key = secrets.token_urlsafe(10)
files[key] = value
return f"attach://{key}"
if isinstance(value, dict):
value = {
key: prepared_item
for key, item in value.items()
if (
prepared_item := self.prepare_value(
item, bot=bot, files=files, _dumps_json=False
)
)
is not None
}
if _dumps_json:
return self.json_dumps(value)
return value
if isinstance(value, list):
value = [
prepared_item
for item in value
if (
prepared_item := self.prepare_value(
item, bot=bot, files=files, _dumps_json=False
)
)
is not None
]
if _dumps_json:
return self.json_dumps(value)
return value
if isinstance(value, datetime.timedelta):
now = datetime.datetime.now()
return str(round((now + value).timestamp()))
if isinstance(value, datetime.datetime):
return str(round(value.timestamp()))
if isinstance(value, Enum):
return self.prepare_value(value.value)
return str(value)
return self.prepare_value(value.value, bot=bot, files=files)
def clean_json(self, value: Any) -> Any:
"""
Clean data before send
"""
if isinstance(value, list):
return [self.clean_json(v) for v in value if v is not None]
if isinstance(value, dict):
return {k: self.clean_json(v) for k, v in value.items() if v is not None}
if _dumps_json:
return self.json_dumps(value)
return value
async def __call__(
self, bot: Bot, method: TelegramMethod[TelegramType], timeout: Optional[int] = UNSET
self,
bot: Bot,
method: TelegramMethod[TelegramType],
timeout: Optional[int] = None,
) -> TelegramType:
middleware = self.middleware.wrap_middlewares(self.make_request, timeout=timeout)
return cast(TelegramType, await middleware(bot, method))

View file

@ -15,7 +15,8 @@ from ..fsm.middleware import FSMContextMiddleware
from ..fsm.storage.base import BaseEventIsolation, BaseStorage
from ..fsm.storage.memory import DisabledEventIsolation, MemoryStorage
from ..fsm.strategy import FSMStrategy
from ..methods import GetUpdates, Request, TelegramMethod
from ..methods import GetUpdates, TelegramMethod
from ..methods.base import TelegramType
from ..types import Update, User
from ..types.update import UpdateTypeLookupError
from ..utils.backoff import Backoff, BackoffConfig
@ -364,7 +365,7 @@ class Dispatcher(Router):
async def feed_webhook_update(
self, bot: Bot, update: Union[Update, Dict[str, Any]], _timeout: float = 55, **kwargs: Any
) -> Optional[Request]:
) -> Optional[TelegramMethod[TelegramType]]:
if not isinstance(update, Update): # Allow to use raw updates
update = Update(**update)
@ -410,7 +411,7 @@ class Dispatcher(Router):
# TODO: handle exceptions
response: Any = process_updates.result()
if isinstance(response, TelegramMethod):
return response.build_request(bot=bot)
return response
else:
process_updates.remove_done_callback(release_waiter)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from typing import TYPE_CHECKING
from ..types import InputFile, InputSticker
from .base import Request, TelegramMethod, prepare_input_sticker
if TYPE_CHECKING:
from ..client.bot import Bot
from ..types import InputSticker
from .base import TelegramMethod
class AddStickerToSet(TelegramMethod[bool]):
@ -17,6 +14,7 @@ class AddStickerToSet(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "addStickerToSet"
user_id: int
"""User identifier of sticker set owner"""
@ -24,11 +22,3 @@ class AddStickerToSet(TelegramMethod[bool]):
"""Sticker set name"""
sticker: InputSticker
"""A JSON-serialized object with information about the added sticker. If exactly the same sticker had already been added to the set, then the set isn't changed."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
files: Dict[str, InputFile] = {}
prepare_input_sticker(input_sticker=data["sticker"], files=files)
return Request(method="addStickerToSet", data=data, files=files)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional
from typing import TYPE_CHECKING, Optional
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class AnswerCallbackQuery(TelegramMethod[bool]):
@ -18,6 +15,7 @@ class AnswerCallbackQuery(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "answerCallbackQuery"
callback_query_id: str
"""Unique identifier for the query to be answered"""
@ -29,8 +27,3 @@ class AnswerCallbackQuery(TelegramMethod[bool]):
"""URL that will be opened by the user's client. If you have created a :class:`aiogram.types.game.Game` and accepted the conditions via `@BotFather <https://t.me/botfather>`_, specify the URL that opens your game - note that this will only work if the query comes from a `https://core.telegram.org/bots/api#inlinekeyboardbutton <https://core.telegram.org/bots/api#inlinekeyboardbutton>`_ *callback_game* button."""
cache_time: Optional[int] = None
"""The maximum amount of time in seconds that the result of the callback query may be cached client-side. Telegram apps will support caching starting in version 3.14. Defaults to 0."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="answerCallbackQuery", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from typing import TYPE_CHECKING, List, Optional
from ..types import InlineQueryResult
from .base import Request, TelegramMethod, prepare_parse_mode
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class AnswerInlineQuery(TelegramMethod[bool]):
@ -19,6 +16,7 @@ class AnswerInlineQuery(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "answerInlineQuery"
inline_query_id: str
"""Unique identifier for the answered query"""
@ -34,15 +32,3 @@ class AnswerInlineQuery(TelegramMethod[bool]):
"""If passed, clients will display a button with specified text that switches the user to a private chat with the bot and sends the bot a start message with the parameter *switch_pm_parameter*"""
switch_pm_parameter: Optional[str] = None
"""`Deep-linking <https://core.telegram.org/bots/features#deep-linking>`_ parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
input_message_contents = []
for result in data["results"]:
input_message_content = result.get("input_message_content", None)
if input_message_content is not None:
input_message_contents.append(input_message_content)
prepare_parse_mode(bot, data["results"] + input_message_contents)
return Request(method="answerInlineQuery", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional
from typing import TYPE_CHECKING, Optional
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class AnswerPreCheckoutQuery(TelegramMethod[bool]):
@ -16,6 +13,7 @@ class AnswerPreCheckoutQuery(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "answerPreCheckoutQuery"
pre_checkout_query_id: str
"""Unique identifier for the query to be answered"""
@ -23,8 +21,3 @@ class AnswerPreCheckoutQuery(TelegramMethod[bool]):
"""Specify :code:`True` if everything is alright (goods are available, etc.) and the bot is ready to proceed with the order. Use :code:`False` if there are any problems."""
error_message: Optional[str] = None
"""Required if *ok* is :code:`False`. Error message in human readable form that explains the reason for failure to proceed with the checkout (e.g. "Sorry, somebody just bought the last of our amazing black T-shirts while you were busy filling out your payment details. Please choose a different color or garment!"). Telegram will display this message to the user."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="answerPreCheckoutQuery", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from typing import TYPE_CHECKING, List, Optional
from ..types import ShippingOption
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class AnswerShippingQuery(TelegramMethod[bool]):
@ -17,6 +14,7 @@ class AnswerShippingQuery(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "answerShippingQuery"
shipping_query_id: str
"""Unique identifier for the query to be answered"""
@ -26,8 +24,3 @@ class AnswerShippingQuery(TelegramMethod[bool]):
"""Required if *ok* is :code:`True`. A JSON-serialized array of available shipping options."""
error_message: Optional[str] = None
"""Required if *ok* is :code:`False`. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="answerShippingQuery", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from typing import TYPE_CHECKING
from ..types import InlineQueryResult, SentWebAppMessage
from .base import Request, TelegramMethod, prepare_parse_mode
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class AnswerWebAppQuery(TelegramMethod[SentWebAppMessage]):
@ -17,17 +14,9 @@ class AnswerWebAppQuery(TelegramMethod[SentWebAppMessage]):
"""
__returning__ = SentWebAppMessage
__api_method__ = "answerWebAppQuery"
web_app_query_id: str
"""Unique identifier for the query to be answered"""
result: InlineQueryResult
"""A JSON-serialized object describing the message to be sent"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
prepare_parse_mode(
bot, data["result"], parse_mode_property="parse_mode", entities_property="entities"
)
return Request(method="answerWebAppQuery", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class ApproveChatJoinRequest(TelegramMethod[bool]):
@ -16,13 +13,9 @@ class ApproveChatJoinRequest(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "approveChatJoinRequest"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
user_id: int
"""Unique identifier of the target user"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="approveChatJoinRequest", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
import datetime
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Optional, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class BanChatMember(TelegramMethod[bool]):
@ -17,6 +14,7 @@ class BanChatMember(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "banChatMember"
chat_id: Union[int, str]
"""Unique identifier for the target group or username of the target supergroup or channel (in the format :code:`@channelusername`)"""
@ -26,8 +24,3 @@ class BanChatMember(TelegramMethod[bool]):
"""Date when the user will be unbanned, unix time. If user is banned for more than 366 days or less than 30 seconds from the current time they are considered to be banned forever. Applied for supergroups and channels only."""
revoke_messages: Optional[bool] = None
"""Pass :code:`True` to delete all messages from the chat for the user that is being removed. If :code:`False`, the user will be able to see messages in the group that were sent before the user was removed. Always :code:`True` for supergroups and channels."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="banChatMember", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class BanChatSenderChat(TelegramMethod[bool]):
@ -16,13 +13,9 @@ class BanChatSenderChat(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "banChatSenderChat"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
sender_chat_id: int
"""Unique identifier of the target sender chat"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="banChatSenderChat", data=data)

View file

@ -1,22 +1,13 @@
from __future__ import annotations
import abc
import secrets
from typing import (
TYPE_CHECKING,
Any,
Dict,
Generator,
Generic,
Optional,
TypeVar,
Union,
)
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Dict, Generator, Generic, Optional, TypeVar
from pydantic import BaseConfig, BaseModel, Extra, root_validator
from pydantic.generics import GenericModel
from ..types import UNSET, InputFile, ResponseParameters
from ..types import InputFile, ResponseParameters
from ..types.base import UNSET_TYPE
if TYPE_CHECKING:
from ..client.bot import Bot
@ -42,7 +33,7 @@ class Response(GenericModel, Generic[TelegramType]):
parameters: Optional[ResponseParameters] = None
class TelegramMethod(abc.ABC, BaseModel, Generic[TelegramType]):
class TelegramMethod(ABC, BaseModel, Generic[TelegramType]):
class Config(BaseConfig):
# use_enum_values = True
extra = Extra.allow
@ -54,25 +45,23 @@ class TelegramMethod(abc.ABC, BaseModel, Generic[TelegramType]):
@root_validator(pre=True)
def remove_unset(cls, values: Dict[str, Any]) -> Dict[str, Any]:
"""
Remove UNSET from `parse_mode` before fields validation.
Remove UNSET before fields validation.
We use UNSET as a sentinel value for `parse_mode` and replace it to real value later.
It isn't a problem when it's just default value for a model field, but UNSET might be passing to
a model initialization from `Bot.method_name`, so we must take care of it and
remove it before fields validation.
It isn't a problem when it's just default value for a model field,
but UNSET might be passing to a model initialization from `Bot.method_name`,
so we must take care of it and remove it before fields validation.
"""
for parse_mode_attribute in {"parse_mode", "explanation_parse_mode"}:
if parse_mode_attribute in values and values[parse_mode_attribute] is UNSET:
values.pop(parse_mode_attribute)
return values
return {k: v for k, v in values.items() if not isinstance(v, UNSET_TYPE)}
@property
@abc.abstractmethod
@abstractmethod
def __returning__(self) -> type: # pragma: no cover
pass
@abc.abstractmethod
def build_request(self, bot: Bot) -> Request: # pragma: no cover
@property
@abstractmethod
def __api_method__(self) -> str:
pass
def dict(self, **kwargs: Any) -> Any:
@ -95,84 +84,3 @@ class TelegramMethod(abc.ABC, BaseModel, Generic[TelegramType]):
bot = Bot.get_current(no_error=False)
return self.emit(bot).__await__()
def prepare_file(name: str, value: Any, data: Dict[str, Any], files: Dict[str, Any]) -> None:
if not value:
return
if name == "thumbnail":
tag = secrets.token_urlsafe(10)
files[tag] = value
data["thumbnail"] = f"attach://{tag}"
elif isinstance(value, InputFile):
files[name] = value
else:
data[name] = value
def prepare_input_media(data: Dict[str, Any], files: Dict[str, InputFile]) -> None:
for input_media in data.get("media", []): # type: Dict[str, Union[str, InputFile]]
if (
"media" in input_media
and input_media["media"]
and isinstance(input_media["media"], InputFile)
):
tag = secrets.token_urlsafe(10)
files[tag] = input_media.pop("media") # type: ignore
input_media["media"] = f"attach://{tag}"
def prepare_input_sticker(input_sticker: Dict[str, Any], files: Dict[str, InputFile]) -> None:
if (
"sticker" in input_sticker
and input_sticker["sticker"]
and isinstance(input_sticker["sticker"], InputFile)
):
tag = secrets.token_urlsafe(10)
files[tag] = input_sticker.pop("sticker")
input_sticker["sticker"] = f"attach://{tag}"
def prepare_input_stickers(data: Dict[str, Any], files: Dict[str, InputFile]) -> None:
for input_sticker in data["stickers"]:
prepare_input_sticker(input_sticker, files=files)
def prepare_media_file(data: Dict[str, Any], files: Dict[str, InputFile]) -> None:
if (
data["media"]
and "media" in data["media"]
and isinstance(data["media"]["media"], InputFile)
):
tag = secrets.token_urlsafe(10)
files[tag] = data["media"].pop("media")
data["media"]["media"] = f"attach://{tag}"
def prepare_parse_mode(
bot: Bot,
root: Any,
parse_mode_property: str = "parse_mode",
entities_property: str = "entities",
) -> None:
"""
Find and set parse_mode with highest priority.
Developer can manually set parse_mode for each message (or message-like) object,
but if parse_mode was unset we should use value from Bot object.
We can't use None for "unset state", because None itself is the parse_mode option.
"""
if isinstance(root, list):
for item in root:
prepare_parse_mode(
bot=bot,
root=item,
parse_mode_property=parse_mode_property,
entities_property=entities_property,
)
elif root.get(parse_mode_property, UNSET) is UNSET:
if bot.parse_mode and root.get(entities_property, None) is None:
root[parse_mode_property] = bot.parse_mode
else:
root[parse_mode_property] = None

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from typing import TYPE_CHECKING
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class Close(TelegramMethod[bool]):
@ -16,8 +13,4 @@ class Close(TelegramMethod[bool]):
"""
__returning__ = bool
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="close", data=data)
__api_method__ = "close"

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class CloseForumTopic(TelegramMethod[bool]):
@ -16,13 +13,9 @@ class CloseForumTopic(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "closeForumTopic"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
message_thread_id: int
"""Unique identifier for the target message thread of the forum topic"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="closeForumTopic", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class CloseGeneralForumTopic(TelegramMethod[bool]):
@ -16,11 +13,7 @@ class CloseGeneralForumTopic(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "closeGeneralForumTopic"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="closeGeneralForumTopic", data=data)

View file

@ -1,9 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from typing import TYPE_CHECKING, List, Optional, Union
from ..types import (
UNSET,
UNSET_PARSE_MODE,
ForceReply,
InlineKeyboardMarkup,
MessageEntity,
@ -11,10 +11,8 @@ from ..types import (
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
)
from .base import Request, TelegramMethod, prepare_parse_mode
if TYPE_CHECKING:
from ..client.bot import Bot
from ..types.base import UNSET_PROTECT_CONTENT
from .base import TelegramMethod
class CopyMessage(TelegramMethod[MessageId]):
@ -25,6 +23,7 @@ class CopyMessage(TelegramMethod[MessageId]):
"""
__returning__ = MessageId
__api_method__ = "copyMessage"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
@ -36,13 +35,13 @@ class CopyMessage(TelegramMethod[MessageId]):
"""Unique identifier for the target message thread (topic) of the forum; for forum supergroups only"""
caption: Optional[str] = None
"""New caption for media, 0-1024 characters after entities parsing. If not specified, the original caption is kept"""
parse_mode: Optional[str] = UNSET
parse_mode: Optional[str] = UNSET_PARSE_MODE
"""Mode for parsing entities in the new caption. See `formatting options <https://core.telegram.org/bots/api#formatting-options>`_ for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""A JSON-serialized list of special entities that appear in the new caption, which can be specified instead of *parse_mode*"""
disable_notification: Optional[bool] = None
"""Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound."""
protect_content: Optional[bool] = None
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT
"""Protects the contents of the sent message from forwarding and saving"""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
@ -52,12 +51,3 @@ class CopyMessage(TelegramMethod[MessageId]):
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None
"""Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots/features#inline-keyboards>`_, `custom reply keyboard <https://core.telegram.org/bots/features#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="caption_entities"
)
return Request(method="copyMessage", data=data)

View file

@ -1,13 +1,10 @@
from __future__ import annotations
import datetime
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Optional, Union
from ..types import ChatInviteLink
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class CreateChatInviteLink(TelegramMethod[ChatInviteLink]):
@ -18,6 +15,7 @@ class CreateChatInviteLink(TelegramMethod[ChatInviteLink]):
"""
__returning__ = ChatInviteLink
__api_method__ = "createChatInviteLink"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
@ -29,8 +27,3 @@ class CreateChatInviteLink(TelegramMethod[ChatInviteLink]):
"""The maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999"""
creates_join_request: Optional[bool] = None
""":code:`True`, if users joining the chat via the link need to be approved by chat administrators. If :code:`True`, *member_limit* can't be specified"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="createChatInviteLink", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Optional, Union
from ..types import ForumTopic
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class CreateForumTopic(TelegramMethod[ForumTopic]):
@ -17,6 +14,7 @@ class CreateForumTopic(TelegramMethod[ForumTopic]):
"""
__returning__ = ForumTopic
__api_method__ = "createForumTopic"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
@ -26,8 +24,3 @@ class CreateForumTopic(TelegramMethod[ForumTopic]):
"""Color of the topic icon in RGB format. Currently, must be one of 7322096 (0x6FB9F0), 16766590 (0xFFD67E), 13338331 (0xCB86DB), 9367192 (0x8EEE98), 16749490 (0xFF93B2), or 16478047 (0xFB6F5F)"""
icon_custom_emoji_id: Optional[str] = None
"""Unique identifier of the custom emoji shown as the topic icon. Use :class:`aiogram.methods.get_forum_topic_icon_stickers.GetForumTopicIconStickers` to get all allowed custom emoji identifiers."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="createForumTopic", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from typing import TYPE_CHECKING, List, Optional
from ..types import LabeledPrice
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class CreateInvoiceLink(TelegramMethod[str]):
@ -17,6 +14,7 @@ class CreateInvoiceLink(TelegramMethod[str]):
"""
__returning__ = str
__api_method__ = "createInvoiceLink"
title: str
"""Product name, 1-32 characters"""
@ -58,8 +56,3 @@ class CreateInvoiceLink(TelegramMethod[str]):
"""Pass :code:`True` if the user's email address should be sent to the provider"""
is_flexible: Optional[bool] = None
"""Pass :code:`True` if the final price depends on the shipping method"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="createInvoiceLink", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from typing import TYPE_CHECKING, List, Optional
from ..types import InputFile, InputSticker
from .base import Request, TelegramMethod, prepare_input_sticker, prepare_input_stickers
if TYPE_CHECKING:
from ..client.bot import Bot
from ..types import InputSticker
from .base import TelegramMethod
class CreateNewStickerSet(TelegramMethod[bool]):
@ -17,6 +14,7 @@ class CreateNewStickerSet(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "createNewStickerSet"
user_id: int
"""User identifier of created sticker set owner"""
@ -32,11 +30,3 @@ class CreateNewStickerSet(TelegramMethod[bool]):
"""Type of stickers in the set, pass 'regular', 'mask', or 'custom_emoji'. By default, a regular sticker set is created."""
needs_repainting: Optional[bool] = None
"""Pass :code:`True` if stickers in the sticker set must be repainted to the color of text when used in messages, the accent color if used as emoji status, white on chat photos, or another appropriate color based on context; for custom emoji sticker sets only"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
files: Dict[str, InputFile] = {}
prepare_input_stickers(data=data, files=files)
return Request(method="createNewStickerSet", data=data, files=files)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class DeclineChatJoinRequest(TelegramMethod[bool]):
@ -16,13 +13,9 @@ class DeclineChatJoinRequest(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "declineChatJoinRequest"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
user_id: int
"""Unique identifier of the target user"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="declineChatJoinRequest", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class DeleteChatPhoto(TelegramMethod[bool]):
@ -16,11 +13,7 @@ class DeleteChatPhoto(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "deleteChatPhoto"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="deleteChatPhoto", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class DeleteChatStickerSet(TelegramMethod[bool]):
@ -16,11 +13,7 @@ class DeleteChatStickerSet(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "deleteChatStickerSet"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="deleteChatStickerSet", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class DeleteForumTopic(TelegramMethod[bool]):
@ -16,13 +13,9 @@ class DeleteForumTopic(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "deleteForumTopic"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
message_thread_id: int
"""Unique identifier for the target message thread of the forum topic"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="deleteForumTopic", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class DeleteMessage(TelegramMethod[bool]):
@ -34,13 +31,9 @@ class DeleteMessage(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "deleteMessage"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
message_id: int
"""Identifier of the message to delete"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="deleteMessage", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional
from typing import TYPE_CHECKING, Optional
from ..types import BotCommandScope
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class DeleteMyCommands(TelegramMethod[bool]):
@ -17,13 +14,9 @@ class DeleteMyCommands(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "deleteMyCommands"
scope: Optional[BotCommandScope] = None
"""A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`."""
language_code: Optional[str] = None
"""A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="deleteMyCommands", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from typing import TYPE_CHECKING
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class DeleteStickerFromSet(TelegramMethod[bool]):
@ -16,11 +13,7 @@ class DeleteStickerFromSet(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "deleteStickerFromSet"
sticker: str
"""File identifier of the sticker"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="deleteStickerFromSet", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from typing import TYPE_CHECKING
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class DeleteStickerSet(TelegramMethod[bool]):
@ -16,11 +13,7 @@ class DeleteStickerSet(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "deleteStickerSet"
name: str
"""Sticker set name"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="deleteStickerSet", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional
from typing import TYPE_CHECKING, Optional
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class DeleteWebhook(TelegramMethod[bool]):
@ -16,11 +13,7 @@ class DeleteWebhook(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "deleteWebhook"
drop_pending_updates: Optional[bool] = None
"""Pass :code:`True` to drop all pending updates"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="deleteWebhook", data=data)

View file

@ -1,13 +1,10 @@
from __future__ import annotations
import datetime
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Optional, Union
from ..types import ChatInviteLink
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class EditChatInviteLink(TelegramMethod[ChatInviteLink]):
@ -18,6 +15,7 @@ class EditChatInviteLink(TelegramMethod[ChatInviteLink]):
"""
__returning__ = ChatInviteLink
__api_method__ = "editChatInviteLink"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
@ -31,8 +29,3 @@ class EditChatInviteLink(TelegramMethod[ChatInviteLink]):
"""The maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999"""
creates_join_request: Optional[bool] = None
""":code:`True`, if users joining the chat via the link need to be approved by chat administrators. If :code:`True`, *member_limit* can't be specified"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="editChatInviteLink", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Optional, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class EditForumTopic(TelegramMethod[bool]):
@ -16,6 +13,7 @@ class EditForumTopic(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "editForumTopic"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
@ -25,8 +23,3 @@ class EditForumTopic(TelegramMethod[bool]):
"""New topic name, 0-128 characters. If not specified or empty, the current name of the topic will be kept"""
icon_custom_emoji_id: Optional[str] = None
"""New unique identifier of the custom emoji shown as the topic icon. Use :class:`aiogram.methods.get_forum_topic_icon_stickers.GetForumTopicIconStickers` to get all allowed custom emoji identifiers. Pass an empty string to remove the icon. If not specified, the current icon will be kept"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="editForumTopic", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class EditGeneralForumTopic(TelegramMethod[bool]):
@ -16,13 +13,9 @@ class EditGeneralForumTopic(TelegramMethod[bool]):
"""
__returning__ = bool
__api_method__ = "editGeneralForumTopic"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
name: str
"""New topic name, 1-128 characters"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="editGeneralForumTopic", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from typing import TYPE_CHECKING, List, Optional, Union
from ..types import UNSET, InlineKeyboardMarkup, Message, MessageEntity
from .base import Request, TelegramMethod, prepare_parse_mode
if TYPE_CHECKING:
from ..client.bot import Bot
from ..types import UNSET_PARSE_MODE, InlineKeyboardMarkup, Message, MessageEntity
from .base import TelegramMethod
class EditMessageCaption(TelegramMethod[Union[Message, bool]]):
@ -17,6 +14,7 @@ class EditMessageCaption(TelegramMethod[Union[Message, bool]]):
"""
__returning__ = Union[Message, bool]
__api_method__ = "editMessageCaption"
chat_id: Optional[Union[int, str]] = None
"""Required if *inline_message_id* is not specified. Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
@ -26,18 +24,9 @@ class EditMessageCaption(TelegramMethod[Union[Message, bool]]):
"""Required if *chat_id* and *message_id* are not specified. Identifier of the inline message"""
caption: Optional[str] = None
"""New caption of the message, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
parse_mode: Optional[str] = UNSET_PARSE_MODE
"""Mode for parsing entities in the message caption. See `formatting options <https://core.telegram.org/bots/api#formatting-options>`_ for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode*"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots/features#inline-keyboards>`_."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="caption_entities"
)
return Request(method="editMessageCaption", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Optional, Union
from ..types import InlineKeyboardMarkup, Message
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class EditMessageLiveLocation(TelegramMethod[Union[Message, bool]]):
@ -17,6 +14,7 @@ class EditMessageLiveLocation(TelegramMethod[Union[Message, bool]]):
"""
__returning__ = Union[Message, bool]
__api_method__ = "editMessageLiveLocation"
latitude: float
"""Latitude of new location"""
@ -36,8 +34,3 @@ class EditMessageLiveLocation(TelegramMethod[Union[Message, bool]]):
"""The maximum distance for proximity alerts about approaching another chat member, in meters. Must be between 1 and 100000 if specified."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for a new `inline keyboard <https://core.telegram.org/bots/features#inline-keyboards>`_."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="editMessageLiveLocation", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Optional, Union
from ..types import InlineKeyboardMarkup, InputFile, InputMedia, Message
from .base import Request, TelegramMethod, prepare_media_file, prepare_parse_mode
if TYPE_CHECKING:
from ..client.bot import Bot
from ..types import InlineKeyboardMarkup, InputMedia, Message
from .base import TelegramMethod
class EditMessageMedia(TelegramMethod[Union[Message, bool]]):
@ -17,6 +14,7 @@ class EditMessageMedia(TelegramMethod[Union[Message, bool]]):
"""
__returning__ = Union[Message, bool]
__api_method__ = "editMessageMedia"
media: InputMedia
"""A JSON-serialized object for a new media content of the message"""
@ -28,11 +26,3 @@ class EditMessageMedia(TelegramMethod[Union[Message, bool]]):
"""Required if *chat_id* and *message_id* are not specified. Identifier of the inline message"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for a new `inline keyboard <https://core.telegram.org/bots/features#inline-keyboards>`_."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
prepare_parse_mode(bot, data["media"])
files: Dict[str, InputFile] = {}
prepare_media_file(data=data, files=files)
return Request(method="editMessageMedia", data=data, files=files)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Optional, Union
from ..types import InlineKeyboardMarkup, Message
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class EditMessageReplyMarkup(TelegramMethod[Union[Message, bool]]):
@ -17,6 +14,7 @@ class EditMessageReplyMarkup(TelegramMethod[Union[Message, bool]]):
"""
__returning__ = Union[Message, bool]
__api_method__ = "editMessageReplyMarkup"
chat_id: Optional[Union[int, str]] = None
"""Required if *inline_message_id* is not specified. Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
@ -26,8 +24,3 @@ class EditMessageReplyMarkup(TelegramMethod[Union[Message, bool]]):
"""Required if *chat_id* and *message_id* are not specified. Identifier of the inline message"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots/features#inline-keyboards>`_."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="editMessageReplyMarkup", data=data)

View file

@ -1,12 +1,10 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from typing import TYPE_CHECKING, List, Optional, Union
from ..types import UNSET, InlineKeyboardMarkup, Message, MessageEntity
from .base import Request, TelegramMethod, prepare_parse_mode
if TYPE_CHECKING:
from ..client.bot import Bot
from ..types import UNSET_PARSE_MODE, InlineKeyboardMarkup, Message, MessageEntity
from ..types.base import UNSET_DISABLE_WEB_PAGE_PREVIEW
from .base import TelegramMethod
class EditMessageText(TelegramMethod[Union[Message, bool]]):
@ -17,6 +15,7 @@ class EditMessageText(TelegramMethod[Union[Message, bool]]):
"""
__returning__ = Union[Message, bool]
__api_method__ = "editMessageText"
text: str
"""New text of the message, 1-4096 characters after entities parsing"""
@ -26,20 +25,11 @@ class EditMessageText(TelegramMethod[Union[Message, bool]]):
"""Required if *inline_message_id* is not specified. Identifier of the message to edit"""
inline_message_id: Optional[str] = None
"""Required if *chat_id* and *message_id* are not specified. Identifier of the inline message"""
parse_mode: Optional[str] = UNSET
parse_mode: Optional[str] = UNSET_PARSE_MODE
"""Mode for parsing entities in the message text. See `formatting options <https://core.telegram.org/bots/api#formatting-options>`_ for more details."""
entities: Optional[List[MessageEntity]] = None
"""A JSON-serialized list of special entities that appear in message text, which can be specified instead of *parse_mode*"""
disable_web_page_preview: Optional[bool] = None
disable_web_page_preview: Optional[bool] = UNSET_DISABLE_WEB_PAGE_PREVIEW
"""Disables link previews for links in this message"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots/features#inline-keyboards>`_."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="entities"
)
return Request(method="editMessageText", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class ExportChatInviteLink(TelegramMethod[str]):
@ -18,11 +15,7 @@ class ExportChatInviteLink(TelegramMethod[str]):
"""
__returning__ = str
__api_method__ = "exportChatInviteLink"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="exportChatInviteLink", data=data)

View file

@ -1,12 +1,10 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Optional, Union
from ..types import Message
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from ..types.base import UNSET_PROTECT_CONTENT
from .base import TelegramMethod
class ForwardMessage(TelegramMethod[Message]):
@ -17,6 +15,7 @@ class ForwardMessage(TelegramMethod[Message]):
"""
__returning__ = Message
__api_method__ = "forwardMessage"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
@ -28,10 +27,5 @@ class ForwardMessage(TelegramMethod[Message]):
"""Unique identifier for the target message thread (topic) of the forum; for forum supergroups only"""
disable_notification: Optional[bool] = None
"""Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound."""
protect_content: Optional[bool] = None
protect_content: Optional[bool] = UNSET_PROTECT_CONTENT
"""Protects the contents of the forwarded message from forwarding and saving"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="forwardMessage", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from ..types import Chat
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetChat(TelegramMethod[Chat]):
@ -17,11 +14,7 @@ class GetChat(TelegramMethod[Chat]):
"""
__returning__ = Chat
__api_method__ = "getChat"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup or channel (in the format :code:`@channelusername`)"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getChat", data=data)

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Union
from typing import TYPE_CHECKING, List, Union
from ..types import (
ChatMemberAdministrator,
@ -10,10 +10,7 @@ from ..types import (
ChatMemberOwner,
ChatMemberRestricted,
)
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetChatAdministrators(
@ -46,11 +43,7 @@ class GetChatAdministrators(
ChatMemberBanned,
]
]
__api_method__ = "getChatAdministrators"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup or channel (in the format :code:`@channelusername`)"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getChatAdministrators", data=data)

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from ..types import (
ChatMemberAdministrator,
@ -10,10 +10,7 @@ from ..types import (
ChatMemberOwner,
ChatMemberRestricted,
)
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetChatMember(
@ -42,13 +39,9 @@ class GetChatMember(
ChatMemberLeft,
ChatMemberBanned,
]
__api_method__ = "getChatMember"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup or channel (in the format :code:`@channelusername`)"""
user_id: int
"""Unique identifier of the target user"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getChatMember", data=data)

View file

@ -1,11 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetChatMemberCount(TelegramMethod[int]):
@ -16,11 +13,7 @@ class GetChatMemberCount(TelegramMethod[int]):
"""
__returning__ = int
__api_method__ = "getChatMemberCount"
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target supergroup or channel (in the format :code:`@channelusername`)"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getChatMemberCount", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Optional, Union
from ..types import MenuButtonCommands, MenuButtonDefault, MenuButtonWebApp
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetChatMenuButton(
@ -19,11 +16,7 @@ class GetChatMenuButton(
"""
__returning__ = Union[MenuButtonDefault, MenuButtonWebApp, MenuButtonCommands]
__api_method__ = "getChatMenuButton"
chat_id: Optional[int] = None
"""Unique identifier for the target private chat. If not specified, default bot's menu button will be returned"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getChatMenuButton", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List
from typing import TYPE_CHECKING, List
from ..types import Sticker
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetCustomEmojiStickers(TelegramMethod[List[Sticker]]):
@ -17,11 +14,7 @@ class GetCustomEmojiStickers(TelegramMethod[List[Sticker]]):
"""
__returning__ = List[Sticker]
__api_method__ = "getCustomEmojiStickers"
custom_emoji_ids: List[str]
"""List of custom emoji identifiers. At most 200 custom emoji identifiers can be specified."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getCustomEmojiStickers", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from typing import TYPE_CHECKING
from ..types import File
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetFile(TelegramMethod[File]):
@ -18,11 +15,7 @@ class GetFile(TelegramMethod[File]):
"""
__returning__ = File
__api_method__ = "getFile"
file_id: str
"""File identifier to get information about"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getFile", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List
from typing import TYPE_CHECKING, List
from ..types import Sticker
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetForumTopicIconStickers(TelegramMethod[List[Sticker]]):
@ -17,8 +14,4 @@ class GetForumTopicIconStickers(TelegramMethod[List[Sticker]]):
"""
__returning__ = List[Sticker]
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getForumTopicIconStickers", data=data)
__api_method__ = "getForumTopicIconStickers"

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from typing import TYPE_CHECKING, List, Optional
from ..types import GameHighScore
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetGameHighScores(TelegramMethod[List[GameHighScore]]):
@ -19,6 +16,7 @@ class GetGameHighScores(TelegramMethod[List[GameHighScore]]):
"""
__returning__ = List[GameHighScore]
__api_method__ = "getGameHighScores"
user_id: int
"""Target user id"""
@ -28,8 +26,3 @@ class GetGameHighScores(TelegramMethod[List[GameHighScore]]):
"""Required if *inline_message_id* is not specified. Identifier of the sent message"""
inline_message_id: Optional[str] = None
"""Required if *chat_id* and *message_id* are not specified. Identifier of the inline message"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getGameHighScores", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from typing import TYPE_CHECKING
from ..types import User
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetMe(TelegramMethod[User]):
@ -17,8 +14,4 @@ class GetMe(TelegramMethod[User]):
"""
__returning__ = User
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getMe", data=data)
__api_method__ = "getMe"

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from typing import TYPE_CHECKING, List, Optional
from ..types import BotCommand, BotCommandScope
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetMyCommands(TelegramMethod[List[BotCommand]]):
@ -17,13 +14,9 @@ class GetMyCommands(TelegramMethod[List[BotCommand]]):
"""
__returning__ = List[BotCommand]
__api_method__ = "getMyCommands"
scope: Optional[BotCommandScope] = None
"""A JSON-serialized object, describing scope of users. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`."""
language_code: Optional[str] = None
"""A two-letter ISO 639-1 language code or an empty string"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getMyCommands", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional
from typing import TYPE_CHECKING, Optional
from ..types import ChatAdministratorRights
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetMyDefaultAdministratorRights(TelegramMethod[ChatAdministratorRights]):
@ -17,11 +14,7 @@ class GetMyDefaultAdministratorRights(TelegramMethod[ChatAdministratorRights]):
"""
__returning__ = ChatAdministratorRights
__api_method__ = "getMyDefaultAdministratorRights"
for_channels: Optional[bool] = None
"""Pass :code:`True` to get default administrator rights of the bot in channels. Otherwise, default administrator rights of the bot for groups and supergroups will be returned."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getMyDefaultAdministratorRights", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional
from typing import TYPE_CHECKING, Optional
from ..types import BotDescription
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetMyDescription(TelegramMethod[BotDescription]):
@ -17,11 +14,7 @@ class GetMyDescription(TelegramMethod[BotDescription]):
"""
__returning__ = BotDescription
__api_method__ = "getMyDescription"
language_code: Optional[str] = None
"""A two-letter ISO 639-1 language code or an empty string"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getMyDescription", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional
from typing import TYPE_CHECKING, Optional
from ..types import BotShortDescription
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetMyShortDescription(TelegramMethod[BotShortDescription]):
@ -17,11 +14,7 @@ class GetMyShortDescription(TelegramMethod[BotShortDescription]):
"""
__returning__ = BotShortDescription
__api_method__ = "getMyShortDescription"
language_code: Optional[str] = None
"""A two-letter ISO 639-1 language code or an empty string"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getMyShortDescription", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from typing import TYPE_CHECKING
from ..types import StickerSet
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetStickerSet(TelegramMethod[StickerSet]):
@ -17,11 +14,7 @@ class GetStickerSet(TelegramMethod[StickerSet]):
"""
__returning__ = StickerSet
__api_method__ = "getStickerSet"
name: str
"""Name of the sticker set"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getStickerSet", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from typing import TYPE_CHECKING, List, Optional
from ..types import Update
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetUpdates(TelegramMethod[List[Update]]):
@ -23,6 +20,7 @@ class GetUpdates(TelegramMethod[List[Update]]):
"""
__returning__ = List[Update]
__api_method__ = "getUpdates"
offset: Optional[int] = None
"""Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as :class:`aiogram.methods.get_updates.GetUpdates` is called with an *offset* higher than its *update_id*. The negative offset can be specified to retrieve updates starting from *-offset* update from the end of the updates queue. All previous updates will forgotten."""
@ -32,8 +30,3 @@ class GetUpdates(TelegramMethod[List[Update]]):
"""Timeout in seconds for long polling. Defaults to 0, i.e. usual short polling. Should be positive, short polling should be used for testing purposes only."""
allowed_updates: Optional[List[str]] = None
"""A JSON-serialized list of the update types you want your bot to receive. For example, specify ['message', 'edited_channel_post', 'callback_query'] to only receive updates of these types. See :class:`aiogram.types.update.Update` for a complete list of available update types. Specify an empty list to receive all update types except *chat_member* (default). If not specified, the previous setting will be used."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getUpdates", data=data)

View file

@ -1,12 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional
from typing import TYPE_CHECKING, Optional
from ..types import UserProfilePhotos
from .base import Request, TelegramMethod
if TYPE_CHECKING:
from ..client.bot import Bot
from .base import TelegramMethod
class GetUserProfilePhotos(TelegramMethod[UserProfilePhotos]):
@ -17,6 +14,7 @@ class GetUserProfilePhotos(TelegramMethod[UserProfilePhotos]):
"""
__returning__ = UserProfilePhotos
__api_method__ = "getUserProfilePhotos"
user_id: int
"""Unique identifier of the target user"""
@ -24,8 +22,3 @@ class GetUserProfilePhotos(TelegramMethod[UserProfilePhotos]):
"""Sequential number of the first photo to be returned. By default, all photos are returned."""
limit: Optional[int] = None
"""Limits the number of photos to be retrieved. Values between 1-100 are accepted. Defaults to 100."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="getUserProfilePhotos", data=data)

Some files were not shown because too many files have changed in this diff Show more