From 7844a663a983a599c79a6bee06fcb5a4323fc0b3 Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Sun, 14 Jun 2020 17:14:10 +0300 Subject: [PATCH] Bump Telegram Bot API version Change request timeout mechanism Bump package version --- .apiversion | 2 +- aiogram/__init__.py | 4 +- aiogram/api/client/bot.py | 434 ++++++++++++------ aiogram/api/client/session/aiohttp.py | 8 +- aiogram/api/client/session/base.py | 7 +- aiogram/api/methods/answer_inline_query.py | 4 +- aiogram/api/methods/base.py | 4 - aiogram/api/methods/edit_message_caption.py | 3 +- aiogram/api/methods/edit_message_text.py | 3 +- aiogram/api/methods/pin_chat_message.py | 4 +- aiogram/api/methods/send_animation.py | 8 +- aiogram/api/methods/send_audio.py | 7 +- aiogram/api/methods/send_dice.py | 9 +- aiogram/api/methods/send_document.py | 7 +- aiogram/api/methods/send_game.py | 2 +- aiogram/api/methods/send_message.py | 3 +- aiogram/api/methods/send_photo.py | 3 +- aiogram/api/methods/send_video.py | 7 +- aiogram/api/methods/send_video_note.py | 4 +- aiogram/api/methods/send_voice.py | 4 +- aiogram/api/methods/set_webhook.py | 6 +- aiogram/api/methods/unpin_chat_message.py | 4 +- aiogram/api/types/base.py | 1 - aiogram/api/types/chat_member.py | 3 +- aiogram/api/types/dice.py | 6 +- aiogram/api/types/force_reply.py | 16 +- aiogram/api/types/game_high_score.py | 2 +- aiogram/api/types/inline_keyboard_button.py | 8 +- .../api/types/inline_query_result_audio.py | 3 +- .../types/inline_query_result_cached_audio.py | 3 +- .../inline_query_result_cached_document.py | 3 +- .../types/inline_query_result_cached_gif.py | 3 +- .../inline_query_result_cached_mpeg4_gif.py | 3 +- .../types/inline_query_result_cached_photo.py | 3 +- .../types/inline_query_result_cached_video.py | 3 +- .../types/inline_query_result_cached_voice.py | 4 +- .../api/types/inline_query_result_document.py | 3 +- aiogram/api/types/inline_query_result_gif.py | 8 +- .../types/inline_query_result_mpeg4_gif.py | 8 +- .../api/types/inline_query_result_photo.py | 3 +- .../api/types/inline_query_result_video.py | 3 +- .../api/types/inline_query_result_voice.py | 4 +- aiogram/api/types/input_media_animation.py | 8 +- aiogram/api/types/input_media_audio.py | 7 +- aiogram/api/types/input_media_document.py | 7 +- aiogram/api/types/input_media_photo.py | 3 +- aiogram/api/types/input_media_video.py | 7 +- .../api/types/input_text_message_content.py | 3 +- aiogram/api/types/message.py | 43 +- aiogram/api/types/update.py | 4 +- aiogram/api/types/user.py | 6 +- docs/_api_version.md | 2 +- docs/_package_version.md | 2 +- poetry.lock | 153 +++--- pyproject.toml | 2 +- tests/mocked_bot.py | 5 +- .../test_session/test_base_session.py | 5 +- tests/test_api/test_types/test_chat_member.py | 11 +- 58 files changed, 526 insertions(+), 369 deletions(-) diff --git a/.apiversion b/.apiversion index b6afe802..899dd4f5 100644 --- a/.apiversion +++ b/.apiversion @@ -1 +1 @@ -4.8 \ No newline at end of file +4.9 \ No newline at end of file diff --git a/aiogram/__init__.py b/aiogram/__init__.py index 0b2a8cc7..435b4eaf 100644 --- a/aiogram/__init__.py +++ b/aiogram/__init__.py @@ -28,5 +28,5 @@ __all__ = ( "handler", ) -__version__ = "3.0.0a4" -__api_version__ = "4.8" +__version__ = "3.0.0a5" +__api_version__ = "4.9" diff --git a/aiogram/api/client/bot.py b/aiogram/api/client/bot.py index 0d2bf1d9..673356d9 100644 --- a/aiogram/api/client/bot.py +++ b/aiogram/api/client/bot.py @@ -269,7 +269,9 @@ class Bot(ContextInstanceMixin["Bot"]): file_path, destination=destination, timeout=timeout, chunk_size=chunk_size, seek=seek ) - async def __call__(self, method: TelegramMethod[T]) -> T: + async def __call__( + self, method: TelegramMethod[T], request_timeout: Optional[int] = None + ) -> T: """ Call API method @@ -308,6 +310,7 @@ class Bot(ContextInstanceMixin["Bot"]): limit: Optional[int] = None, timeout: Optional[int] = None, allowed_updates: Optional[List[str]] = None, + request_timeout: Optional[int] = None, ) -> List[Update]: """ Use this method to receive incoming updates using long polling (wiki). An Array of Update @@ -337,12 +340,13 @@ class Bot(ContextInstanceMixin["Bot"]): Update for a complete list of available update types. Specify an empty list to receive all updates regardless of type (default). If not specified, the previous setting will be used. + :param request_timeout: Request timeout :return: An Array of Update objects is returned. """ call = GetUpdates( offset=offset, limit=limit, timeout=timeout, allowed_updates=allowed_updates, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def set_webhook( self, @@ -350,6 +354,7 @@ class Bot(ContextInstanceMixin["Bot"]): certificate: Optional[InputFile] = None, max_connections: Optional[int] = None, allowed_updates: Optional[List[str]] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to specify a url and receive incoming updates via an outgoing webhook. @@ -358,7 +363,7 @@ class Bot(ContextInstanceMixin["Bot"]): will give up after a reasonable amount of attempts. Returns True on success. If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the URL, e.g. https://www.example.com/. Since nobody else - knows your bot‘s token, you can be pretty sure it’s us. + knows your bot's token, you can be pretty sure it's us. Notes 1. You will not be able to receive updates using getUpdates for as long as an outgoing webhook is set up. @@ -376,14 +381,15 @@ class Bot(ContextInstanceMixin["Bot"]): can be checked. See our self-signed guide for details. :param max_connections: Maximum allowed number of simultaneous HTTPS connections to the webhook for update delivery, 1-100. Defaults to 40. Use lower - values to limit the load on your bot‘s server, and higher values - to increase your bot’s throughput. + values to limit the load on your bot's server, and higher values + to increase your bot's throughput. :param allowed_updates: 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 Update for a complete list of available update types. Specify an empty list to receive all updates regardless of type (default). If not specified, the previous setting will be used. + :param request_timeout: Request timeout :return: Returns True on success. """ call = SetWebhook( @@ -392,21 +398,22 @@ class Bot(ContextInstanceMixin["Bot"]): max_connections=max_connections, allowed_updates=allowed_updates, ) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def delete_webhook(self,) -> bool: + async def delete_webhook(self, request_timeout: Optional[int] = None,) -> bool: """ Use this method to remove webhook integration if you decide to switch back to getUpdates. Returns True on success. Requires no parameters. Source: https://core.telegram.org/bots/api#deletewebhook + :param request_timeout: Request timeout :return: Returns True on success. """ call = DeleteWebhook() - return await self(call) + return await self(call, request_timeout=request_timeout) - async def get_webhook_info(self,) -> WebhookInfo: + async def get_webhook_info(self, request_timeout: Optional[int] = None,) -> WebhookInfo: """ Use this method to get current webhook status. Requires no parameters. On success, returns a WebhookInfo object. If the bot is using getUpdates, will return an object with the url @@ -414,28 +421,30 @@ class Bot(ContextInstanceMixin["Bot"]): Source: https://core.telegram.org/bots/api#getwebhookinfo + :param request_timeout: Request timeout :return: On success, returns a WebhookInfo object. If the bot is using getUpdates, will return an object with the url field empty. """ call = GetWebhookInfo() - return await self(call) + return await self(call, request_timeout=request_timeout) # ============================================================================================= # Group: Available methods # Source: https://core.telegram.org/bots/api#available-methods # ============================================================================================= - async def get_me(self,) -> User: + async def get_me(self, request_timeout: Optional[int] = None,) -> User: """ A simple method for testing your bot's auth token. Requires no parameters. Returns basic information about the bot in form of a User object. Source: https://core.telegram.org/bots/api#getme + :param request_timeout: Request timeout :return: Returns basic information about the bot in form of a User object. """ call = GetMe() - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_message( self, @@ -448,6 +457,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send text messages. On success, the sent Message is returned. @@ -466,6 +476,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendMessage( @@ -477,7 +488,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def forward_message( self, @@ -485,6 +496,7 @@ class Bot(ContextInstanceMixin["Bot"]): from_chat_id: Union[int, str], message_id: int, disable_notification: Optional[bool] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to forward messages of any kind. On success, the sent Message is returned. @@ -498,6 +510,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param message_id: Message identifier in the chat specified in from_chat_id :param disable_notification: Sends the message silently. Users will receive a notification with no sound. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = ForwardMessage( @@ -506,7 +519,7 @@ class Bot(ContextInstanceMixin["Bot"]): message_id=message_id, disable_notification=disable_notification, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_photo( self, @@ -519,6 +532,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send photos. On success, the sent Message is returned. @@ -541,6 +555,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendPhoto( @@ -552,7 +567,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_audio( self, @@ -569,6 +584,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send audio files, if you want Telegram clients to display them in the @@ -593,9 +609,9 @@ class Bot(ContextInstanceMixin["Bot"]): :param title: Track name :param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and - less than 200 kB in size. A thumbnail‘s width and height should not exceed + less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. - Thumbnails can’t be reused and can be only uploaded as a new file, so you + Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under . :param disable_notification: Sends the message silently. Users will receive a notification @@ -604,6 +620,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendAudio( @@ -619,7 +636,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_document( self, @@ -633,6 +650,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send general files. On success, the sent Message is returned. Bots can @@ -649,9 +667,9 @@ class Bot(ContextInstanceMixin["Bot"]): multipart/form-data. :param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and - less than 200 kB in size. A thumbnail‘s width and height should not exceed + less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. - Thumbnails can’t be reused and can be only uploaded as a new file, so you + Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under . :param caption: Document caption (may also be used when resending documents by file_id), @@ -664,6 +682,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendDocument( @@ -676,7 +695,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_video( self, @@ -694,6 +713,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send video files, Telegram clients support mp4 videos (other formats @@ -713,9 +733,9 @@ class Bot(ContextInstanceMixin["Bot"]): :param height: Video height :param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and - less than 200 kB in size. A thumbnail‘s width and height should not exceed + less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. - Thumbnails can’t be reused and can be only uploaded as a new file, so you + Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under . :param caption: Video caption (may also be used when resending videos by file_id), 0-1024 @@ -729,6 +749,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendVideo( @@ -745,7 +766,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_animation( self, @@ -762,6 +783,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound). On @@ -781,9 +803,9 @@ class Bot(ContextInstanceMixin["Bot"]): :param height: Animation height :param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and - less than 200 kB in size. A thumbnail‘s width and height should not exceed + less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. - Thumbnails can’t be reused and can be only uploaded as a new file, so you + Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under . :param caption: Animation caption (may also be used when resending animation by file_id), @@ -796,6 +818,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendAnimation( @@ -811,7 +834,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_voice( self, @@ -825,6 +848,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send audio files, if you want Telegram clients to display the file as a @@ -851,6 +875,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendVoice( @@ -863,7 +888,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_video_note( self, @@ -877,6 +902,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long. @@ -894,9 +920,9 @@ class Bot(ContextInstanceMixin["Bot"]): :param length: Video width and height, i.e. diameter of the video message :param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and - less than 200 kB in size. A thumbnail‘s width and height should not exceed + less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. - Thumbnails can’t be reused and can be only uploaded as a new file, so you + Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under . :param disable_notification: Sends the message silently. Users will receive a notification @@ -905,6 +931,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendVideoNote( @@ -917,7 +944,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_media_group( self, @@ -925,6 +952,7 @@ class Bot(ContextInstanceMixin["Bot"]): media: List[Union[InputMediaPhoto, InputMediaVideo]], disable_notification: Optional[bool] = None, reply_to_message_id: Optional[int] = None, + request_timeout: Optional[int] = None, ) -> List[Message]: """ Use this method to send a group of photos or videos as an album. On success, an array of @@ -939,6 +967,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param disable_notification: Sends the messages silently. Users will receive a notification with no sound. :param reply_to_message_id: If the messages are a reply, ID of the original message + :param request_timeout: Request timeout :return: On success, an array of the sent Messages is returned. """ call = SendMediaGroup( @@ -947,7 +976,7 @@ class Bot(ContextInstanceMixin["Bot"]): disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_location( self, @@ -960,6 +989,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send point on the map. On success, the sent Message is returned. @@ -978,6 +1008,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendLocation( @@ -989,7 +1020,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def edit_message_live_location( self, @@ -999,6 +1030,7 @@ class Bot(ContextInstanceMixin["Bot"]): message_id: Optional[int] = None, inline_message_id: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, + request_timeout: Optional[int] = None, ) -> Union[Message, bool]: """ Use this method to edit live location messages. A location can be edited until its @@ -1018,6 +1050,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message :param reply_markup: A JSON-serialized object for a new inline keyboard. + :param request_timeout: Request timeout :return: On success, if the edited message was sent by the bot, the edited Message is returned, otherwise True is returned. """ @@ -1029,7 +1062,7 @@ class Bot(ContextInstanceMixin["Bot"]): inline_message_id=inline_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def stop_message_live_location( self, @@ -1037,6 +1070,7 @@ class Bot(ContextInstanceMixin["Bot"]): message_id: Optional[int] = None, inline_message_id: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, + request_timeout: Optional[int] = None, ) -> Union[Message, bool]: """ Use this method to stop updating a live location message before live_period expires. On @@ -1053,6 +1087,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message :param reply_markup: A JSON-serialized object for a new inline keyboard. + :param request_timeout: Request timeout :return: On success, if the message was sent by the bot, the sent Message is returned, otherwise True is returned. """ @@ -1062,7 +1097,7 @@ class Bot(ContextInstanceMixin["Bot"]): inline_message_id=inline_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_venue( self, @@ -1078,6 +1113,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send information about a venue. On success, the sent Message is @@ -1101,6 +1137,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendVenue( @@ -1115,7 +1152,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_contact( self, @@ -1129,6 +1166,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send phone contacts. On success, the sent Message is returned. @@ -1147,6 +1185,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendContact( @@ -1159,7 +1198,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_poll( self, @@ -1180,6 +1219,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send a native poll. On success, the sent Message is returned. @@ -1215,6 +1255,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendPoll( @@ -1234,7 +1275,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def send_dice( self, @@ -1245,24 +1286,26 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ - Use this method to send a dice, which will have a random value from 1 to 6. On success, - the sent Message is returned. (Yes, we're aware of the 'proper' singular of die. But it's - awkward, and we decided to help it change. One dice at a time!) + Use this method to send an animated emoji that will display a random value. On success, + the sent Message is returned. Source: https://core.telegram.org/bots/api#senddice :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername) :param emoji: Emoji on which the dice throw animation is based. Currently, must be one of - '' or ''. Defauts to '' + '', '', or ''. Dice can have values 1-6 for '' and '', and values 1-5 for + ''. Defaults to '' :param disable_notification: Sends the message silently. Users will receive a notification with no sound. :param reply_to_message_id: If the message is a reply, ID of the original message :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendDice( @@ -1272,9 +1315,11 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def send_chat_action(self, chat_id: Union[int, str], action: str,) -> bool: + async def send_chat_action( + self, chat_id: Union[int, str], action: str, request_timeout: Optional[int] = None, + ) -> bool: """ Use this method when you need to tell the user that something is happening on the bot's side. The status is set for 5 seconds or less (when a message arrives from your bot, @@ -1295,13 +1340,18 @@ class Bot(ContextInstanceMixin["Bot"]): record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for location data, record_video_note or upload_video_note for video notes. + :param request_timeout: Request timeout :return: Returns True on success. """ call = SendChatAction(chat_id=chat_id, action=action,) - return await self(call) + return await self(call, request_timeout=request_timeout) async def get_user_profile_photos( - self, user_id: int, offset: Optional[int] = None, limit: Optional[int] = None, + self, + user_id: int, + offset: Optional[int] = None, + limit: Optional[int] = None, + request_timeout: Optional[int] = None, ) -> UserProfilePhotos: """ Use this method to get a list of profile pictures for a user. Returns a UserProfilePhotos @@ -1314,12 +1364,13 @@ class Bot(ContextInstanceMixin["Bot"]): are returned. :param limit: Limits the number of photos to be retrieved. Values between 1-100 are accepted. Defaults to 100. + :param request_timeout: Request timeout :return: Returns a UserProfilePhotos object. """ call = GetUserProfilePhotos(user_id=user_id, offset=offset, limit=limit,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def get_file(self, file_id: str,) -> File: + async def get_file(self, file_id: str, request_timeout: Optional[int] = None,) -> File: """ Use this method to get basic info about a file and prepare it for downloading. For the moment, bots can download files of up to 20MB in size. On success, a File object is @@ -1333,16 +1384,18 @@ class Bot(ContextInstanceMixin["Bot"]): Source: https://core.telegram.org/bots/api#getfile :param file_id: File identifier to get info about + :param request_timeout: Request timeout :return: On success, a File object is returned. """ call = GetFile(file_id=file_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) async def kick_chat_member( self, chat_id: Union[int, str], user_id: int, until_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to kick a user from a group, a supergroup or a channel. In the case of @@ -1358,13 +1411,16 @@ class Bot(ContextInstanceMixin["Bot"]): :param until_date: 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 + :param request_timeout: Request timeout :return: In the case of supergroups and channels, the user will not be able to return to the group on their own using invite links, etc. Returns True on success. """ call = KickChatMember(chat_id=chat_id, user_id=user_id, until_date=until_date,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def unban_chat_member(self, chat_id: Union[int, str], user_id: int,) -> bool: + async def unban_chat_member( + self, chat_id: Union[int, str], user_id: int, request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to unban a previously kicked user in a supergroup or channel. The user will not return to the group or channel automatically, but will be able to join via link, @@ -1375,11 +1431,12 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target group or username of the target supergroup or channel (in the format @username) :param user_id: Unique identifier of the target user + :param request_timeout: Request timeout :return: The user will not return to the group or channel automatically, but will be able to join via link, etc. Returns True on success. """ call = UnbanChatMember(chat_id=chat_id, user_id=user_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) async def restrict_chat_member( self, @@ -1387,6 +1444,7 @@ class Bot(ContextInstanceMixin["Bot"]): user_id: int, permissions: ChatPermissions, until_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to restrict a user in a supergroup. The bot must be an administrator in @@ -1402,12 +1460,13 @@ class Bot(ContextInstanceMixin["Bot"]): :param until_date: Date when restrictions will be lifted for the user, unix time. If user is restricted for more than 366 days or less than 30 seconds from the current time, they are considered to be restricted forever + :param request_timeout: Request timeout :return: Returns True on success. """ call = RestrictChatMember( chat_id=chat_id, user_id=user_id, permissions=permissions, until_date=until_date, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def promote_chat_member( self, @@ -1421,6 +1480,7 @@ class Bot(ContextInstanceMixin["Bot"]): can_restrict_members: Optional[bool] = None, can_pin_messages: Optional[bool] = None, can_promote_members: Optional[bool] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to promote or demote a user in a supergroup or a channel. The bot must be @@ -1449,6 +1509,7 @@ class Bot(ContextInstanceMixin["Bot"]): with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him) + :param request_timeout: Request timeout :return: Returns True on success. """ call = PromoteChatMember( @@ -1463,10 +1524,14 @@ class Bot(ContextInstanceMixin["Bot"]): can_pin_messages=can_pin_messages, can_promote_members=can_promote_members, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def set_chat_administrator_custom_title( - self, chat_id: Union[int, str], user_id: int, custom_title: str, + self, + chat_id: Union[int, str], + user_id: int, + custom_title: str, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to set a custom title for an administrator in a supergroup promoted by the @@ -1479,15 +1544,19 @@ class Bot(ContextInstanceMixin["Bot"]): :param user_id: Unique identifier of the target user :param custom_title: New custom title for the administrator; 0-16 characters, emoji are not allowed + :param request_timeout: Request timeout :return: Returns True on success. """ call = SetChatAdministratorCustomTitle( chat_id=chat_id, user_id=user_id, custom_title=custom_title, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def set_chat_permissions( - self, chat_id: Union[int, str], permissions: ChatPermissions, + self, + chat_id: Union[int, str], + permissions: ChatPermissions, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to set default chat permissions for all members. The bot must be an @@ -1499,12 +1568,15 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername) :param permissions: New default chat permissions + :param request_timeout: Request timeout :return: Returns True on success. """ call = SetChatPermissions(chat_id=chat_id, permissions=permissions,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def export_chat_invite_link(self, chat_id: Union[int, str],) -> str: + async def export_chat_invite_link( + self, chat_id: Union[int, str], request_timeout: Optional[int] = None, + ) -> str: """ Use this method to generate a new invite link for a chat; any previously generated link is revoked. The bot must be an administrator in the chat for this to work and must have the @@ -1519,12 +1591,15 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername) + :param request_timeout: Request timeout :return: Returns the new invite link as String on success. """ call = ExportChatInviteLink(chat_id=chat_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def set_chat_photo(self, chat_id: Union[int, str], photo: InputFile,) -> bool: + async def set_chat_photo( + self, chat_id: Union[int, str], photo: InputFile, request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have @@ -1535,12 +1610,15 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername) :param photo: New chat photo, uploaded using multipart/form-data + :param request_timeout: Request timeout :return: Returns True on success. """ call = SetChatPhoto(chat_id=chat_id, photo=photo,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def delete_chat_photo(self, chat_id: Union[int, str],) -> bool: + async def delete_chat_photo( + self, chat_id: Union[int, str], request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to delete a chat photo. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin @@ -1550,12 +1628,15 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername) + :param request_timeout: Request timeout :return: Returns True on success. """ call = DeleteChatPhoto(chat_id=chat_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def set_chat_title(self, chat_id: Union[int, str], title: str,) -> bool: + async def set_chat_title( + self, chat_id: Union[int, str], title: str, request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to change the title of a chat. Titles can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the @@ -1566,13 +1647,17 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername) :param title: New chat title, 1-255 characters + :param request_timeout: Request timeout :return: Returns True on success. """ call = SetChatTitle(chat_id=chat_id, title=title,) - return await self(call) + return await self(call, request_timeout=request_timeout) async def set_chat_description( - self, chat_id: Union[int, str], description: Optional[str] = None, + self, + chat_id: Union[int, str], + description: Optional[str] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to change the description of a group, a supergroup or a channel. The bot @@ -1584,21 +1669,23 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername) :param description: New chat description, 0-255 characters + :param request_timeout: Request timeout :return: Returns True on success. """ call = SetChatDescription(chat_id=chat_id, description=description,) - return await self(call) + return await self(call, request_timeout=request_timeout) async def pin_chat_message( self, chat_id: Union[int, str], message_id: int, disable_notification: Optional[bool] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to pin a message in a group, a supergroup, or a channel. The bot must be - an administrator in the chat for this to work and must have the ‘can_pin_messages’ admin - right in the supergroup or ‘can_edit_messages’ admin right in the channel. Returns True on + an administrator in the chat for this to work and must have the 'can_pin_messages' admin + right in the supergroup or 'can_edit_messages' admin right in the channel. Returns True on success. Source: https://core.telegram.org/bots/api#pinchatmessage @@ -1609,30 +1696,36 @@ class Bot(ContextInstanceMixin["Bot"]): :param disable_notification: Pass True, if it is not necessary to send a notification to all chat members about the new pinned message. Notifications are always disabled in channels. + :param request_timeout: Request timeout :return: Returns True on success. """ call = PinChatMessage( chat_id=chat_id, message_id=message_id, disable_notification=disable_notification, ) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def unpin_chat_message(self, chat_id: Union[int, str],) -> bool: + async def unpin_chat_message( + self, chat_id: Union[int, str], request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to unpin a message in a group, a supergroup, or a channel. The bot must be - an administrator in the chat for this to work and must have the ‘can_pin_messages’ admin - right in the supergroup or ‘can_edit_messages’ admin right in the channel. Returns True on + an administrator in the chat for this to work and must have the 'can_pin_messages' admin + right in the supergroup or 'can_edit_messages' admin right in the channel. Returns True on success. Source: https://core.telegram.org/bots/api#unpinchatmessage :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername) + :param request_timeout: Request timeout :return: Returns True on success. """ call = UnpinChatMessage(chat_id=chat_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def leave_chat(self, chat_id: Union[int, str],) -> bool: + async def leave_chat( + self, chat_id: Union[int, str], request_timeout: Optional[int] = None, + ) -> bool: """ Use this method for your bot to leave a group, supergroup or channel. Returns True on success. @@ -1641,12 +1734,15 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format @channelusername) + :param request_timeout: Request timeout :return: Returns True on success. """ call = LeaveChat(chat_id=chat_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def get_chat(self, chat_id: Union[int, str],) -> Chat: + async def get_chat( + self, chat_id: Union[int, str], request_timeout: Optional[int] = None, + ) -> Chat: """ Use this method to get up to date information about the chat (current name of the user for one-on-one conversations, current username of a user, group or channel, etc.). Returns a @@ -1656,12 +1752,15 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format @channelusername) + :param request_timeout: Request timeout :return: Returns a Chat object on success. """ call = GetChat(chat_id=chat_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def get_chat_administrators(self, chat_id: Union[int, str],) -> List[ChatMember]: + async def get_chat_administrators( + self, chat_id: Union[int, str], request_timeout: Optional[int] = None, + ) -> List[ChatMember]: """ Use this method to get a list of administrators in a chat. On success, returns an Array of ChatMember objects that contains information about all chat administrators except other @@ -1672,15 +1771,18 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format @channelusername) + :param request_timeout: Request timeout :return: On success, returns an Array of ChatMember objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned. """ call = GetChatAdministrators(chat_id=chat_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def get_chat_members_count(self, chat_id: Union[int, str],) -> int: + async def get_chat_members_count( + self, chat_id: Union[int, str], request_timeout: Optional[int] = None, + ) -> int: """ Use this method to get the number of members in a chat. Returns Int on success. @@ -1688,12 +1790,15 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format @channelusername) + :param request_timeout: Request timeout :return: Returns Int on success. """ call = GetChatMembersCount(chat_id=chat_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def get_chat_member(self, chat_id: Union[int, str], user_id: int,) -> ChatMember: + async def get_chat_member( + self, chat_id: Union[int, str], user_id: int, request_timeout: Optional[int] = None, + ) -> ChatMember: """ Use this method to get information about a member of a chat. Returns a ChatMember object on success. @@ -1703,12 +1808,18 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format @channelusername) :param user_id: Unique identifier of the target user + :param request_timeout: Request timeout :return: Returns a ChatMember object on success. """ call = GetChatMember(chat_id=chat_id, user_id=user_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def set_chat_sticker_set(self, chat_id: Union[int, str], sticker_set_name: str,) -> bool: + async def set_chat_sticker_set( + self, + chat_id: Union[int, str], + sticker_set_name: str, + request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to set a new group sticker set for a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Use @@ -1720,13 +1831,16 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername) :param sticker_set_name: Name of the sticker set to be set as the group sticker set + :param request_timeout: Request timeout :return: Use the field can_set_sticker_set optionally returned in getChat requests to check if the bot can use this method. Returns True on success. """ call = SetChatStickerSet(chat_id=chat_id, sticker_set_name=sticker_set_name,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def delete_chat_sticker_set(self, chat_id: Union[int, str],) -> bool: + async def delete_chat_sticker_set( + self, chat_id: Union[int, str], request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to delete a group sticker set from a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Use @@ -1737,11 +1851,12 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername) + :param request_timeout: Request timeout :return: Use the field can_set_sticker_set optionally returned in getChat requests to check if the bot can use this method. Returns True on success. """ call = DeleteChatStickerSet(chat_id=chat_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) async def answer_callback_query( self, @@ -1750,6 +1865,7 @@ class Bot(ContextInstanceMixin["Bot"]): show_alert: Optional[bool] = None, url: Optional[str] = None, cache_time: Optional[int] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to send answers to callback queries sent from inline keyboards. The answer @@ -1773,6 +1889,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param cache_time: 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. + :param request_timeout: Request timeout :return: On success, True is returned. """ call = AnswerCallbackQuery( @@ -1782,9 +1899,11 @@ class Bot(ContextInstanceMixin["Bot"]): url=url, cache_time=cache_time, ) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def set_my_commands(self, commands: List[BotCommand],) -> bool: + async def set_my_commands( + self, commands: List[BotCommand], request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to change the list of the bot's commands. Returns True on success. @@ -1792,22 +1911,24 @@ class Bot(ContextInstanceMixin["Bot"]): :param commands: A JSON-serialized list of bot commands to be set as the list of the bot's commands. At most 100 commands can be specified. + :param request_timeout: Request timeout :return: Returns True on success. """ call = SetMyCommands(commands=commands,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def get_my_commands(self,) -> List[BotCommand]: + async def get_my_commands(self, request_timeout: Optional[int] = None,) -> List[BotCommand]: """ Use this method to get the current list of the bot's commands. Requires no parameters. Returns Array of BotCommand on success. Source: https://core.telegram.org/bots/api#getmycommands + :param request_timeout: Request timeout :return: Returns Array of BotCommand on success. """ call = GetMyCommands() - return await self(call) + return await self(call, request_timeout=request_timeout) # ============================================================================================= # Group: Updating messages @@ -1823,6 +1944,7 @@ class Bot(ContextInstanceMixin["Bot"]): parse_mode: Optional[str] = UNSET, disable_web_page_preview: Optional[bool] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, + request_timeout: Optional[int] = None, ) -> Union[Message, bool]: """ Use this method to edit text and game messages. On success, if edited message is sent by @@ -1842,6 +1964,7 @@ class Bot(ContextInstanceMixin["Bot"]): for more details. :param disable_web_page_preview: Disables link previews for links in this message :param reply_markup: A JSON-serialized object for an inline keyboard. + :param request_timeout: Request timeout :return: On success, if edited message is sent by the bot, the edited Message is returned, otherwise True is returned. """ @@ -1854,7 +1977,7 @@ class Bot(ContextInstanceMixin["Bot"]): disable_web_page_preview=disable_web_page_preview, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def edit_message_caption( self, @@ -1864,6 +1987,7 @@ class Bot(ContextInstanceMixin["Bot"]): caption: Optional[str] = None, parse_mode: Optional[str] = UNSET, reply_markup: Optional[InlineKeyboardMarkup] = None, + request_timeout: Optional[int] = None, ) -> Union[Message, bool]: """ Use this method to edit captions of messages. On success, if edited message is sent by the @@ -1882,6 +2006,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param parse_mode: Mode for parsing entities in the message caption. See formatting options for more details. :param reply_markup: A JSON-serialized object for an inline keyboard. + :param request_timeout: Request timeout :return: On success, if edited message is sent by the bot, the edited Message is returned, otherwise True is returned. """ @@ -1893,7 +2018,7 @@ class Bot(ContextInstanceMixin["Bot"]): parse_mode=parse_mode, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def edit_message_media( self, @@ -1902,6 +2027,7 @@ class Bot(ContextInstanceMixin["Bot"]): message_id: Optional[int] = None, inline_message_id: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, + request_timeout: Optional[int] = None, ) -> Union[Message, bool]: """ Use this method to edit animation, audio, document, photo, or video messages. If a message @@ -1922,6 +2048,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message :param reply_markup: A JSON-serialized object for a new inline keyboard. + :param request_timeout: Request timeout :return: On success, if the edited message was sent by the bot, the edited Message is returned, otherwise True is returned. """ @@ -1932,7 +2059,7 @@ class Bot(ContextInstanceMixin["Bot"]): inline_message_id=inline_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def edit_message_reply_markup( self, @@ -1940,6 +2067,7 @@ class Bot(ContextInstanceMixin["Bot"]): message_id: Optional[int] = None, inline_message_id: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, + request_timeout: Optional[int] = None, ) -> Union[Message, bool]: """ Use this method to edit only the reply markup of messages. On success, if edited message @@ -1955,6 +2083,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message :param reply_markup: A JSON-serialized object for an inline keyboard. + :param request_timeout: Request timeout :return: On success, if edited message is sent by the bot, the edited Message is returned, otherwise True is returned. """ @@ -1964,13 +2093,14 @@ class Bot(ContextInstanceMixin["Bot"]): inline_message_id=inline_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def stop_poll( self, chat_id: Union[int, str], message_id: int, reply_markup: Optional[InlineKeyboardMarkup] = None, + request_timeout: Optional[int] = None, ) -> Poll: """ Use this method to stop a poll which was sent by the bot. On success, the stopped Poll @@ -1982,12 +2112,15 @@ class Bot(ContextInstanceMixin["Bot"]): (in the format @channelusername) :param message_id: Identifier of the original message with the poll :param reply_markup: A JSON-serialized object for a new message inline keyboard. + :param request_timeout: Request timeout :return: On success, the stopped Poll with the final results is returned. """ call = StopPoll(chat_id=chat_id, message_id=message_id, reply_markup=reply_markup,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def delete_message(self, chat_id: Union[int, str], message_id: int,) -> bool: + async def delete_message( + self, chat_id: Union[int, str], message_id: int, request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to delete a message, including service messages, with the following limitations: @@ -2007,10 +2140,11 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername) :param message_id: Identifier of the message to delete + :param request_timeout: Request timeout :return: Returns True on success. """ call = DeleteMessage(chat_id=chat_id, message_id=message_id,) - return await self(call) + return await self(call, request_timeout=request_timeout) # ============================================================================================= # Group: Stickers @@ -2026,6 +2160,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_markup: Optional[ Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply] ] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send static .WEBP or animated .TGS stickers. On success, the sent @@ -2045,6 +2180,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendSticker( @@ -2054,21 +2190,26 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def get_sticker_set(self, name: str,) -> StickerSet: + async def get_sticker_set( + self, name: str, request_timeout: Optional[int] = None, + ) -> StickerSet: """ Use this method to get a sticker set. On success, a StickerSet object is returned. Source: https://core.telegram.org/bots/api#getstickerset :param name: Name of the sticker set + :param request_timeout: Request timeout :return: On success, a StickerSet object is returned. """ call = GetStickerSet(name=name,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def upload_sticker_file(self, user_id: int, png_sticker: InputFile,) -> File: + async def upload_sticker_file( + self, user_id: int, png_sticker: InputFile, request_timeout: Optional[int] = None, + ) -> File: """ Use this method to upload a .PNG file with a sticker for later use in createNewStickerSet and addStickerToSet methods (can be used multiple times). Returns the uploaded File on @@ -2080,10 +2221,11 @@ class Bot(ContextInstanceMixin["Bot"]): :param png_sticker: PNG image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. + :param request_timeout: Request timeout :return: Returns the uploaded File on success. """ call = UploadStickerFile(user_id=user_id, png_sticker=png_sticker,) - return await self(call) + return await self(call, request_timeout=request_timeout) async def create_new_sticker_set( self, @@ -2095,6 +2237,7 @@ class Bot(ContextInstanceMixin["Bot"]): tgs_sticker: Optional[InputFile] = None, contains_masks: Optional[bool] = None, mask_position: Optional[MaskPosition] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to create a new sticker set owned by a user. The bot will be able to edit @@ -2122,6 +2265,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param contains_masks: Pass True, if a set of mask stickers should be created :param mask_position: A JSON-serialized object for position where the mask should be placed on faces + :param request_timeout: Request timeout :return: Returns True on success. """ call = CreateNewStickerSet( @@ -2134,7 +2278,7 @@ class Bot(ContextInstanceMixin["Bot"]): contains_masks=contains_masks, mask_position=mask_position, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def add_sticker_to_set( self, @@ -2144,6 +2288,7 @@ class Bot(ContextInstanceMixin["Bot"]): png_sticker: Optional[Union[InputFile, str]] = None, tgs_sticker: Optional[InputFile] = None, mask_position: Optional[MaskPosition] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to add a new sticker to a set created by the bot. You must use exactly one @@ -2167,6 +2312,7 @@ class Bot(ContextInstanceMixin["Bot"]): for technical requirements :param mask_position: A JSON-serialized object for position where the mask should be placed on faces + :param request_timeout: Request timeout :return: Returns True on success. """ call = AddStickerToSet( @@ -2177,9 +2323,11 @@ class Bot(ContextInstanceMixin["Bot"]): tgs_sticker=tgs_sticker, mask_position=mask_position, ) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def set_sticker_position_in_set(self, sticker: str, position: int,) -> bool: + async def set_sticker_position_in_set( + self, sticker: str, position: int, request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to move a sticker in a set created by the bot to a specific position. Returns True on success. @@ -2188,12 +2336,15 @@ class Bot(ContextInstanceMixin["Bot"]): :param sticker: File identifier of the sticker :param position: New sticker position in the set, zero-based + :param request_timeout: Request timeout :return: Returns True on success. """ call = SetStickerPositionInSet(sticker=sticker, position=position,) - return await self(call) + return await self(call, request_timeout=request_timeout) - async def delete_sticker_from_set(self, sticker: str,) -> bool: + async def delete_sticker_from_set( + self, sticker: str, request_timeout: Optional[int] = None, + ) -> bool: """ Use this method to delete a sticker from a set created by the bot. Returns True on success. @@ -2201,13 +2352,18 @@ class Bot(ContextInstanceMixin["Bot"]): Source: https://core.telegram.org/bots/api#deletestickerfromset :param sticker: File identifier of the sticker + :param request_timeout: Request timeout :return: Returns True on success. """ call = DeleteStickerFromSet(sticker=sticker,) - return await self(call) + return await self(call, request_timeout=request_timeout) async def set_sticker_set_thumb( - self, name: str, user_id: int, thumb: Optional[Union[InputFile, str]] = None, + self, + name: str, + user_id: int, + thumb: Optional[Union[InputFile, str]] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to set the thumbnail of a sticker set. Animated thumbnails can be set for @@ -2226,10 +2382,11 @@ class Bot(ContextInstanceMixin["Bot"]): String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data.. Animated sticker set thumbnail can't be uploaded via HTTP URL. + :param request_timeout: Request timeout :return: Returns True on success. """ call = SetStickerSetThumb(name=name, user_id=user_id, thumb=thumb,) - return await self(call) + return await self(call, request_timeout=request_timeout) # ============================================================================================= # Group: Inline mode @@ -2245,6 +2402,7 @@ class Bot(ContextInstanceMixin["Bot"]): next_offset: Optional[str] = None, switch_pm_text: Optional[str] = None, switch_pm_parameter: Optional[str] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Use this method to send answers to an inline query. On success, True is returned. @@ -2261,14 +2419,15 @@ class Bot(ContextInstanceMixin["Bot"]): user who sends the same query :param next_offset: Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are - no more results or if you don‘t support pagination. Offset length - can’t exceed 64 bytes. + no more results or if you don't support pagination. Offset length + can't exceed 64 bytes. :param switch_pm_text: 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 :param switch_pm_parameter: Deep-linking parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed. + :param request_timeout: Request timeout :return: On success, True is returned. """ call = AnswerInlineQuery( @@ -2280,7 +2439,7 @@ class Bot(ContextInstanceMixin["Bot"]): switch_pm_text=switch_pm_text, switch_pm_parameter=switch_pm_parameter, ) - return await self(call) + return await self(call, request_timeout=request_timeout) # ============================================================================================= # Group: Payments @@ -2312,6 +2471,7 @@ class Bot(ContextInstanceMixin["Bot"]): disable_notification: Optional[bool] = None, reply_to_message_id: Optional[int] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send invoices. On success, the sent Message is returned. @@ -2356,6 +2516,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param reply_markup: A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendInvoice( @@ -2383,7 +2544,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def answer_shipping_query( self, @@ -2391,6 +2552,7 @@ class Bot(ContextInstanceMixin["Bot"]): ok: bool, shipping_options: Optional[List[ShippingOption]] = None, error_message: Optional[str] = None, + request_timeout: Optional[int] = None, ) -> bool: """ If you sent an invoice requesting a shipping address and the parameter is_flexible was @@ -2409,6 +2571,7 @@ class Bot(ContextInstanceMixin["Bot"]): 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. + :param request_timeout: Request timeout :return: On success, True is returned. """ call = AnswerShippingQuery( @@ -2417,10 +2580,14 @@ class Bot(ContextInstanceMixin["Bot"]): shipping_options=shipping_options, error_message=error_message, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def answer_pre_checkout_query( - self, pre_checkout_query_id: str, ok: bool, error_message: Optional[str] = None, + self, + pre_checkout_query_id: str, + ok: bool, + error_message: Optional[str] = None, + request_timeout: Optional[int] = None, ) -> bool: """ Once the user has confirmed their payment and shipping details, the Bot API sends the @@ -2439,12 +2606,13 @@ class Bot(ContextInstanceMixin["Bot"]): while you were busy filling out your payment details. Please choose a different color or garment!"). Telegram will display this message to the user. + :param request_timeout: Request timeout :return: On success, True is returned. """ call = AnswerPreCheckoutQuery( pre_checkout_query_id=pre_checkout_query_id, ok=ok, error_message=error_message, ) - return await self(call) + return await self(call, request_timeout=request_timeout) # ============================================================================================= # Group: Telegram Passport @@ -2452,7 +2620,10 @@ class Bot(ContextInstanceMixin["Bot"]): # ============================================================================================= async def set_passport_data_errors( - self, user_id: int, errors: List[PassportElementError], + self, + user_id: int, + errors: List[PassportElementError], + request_timeout: Optional[int] = None, ) -> bool: """ Informs a user that some of the Telegram Passport elements they provided contains errors. @@ -2468,12 +2639,13 @@ class Bot(ContextInstanceMixin["Bot"]): :param user_id: User identifier :param errors: A JSON-serialized array describing the errors + :param request_timeout: Request timeout :return: The user will not be able to re-submit their Passport to you until the errors are fixed (the contents of the field for which you returned the error must change). Returns True on success. """ call = SetPassportDataErrors(user_id=user_id, errors=errors,) - return await self(call) + return await self(call, request_timeout=request_timeout) # ============================================================================================= # Group: Games @@ -2487,6 +2659,7 @@ class Bot(ContextInstanceMixin["Bot"]): disable_notification: Optional[bool] = None, reply_to_message_id: Optional[int] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, + request_timeout: Optional[int] = None, ) -> Message: """ Use this method to send a game. On success, the sent Message is returned. @@ -2499,9 +2672,10 @@ class Bot(ContextInstanceMixin["Bot"]): :param disable_notification: Sends the message silently. Users will receive a notification with no sound. :param reply_to_message_id: If the message is a reply, ID of the original message - :param reply_markup: A JSON-serialized object for an inline keyboard. If empty, one ‘Play - game_title’ button will be shown. If not empty, the first button must + :param reply_markup: A JSON-serialized object for an inline keyboard. If empty, one 'Play + game_title' button will be shown. If not empty, the first button must launch the game. + :param request_timeout: Request timeout :return: On success, the sent Message is returned. """ call = SendGame( @@ -2511,7 +2685,7 @@ class Bot(ContextInstanceMixin["Bot"]): reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def set_game_score( self, @@ -2522,6 +2696,7 @@ class Bot(ContextInstanceMixin["Bot"]): chat_id: Optional[int] = None, message_id: Optional[int] = None, inline_message_id: Optional[str] = None, + request_timeout: Optional[int] = None, ) -> Union[Message, bool]: """ Use this method to set the score of the specified user in a game. On success, if the @@ -2543,6 +2718,7 @@ class Bot(ContextInstanceMixin["Bot"]): message :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message + :param request_timeout: Request timeout :return: On success, if the message was sent by the bot, returns the edited Message, otherwise returns True. Returns an error, if the new score is not greater than the user's current score in the chat and force is False. @@ -2556,7 +2732,7 @@ class Bot(ContextInstanceMixin["Bot"]): message_id=message_id, inline_message_id=inline_message_id, ) - return await self(call) + return await self(call, request_timeout=request_timeout) async def get_game_high_scores( self, @@ -2564,6 +2740,7 @@ class Bot(ContextInstanceMixin["Bot"]): chat_id: Optional[int] = None, message_id: Optional[int] = None, inline_message_id: Optional[str] = None, + request_timeout: Optional[int] = None, ) -> List[GameHighScore]: """ Use this method to get data for high score tables. Will return the score of the specified @@ -2582,6 +2759,7 @@ class Bot(ContextInstanceMixin["Bot"]): message :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message + :param request_timeout: Request timeout :return: Will return the score of the specified user and several of their neighbors in a game. On success, returns an Array of GameHighScore objects. This method will currently return scores for the target user, plus two of their closest neighbors @@ -2594,4 +2772,4 @@ class Bot(ContextInstanceMixin["Bot"]): message_id=message_id, inline_message_id=inline_message_id, ) - return await self(call) + return await self(call, request_timeout=request_timeout) diff --git a/aiogram/api/client/session/aiohttp.py b/aiogram/api/client/session/aiohttp.py index 774e7186..4ecfcea9 100644 --- a/aiogram/api/client/session/aiohttp.py +++ b/aiogram/api/client/session/aiohttp.py @@ -125,16 +125,16 @@ class AiohttpSession(BaseSession): form.add_field(key, value, filename=value.filename or key) return form - async def make_request(self, token: str, call: TelegramMethod[T]) -> T: + async def make_request( + self, token: str, call: TelegramMethod[T], timeout: Optional[int] = None + ) -> T: session = await self.create_session() request = call.build_request() url = self.api.api_url(token=token, method=request.method) form = self.build_form_data(request) - async with session.post( - url, data=form, timeout=call.request_timeout or self.timeout - ) as resp: + async with session.post(url, data=form, timeout=timeout or self.timeout) as resp: raw_result = await resp.json(loads=self.json_loads) response = call.build_response(raw_result) diff --git a/aiogram/api/client/session/base.py b/aiogram/api/client/session/base.py index 379e69ac..c49d4b5a 100644 --- a/aiogram/api/client/session/base.py +++ b/aiogram/api/client/session/base.py @@ -10,6 +10,7 @@ from aiogram.utils.exceptions import TelegramAPIError from ....utils.helper import Default from ...methods import Response, TelegramMethod +from ...types import UNSET from ..telegram import PRODUCTION, TelegramAPIServer T = TypeVar("T") @@ -18,9 +19,7 @@ _JsonDumps = Callable[..., str] class BaseSession(abc.ABC): - # global session timeout default_timeout: ClassVar[float] = 60.0 - api: Default[TelegramAPIServer] = Default(PRODUCTION) json_loads: Default[_JsonLoads] = Default(json.loads) json_dumps: Default[_JsonDumps] = Default(json.dumps) @@ -37,7 +36,9 @@ class BaseSession(abc.ABC): pass @abc.abstractmethod - async def make_request(self, token: str, method: TelegramMethod[T]) -> T: # pragma: no cover + async def make_request( + self, token: str, method: TelegramMethod[T], timeout: Optional[int] = UNSET + ) -> T: # pragma: no cover pass @abc.abstractmethod diff --git a/aiogram/api/methods/answer_inline_query.py b/aiogram/api/methods/answer_inline_query.py index a5b8bd7b..eb8a7138 100644 --- a/aiogram/api/methods/answer_inline_query.py +++ b/aiogram/api/methods/answer_inline_query.py @@ -26,8 +26,8 @@ class AnswerInlineQuery(TelegramMethod[bool]): query. By default, results may be returned to any user who sends the same query""" next_offset: Optional[str] = None """Pass the offset that a client should send in the next query with the same text to receive - more results. Pass an empty string if there are no more results or if you don‘t support - pagination. Offset length can’t exceed 64 bytes.""" + more results. Pass an empty string if there are no more results or if you don't support + pagination. Offset length can't exceed 64 bytes.""" switch_pm_text: Optional[str] = None """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 diff --git a/aiogram/api/methods/base.py b/aiogram/api/methods/base.py index 4fcd9ae9..40f251c0 100644 --- a/aiogram/api/methods/base.py +++ b/aiogram/api/methods/base.py @@ -69,13 +69,9 @@ class TelegramMethod(abc.ABC, BaseModel, Generic[T]): def build_request(self) -> Request: # pragma: no cover pass - request_timeout: Optional[float] = None - def dict(self, **kwargs: Any) -> Any: # override dict of pydantic.BaseModel to overcome exporting request_timeout field exclude = kwargs.pop("exclude", set()) - if isinstance(exclude, set): - exclude.add("request_timeout") return super().dict(exclude=exclude, **kwargs) diff --git a/aiogram/api/methods/edit_message_caption.py b/aiogram/api/methods/edit_message_caption.py index ebbe9c7b..733c357d 100644 --- a/aiogram/api/methods/edit_message_caption.py +++ b/aiogram/api/methods/edit_message_caption.py @@ -24,8 +24,7 @@ class EditMessageCaption(TelegramMethod[Union[Message, bool]]): caption: Optional[str] = None """New caption of the message, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the message caption. See formatting options for more details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """A JSON-serialized object for an inline keyboard.""" diff --git a/aiogram/api/methods/edit_message_text.py b/aiogram/api/methods/edit_message_text.py index 20098fdc..23255e98 100644 --- a/aiogram/api/methods/edit_message_text.py +++ b/aiogram/api/methods/edit_message_text.py @@ -24,8 +24,7 @@ class EditMessageText(TelegramMethod[Union[Message, bool]]): 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 - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in your bot's message.""" + """Mode for parsing entities in the message text. See formatting options for more details.""" disable_web_page_preview: Optional[bool] = None """Disables link previews for links in this message""" reply_markup: Optional[InlineKeyboardMarkup] = None diff --git a/aiogram/api/methods/pin_chat_message.py b/aiogram/api/methods/pin_chat_message.py index 1d7383e7..3f8a442d 100644 --- a/aiogram/api/methods/pin_chat_message.py +++ b/aiogram/api/methods/pin_chat_message.py @@ -6,8 +6,8 @@ from .base import Request, TelegramMethod class PinChatMessage(TelegramMethod[bool]): """ Use this method to pin a message in a group, a supergroup, or a channel. The bot must be an - administrator in the chat for this to work and must have the ‘can_pin_messages’ admin right in - the supergroup or ‘can_edit_messages’ admin right in the channel. Returns True on success. + administrator in the chat for this to work and must have the 'can_pin_messages' admin right in + the supergroup or 'can_edit_messages' admin right in the channel. Returns True on success. Source: https://core.telegram.org/bots/api#pinchatmessage """ diff --git a/aiogram/api/methods/send_animation.py b/aiogram/api/methods/send_animation.py index aca62a40..955ed9e9 100644 --- a/aiogram/api/methods/send_animation.py +++ b/aiogram/api/methods/send_animation.py @@ -39,16 +39,16 @@ class SendAnimation(TelegramMethod[Message]): thumb: Optional[Union[InputFile, str]] = None """Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. Ignored if the file is not uploaded - using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new + A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded + using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under .""" caption: Optional[str] = None """Animation caption (may also be used when resending animation by file_id), 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the animation caption. See formatting options for more + details.""" disable_notification: Optional[bool] = None """Sends the message silently. Users will receive a notification with no sound.""" reply_to_message_id: Optional[int] = None diff --git a/aiogram/api/methods/send_audio.py b/aiogram/api/methods/send_audio.py index be4870c4..ca39408f 100644 --- a/aiogram/api/methods/send_audio.py +++ b/aiogram/api/methods/send_audio.py @@ -35,8 +35,7 @@ class SendAudio(TelegramMethod[Message]): caption: Optional[str] = None """Audio caption, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the audio caption. See formatting options for more details.""" duration: Optional[int] = None """Duration of the audio in seconds""" performer: Optional[str] = None @@ -46,8 +45,8 @@ class SendAudio(TelegramMethod[Message]): thumb: Optional[Union[InputFile, str]] = None """Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. Ignored if the file is not uploaded - using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new + A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded + using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under .""" disable_notification: Optional[bool] = None diff --git a/aiogram/api/methods/send_dice.py b/aiogram/api/methods/send_dice.py index f200850e..fb767799 100644 --- a/aiogram/api/methods/send_dice.py +++ b/aiogram/api/methods/send_dice.py @@ -12,9 +12,8 @@ from .base import Request, TelegramMethod class SendDice(TelegramMethod[Message]): """ - Use this method to send a dice, which will have a random value from 1 to 6. On success, the - sent Message is returned. (Yes, we're aware of the 'proper' singular of die. But it's awkward, - and we decided to help it change. One dice at a time!) + Use this method to send an animated emoji that will display a random value. On success, the + sent Message is returned. Source: https://core.telegram.org/bots/api#senddice """ @@ -25,8 +24,8 @@ class SendDice(TelegramMethod[Message]): """Unique identifier for the target chat or username of the target channel (in the format @channelusername)""" emoji: Optional[str] = None - """Emoji on which the dice throw animation is based. Currently, must be one of '' or ''. - Defauts to ''""" + """Emoji on which the dice throw animation is based. Currently, must be one of '', '', or ''. + Dice can have values 1-6 for '' and '', and values 1-5 for ''. Defaults to ''""" disable_notification: Optional[bool] = None """Sends the message silently. Users will receive a notification with no sound.""" reply_to_message_id: Optional[int] = None diff --git a/aiogram/api/methods/send_document.py b/aiogram/api/methods/send_document.py index c67588e4..b6868135 100644 --- a/aiogram/api/methods/send_document.py +++ b/aiogram/api/methods/send_document.py @@ -33,16 +33,15 @@ class SendDocument(TelegramMethod[Message]): thumb: Optional[Union[InputFile, str]] = None """Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. Ignored if the file is not uploaded - using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new + A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded + using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under .""" caption: Optional[str] = None """Document caption (may also be used when resending documents by file_id), 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the document caption. See formatting options for more details.""" disable_notification: Optional[bool] = None """Sends the message silently. Users will receive a notification with no sound.""" reply_to_message_id: Optional[int] = None diff --git a/aiogram/api/methods/send_game.py b/aiogram/api/methods/send_game.py index 0e32c6eb..9d760555 100644 --- a/aiogram/api/methods/send_game.py +++ b/aiogram/api/methods/send_game.py @@ -23,7 +23,7 @@ class SendGame(TelegramMethod[Message]): reply_to_message_id: Optional[int] = None """If the message is a reply, ID of the original message""" reply_markup: Optional[InlineKeyboardMarkup] = None - """A JSON-serialized object for an inline keyboard. If empty, one ‘Play game_title’ button + """A JSON-serialized object for an inline keyboard. If empty, one 'Play game_title' button will be shown. If not empty, the first button must launch the game.""" def build_request(self) -> Request: diff --git a/aiogram/api/methods/send_message.py b/aiogram/api/methods/send_message.py index 54f0fe37..44cc0fd2 100644 --- a/aiogram/api/methods/send_message.py +++ b/aiogram/api/methods/send_message.py @@ -26,8 +26,7 @@ class SendMessage(TelegramMethod[Message]): text: str """Text of the message to be sent, 1-4096 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in your bot's message.""" + """Mode for parsing entities in the message text. See formatting options for more details.""" disable_web_page_preview: Optional[bool] = None """Disables link previews for links in this message""" disable_notification: Optional[bool] = None diff --git a/aiogram/api/methods/send_photo.py b/aiogram/api/methods/send_photo.py index 89a25864..ab37099d 100644 --- a/aiogram/api/methods/send_photo.py +++ b/aiogram/api/methods/send_photo.py @@ -32,8 +32,7 @@ class SendPhoto(TelegramMethod[Message]): """Photo caption (may also be used when resending photos by file_id), 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the photo caption. See formatting options for more details.""" disable_notification: Optional[bool] = None """Sends the message silently. Users will receive a notification with no sound.""" reply_to_message_id: Optional[int] = None diff --git a/aiogram/api/methods/send_video.py b/aiogram/api/methods/send_video.py index f2659348..8784d134 100644 --- a/aiogram/api/methods/send_video.py +++ b/aiogram/api/methods/send_video.py @@ -39,16 +39,15 @@ class SendVideo(TelegramMethod[Message]): thumb: Optional[Union[InputFile, str]] = None """Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. Ignored if the file is not uploaded - using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new + A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded + using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under .""" caption: Optional[str] = None """Video caption (may also be used when resending videos by file_id), 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the video caption. See formatting options for more details.""" supports_streaming: Optional[bool] = None """Pass True, if the uploaded video is suitable for streaming""" disable_notification: Optional[bool] = None diff --git a/aiogram/api/methods/send_video_note.py b/aiogram/api/methods/send_video_note.py index 05f55696..bb41045a 100644 --- a/aiogram/api/methods/send_video_note.py +++ b/aiogram/api/methods/send_video_note.py @@ -35,8 +35,8 @@ class SendVideoNote(TelegramMethod[Message]): thumb: Optional[Union[InputFile, str]] = None """Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. Ignored if the file is not uploaded - using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new + A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded + using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under .""" disable_notification: Optional[bool] = None diff --git a/aiogram/api/methods/send_voice.py b/aiogram/api/methods/send_voice.py index 1369ad1c..945c6314 100644 --- a/aiogram/api/methods/send_voice.py +++ b/aiogram/api/methods/send_voice.py @@ -35,8 +35,8 @@ class SendVoice(TelegramMethod[Message]): caption: Optional[str] = None """Voice message caption, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the voice message caption. See formatting options for more + details.""" duration: Optional[int] = None """Duration of the voice message in seconds""" disable_notification: Optional[bool] = None diff --git a/aiogram/api/methods/set_webhook.py b/aiogram/api/methods/set_webhook.py index 905385ad..7da2d287 100644 --- a/aiogram/api/methods/set_webhook.py +++ b/aiogram/api/methods/set_webhook.py @@ -12,7 +12,7 @@ class SetWebhook(TelegramMethod[bool]): after a reasonable amount of attempts. Returns True on success. If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the URL, e.g. https://www.example.com/. Since nobody else knows your - bot‘s token, you can be pretty sure it’s us. + bot's token, you can be pretty sure it's us. Notes 1. You will not be able to receive updates using getUpdates for as long as an outgoing webhook is set up. @@ -34,8 +34,8 @@ class SetWebhook(TelegramMethod[bool]): our self-signed guide for details.""" max_connections: Optional[int] = None """Maximum allowed number of simultaneous HTTPS connections to the webhook for update - delivery, 1-100. Defaults to 40. Use lower values to limit the load on your bot‘s server, - and higher values to increase your bot’s throughput.""" + delivery, 1-100. Defaults to 40. Use lower values to limit the load on your bot's server, + and higher values to increase your bot's throughput.""" 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 diff --git a/aiogram/api/methods/unpin_chat_message.py b/aiogram/api/methods/unpin_chat_message.py index 20cee142..c205884d 100644 --- a/aiogram/api/methods/unpin_chat_message.py +++ b/aiogram/api/methods/unpin_chat_message.py @@ -6,8 +6,8 @@ from .base import Request, TelegramMethod class UnpinChatMessage(TelegramMethod[bool]): """ Use this method to unpin a message in a group, a supergroup, or a channel. The bot must be an - administrator in the chat for this to work and must have the ‘can_pin_messages’ admin right in - the supergroup or ‘can_edit_messages’ admin right in the channel. Returns True on success. + administrator in the chat for this to work and must have the 'can_pin_messages' admin right in + the supergroup or 'can_edit_messages' admin right in the channel. Returns True on success. Source: https://core.telegram.org/bots/api#unpinchatmessage """ diff --git a/aiogram/api/types/base.py b/aiogram/api/types/base.py index 06618234..99db1a01 100644 --- a/aiogram/api/types/base.py +++ b/aiogram/api/types/base.py @@ -24,4 +24,3 @@ class MutableTelegramObject(TelegramObject): UNSET: Any = sentinel.UNSET # special sentinel object which used in sutuation when None might be a useful value -print(id(UNSET)) diff --git a/aiogram/api/types/chat_member.py b/aiogram/api/types/chat_member.py index 593a86fb..dca3029e 100644 --- a/aiogram/api/types/chat_member.py +++ b/aiogram/api/types/chat_member.py @@ -3,8 +3,8 @@ from __future__ import annotations import datetime from typing import TYPE_CHECKING, Optional, Union -from .base import TelegramObject from ...utils import helper +from .base import TelegramObject if TYPE_CHECKING: # pragma: no cover from .user import User @@ -80,6 +80,7 @@ class ChatMemberStatus(helper.Helper): """ Chat member status """ + mode = helper.HelperMode.lowercase CREATOR = helper.Item() # creator diff --git a/aiogram/api/types/dice.py b/aiogram/api/types/dice.py index a85d54ac..d9b1da10 100644 --- a/aiogram/api/types/dice.py +++ b/aiogram/api/types/dice.py @@ -5,9 +5,7 @@ from .base import TelegramObject class Dice(TelegramObject): """ - This object represents a dice with a random value from 1 to 6 for currently supported base - emoji. (Yes, we're aware of the 'proper' singular of die. But it's awkward, and we decided to - help it change. One dice at a time!) + This object represents an animated emoji that displays a random value. Source: https://core.telegram.org/bots/api#dice """ @@ -15,7 +13,7 @@ class Dice(TelegramObject): emoji: str """Emoji on which the dice throw animation is based""" value: int - """Value of the dice, 1-6 for currently supported base emoji""" + """Value of the dice, 1-6 for '' and '' base emoji, 1-5 for '' base emoji""" class DiceEmoji: diff --git a/aiogram/api/types/force_reply.py b/aiogram/api/types/force_reply.py index 8ef4a1bd..8cbc1653 100644 --- a/aiogram/api/types/force_reply.py +++ b/aiogram/api/types/force_reply.py @@ -8,7 +8,7 @@ from .base import MutableTelegramObject class ForceReply(MutableTelegramObject): """ Upon receiving a message with this object, Telegram clients will display a reply interface to - the user (act as if the user has selected the bot‘s message and tapped ’Reply'). This can be + the user (act as if the user has selected the bot's message and tapped 'Reply'). This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode. Example: A poll bot for groups runs in privacy mode (only receives commands, replies to its @@ -16,19 +16,19 @@ class ForceReply(MutableTelegramObject): Explain the user how to send a command with parameters (e.g. /newpoll question answer1 answer2). May be appealing for hardcore users but lacks modern day polish. - Guide the user through a step-by-step process. ‘Please send me your question’, ‘Cool, now - let’s add the first answer option‘, ’Great. Keep adding answer options, then send /done when - you‘re ready’. - The last option is definitely more attractive. And if you use ForceReply in your bot‘s - questions, it will receive the user’s answers even if it only receives replies, commands and + Guide the user through a step-by-step process. 'Please send me your question', 'Cool, now + let's add the first answer option', 'Great. Keep adding answer options, then send /done when + you're ready'. + The last option is definitely more attractive. And if you use ForceReply in your bot's + questions, it will receive the user's answers even if it only receives replies, commands and mentions — without any extra work for the user. Source: https://core.telegram.org/bots/api#forcereply """ force_reply: bool - """Shows reply interface to the user, as if they manually selected the bot‘s message and - tapped ’Reply'""" + """Shows reply interface to the user, as if they manually selected the bot's message and + tapped 'Reply'""" selective: Optional[bool] = None """Use this parameter if you want to force reply from specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply diff --git a/aiogram/api/types/game_high_score.py b/aiogram/api/types/game_high_score.py index af8a1f3a..7bc35de6 100644 --- a/aiogram/api/types/game_high_score.py +++ b/aiogram/api/types/game_high_score.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: # pragma: no cover class GameHighScore(TelegramObject): """ This object represents one row of the high scores table for a game. - And that‘s about all we’ve got for now. + And that's about all we've got for now. If you've got any questions, please check out our Bot FAQ Source: https://core.telegram.org/bots/api#gamehighscore diff --git a/aiogram/api/types/inline_keyboard_button.py b/aiogram/api/types/inline_keyboard_button.py index deb1f3c2..33ade442 100644 --- a/aiogram/api/types/inline_keyboard_button.py +++ b/aiogram/api/types/inline_keyboard_button.py @@ -28,11 +28,11 @@ class InlineKeyboardButton(MutableTelegramObject): """Data to be sent in a callback query to the bot when button is pressed, 1-64 bytes""" switch_inline_query: Optional[str] = None """If set, pressing the button will prompt the user to select one of their chats, open that - chat and insert the bot‘s username and the specified inline query in the input field. Can - be empty, in which case just the bot’s username will be inserted.""" + chat and insert the bot's username and the specified inline query in the input field. Can + be empty, in which case just the bot's username will be inserted.""" switch_inline_query_current_chat: Optional[str] = None - """If set, pressing the button will insert the bot‘s username and the specified inline query - in the current chat’s input field. Can be empty, in which case only the bot's username will + """If set, pressing the button will insert the bot's username and the specified inline query + in the current chat's input field. Can be empty, in which case only the bot's username will be inserted.""" callback_game: Optional[CallbackGame] = None """Description of the game that will be launched when the user presses the button.""" diff --git a/aiogram/api/types/inline_query_result_audio.py b/aiogram/api/types/inline_query_result_audio.py index 687de9f0..b236f26d 100644 --- a/aiogram/api/types/inline_query_result_audio.py +++ b/aiogram/api/types/inline_query_result_audio.py @@ -34,8 +34,7 @@ class InlineQueryResultAudio(InlineQueryResult): caption: Optional[str] = None """Caption, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the audio caption. See formatting options for more details.""" performer: Optional[str] = None """Performer""" audio_duration: Optional[int] = None diff --git a/aiogram/api/types/inline_query_result_cached_audio.py b/aiogram/api/types/inline_query_result_cached_audio.py index af508b2e..b26edfed 100644 --- a/aiogram/api/types/inline_query_result_cached_audio.py +++ b/aiogram/api/types/inline_query_result_cached_audio.py @@ -32,8 +32,7 @@ class InlineQueryResultCachedAudio(InlineQueryResult): caption: Optional[str] = None """Caption, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the audio caption. See formatting options for more details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """Inline keyboard attached to the message""" input_message_content: Optional[InputMessageContent] = None diff --git a/aiogram/api/types/inline_query_result_cached_document.py b/aiogram/api/types/inline_query_result_cached_document.py index f9024291..74fa2ecf 100644 --- a/aiogram/api/types/inline_query_result_cached_document.py +++ b/aiogram/api/types/inline_query_result_cached_document.py @@ -36,8 +36,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult): caption: Optional[str] = None """Caption of the document to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the document caption. See formatting options for more details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """Inline keyboard attached to the message""" input_message_content: Optional[InputMessageContent] = None diff --git a/aiogram/api/types/inline_query_result_cached_gif.py b/aiogram/api/types/inline_query_result_cached_gif.py index 3408a404..cb66af96 100644 --- a/aiogram/api/types/inline_query_result_cached_gif.py +++ b/aiogram/api/types/inline_query_result_cached_gif.py @@ -32,8 +32,7 @@ class InlineQueryResultCachedGif(InlineQueryResult): caption: Optional[str] = None """Caption of the GIF file to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the caption. See formatting options for more details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """Inline keyboard attached to the message""" input_message_content: Optional[InputMessageContent] = None diff --git a/aiogram/api/types/inline_query_result_cached_mpeg4_gif.py b/aiogram/api/types/inline_query_result_cached_mpeg4_gif.py index 71a4e926..a43de25f 100644 --- a/aiogram/api/types/inline_query_result_cached_mpeg4_gif.py +++ b/aiogram/api/types/inline_query_result_cached_mpeg4_gif.py @@ -33,8 +33,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult): caption: Optional[str] = None """Caption of the MPEG-4 file to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the caption. See formatting options for more details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """Inline keyboard attached to the message""" input_message_content: Optional[InputMessageContent] = None diff --git a/aiogram/api/types/inline_query_result_cached_photo.py b/aiogram/api/types/inline_query_result_cached_photo.py index 1e7abd57..b3a9f8a1 100644 --- a/aiogram/api/types/inline_query_result_cached_photo.py +++ b/aiogram/api/types/inline_query_result_cached_photo.py @@ -34,8 +34,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult): caption: Optional[str] = None """Caption of the photo to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the photo caption. See formatting options for more details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """Inline keyboard attached to the message""" input_message_content: Optional[InputMessageContent] = None diff --git a/aiogram/api/types/inline_query_result_cached_video.py b/aiogram/api/types/inline_query_result_cached_video.py index b6161679..ef561bb4 100644 --- a/aiogram/api/types/inline_query_result_cached_video.py +++ b/aiogram/api/types/inline_query_result_cached_video.py @@ -34,8 +34,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult): caption: Optional[str] = None """Caption of the video to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the video caption. See formatting options for more details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """Inline keyboard attached to the message""" input_message_content: Optional[InputMessageContent] = None diff --git a/aiogram/api/types/inline_query_result_cached_voice.py b/aiogram/api/types/inline_query_result_cached_voice.py index 12491b88..aec92d44 100644 --- a/aiogram/api/types/inline_query_result_cached_voice.py +++ b/aiogram/api/types/inline_query_result_cached_voice.py @@ -34,8 +34,8 @@ class InlineQueryResultCachedVoice(InlineQueryResult): caption: Optional[str] = None """Caption, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the voice message caption. See formatting options for more + details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """Inline keyboard attached to the message""" input_message_content: Optional[InputMessageContent] = None diff --git a/aiogram/api/types/inline_query_result_document.py b/aiogram/api/types/inline_query_result_document.py index 0c66579c..01e389ff 100644 --- a/aiogram/api/types/inline_query_result_document.py +++ b/aiogram/api/types/inline_query_result_document.py @@ -37,8 +37,7 @@ class InlineQueryResultDocument(InlineQueryResult): caption: Optional[str] = None """Caption of the document to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the document caption. See formatting options for more details.""" description: Optional[str] = None """Short description of the result""" reply_markup: Optional[InlineKeyboardMarkup] = None diff --git a/aiogram/api/types/inline_query_result_gif.py b/aiogram/api/types/inline_query_result_gif.py index 1285b96f..8812c43a 100644 --- a/aiogram/api/types/inline_query_result_gif.py +++ b/aiogram/api/types/inline_query_result_gif.py @@ -28,20 +28,22 @@ class InlineQueryResultGif(InlineQueryResult): gif_url: str """A valid URL for the GIF file. File size must not exceed 1MB""" thumb_url: str - """URL of the static thumbnail for the result (jpeg or gif)""" + """URL of the static (JPEG or GIF) or animated (MPEG4) thumbnail for the result""" gif_width: Optional[int] = None """Width of the GIF""" gif_height: Optional[int] = None """Height of the GIF""" gif_duration: Optional[int] = None """Duration of the GIF""" + thumb_mime_type: Optional[str] = None + """MIME type of the thumbnail, must be one of 'image/jpeg', 'image/gif', or 'video/mp4'. + Defaults to 'image/jpeg'""" title: Optional[str] = None """Title for the result""" caption: Optional[str] = None """Caption of the GIF file to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the caption. See formatting options for more details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """Inline keyboard attached to the message""" input_message_content: Optional[InputMessageContent] = None diff --git a/aiogram/api/types/inline_query_result_mpeg4_gif.py b/aiogram/api/types/inline_query_result_mpeg4_gif.py index 4fa6a8e9..76f97e0a 100644 --- a/aiogram/api/types/inline_query_result_mpeg4_gif.py +++ b/aiogram/api/types/inline_query_result_mpeg4_gif.py @@ -29,20 +29,22 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): mpeg4_url: str """A valid URL for the MP4 file. File size must not exceed 1MB""" thumb_url: str - """URL of the static thumbnail (jpeg or gif) for the result""" + """URL of the static (JPEG or GIF) or animated (MPEG4) thumbnail for the result""" mpeg4_width: Optional[int] = None """Video width""" mpeg4_height: Optional[int] = None """Video height""" mpeg4_duration: Optional[int] = None """Video duration""" + thumb_mime_type: Optional[str] = None + """MIME type of the thumbnail, must be one of 'image/jpeg', 'image/gif', or 'video/mp4'. + Defaults to 'image/jpeg'""" title: Optional[str] = None """Title for the result""" caption: Optional[str] = None """Caption of the MPEG-4 file to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the caption. See formatting options for more details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """Inline keyboard attached to the message""" input_message_content: Optional[InputMessageContent] = None diff --git a/aiogram/api/types/inline_query_result_photo.py b/aiogram/api/types/inline_query_result_photo.py index 5927c62c..31cddee2 100644 --- a/aiogram/api/types/inline_query_result_photo.py +++ b/aiogram/api/types/inline_query_result_photo.py @@ -40,8 +40,7 @@ class InlineQueryResultPhoto(InlineQueryResult): caption: Optional[str] = None """Caption of the photo to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the photo caption. See formatting options for more details.""" reply_markup: Optional[InlineKeyboardMarkup] = None """Inline keyboard attached to the message""" input_message_content: Optional[InputMessageContent] = None diff --git a/aiogram/api/types/inline_query_result_video.py b/aiogram/api/types/inline_query_result_video.py index 5ea390ed..3002b8be 100644 --- a/aiogram/api/types/inline_query_result_video.py +++ b/aiogram/api/types/inline_query_result_video.py @@ -38,8 +38,7 @@ class InlineQueryResultVideo(InlineQueryResult): caption: Optional[str] = None """Caption of the video to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the video caption. See formatting options for more details.""" video_width: Optional[int] = None """Video width""" video_height: Optional[int] = None diff --git a/aiogram/api/types/inline_query_result_voice.py b/aiogram/api/types/inline_query_result_voice.py index 74d17448..724d46bc 100644 --- a/aiogram/api/types/inline_query_result_voice.py +++ b/aiogram/api/types/inline_query_result_voice.py @@ -35,8 +35,8 @@ class InlineQueryResultVoice(InlineQueryResult): caption: Optional[str] = None """Caption, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the voice message caption. See formatting options for more + details.""" voice_duration: Optional[int] = None """Recording duration in seconds""" reply_markup: Optional[InlineKeyboardMarkup] = None diff --git a/aiogram/api/types/input_media_animation.py b/aiogram/api/types/input_media_animation.py index e62dc95e..d30084a2 100644 --- a/aiogram/api/types/input_media_animation.py +++ b/aiogram/api/types/input_media_animation.py @@ -28,15 +28,15 @@ class InputMediaAnimation(InputMedia): thumb: Optional[Union[InputFile, str]] = None """Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. Ignored if the file is not uploaded - using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new + A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded + using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under .""" caption: Optional[str] = None """Caption of the animation to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the animation caption. See formatting options for more + details.""" width: Optional[int] = None """Animation width""" height: Optional[int] = None diff --git a/aiogram/api/types/input_media_audio.py b/aiogram/api/types/input_media_audio.py index 40059bd9..098087d1 100644 --- a/aiogram/api/types/input_media_audio.py +++ b/aiogram/api/types/input_media_audio.py @@ -28,15 +28,14 @@ class InputMediaAudio(InputMedia): thumb: Optional[Union[InputFile, str]] = None """Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. Ignored if the file is not uploaded - using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new + A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded + using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under .""" caption: Optional[str] = None """Caption of the audio to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the audio caption. See formatting options for more details.""" duration: Optional[int] = None """Duration of the audio in seconds""" performer: Optional[str] = None diff --git a/aiogram/api/types/input_media_document.py b/aiogram/api/types/input_media_document.py index d57f1178..e29a5014 100644 --- a/aiogram/api/types/input_media_document.py +++ b/aiogram/api/types/input_media_document.py @@ -28,12 +28,11 @@ class InputMediaDocument(InputMedia): thumb: Optional[Union[InputFile, str]] = None """Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. Ignored if the file is not uploaded - using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new + A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded + using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under .""" caption: Optional[str] = None """Caption of the document to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the document caption. See formatting options for more details.""" diff --git a/aiogram/api/types/input_media_photo.py b/aiogram/api/types/input_media_photo.py index c92b45e4..6ef61006 100644 --- a/aiogram/api/types/input_media_photo.py +++ b/aiogram/api/types/input_media_photo.py @@ -28,5 +28,4 @@ class InputMediaPhoto(InputMedia): caption: Optional[str] = None """Caption of the photo to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the photo caption. See formatting options for more details.""" diff --git a/aiogram/api/types/input_media_video.py b/aiogram/api/types/input_media_video.py index 61e73c1e..d8dc0adf 100644 --- a/aiogram/api/types/input_media_video.py +++ b/aiogram/api/types/input_media_video.py @@ -28,15 +28,14 @@ class InputMediaVideo(InputMedia): thumb: Optional[Union[InputFile, str]] = None """Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. Ignored if the file is not uploaded - using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new + A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded + using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under .""" caption: Optional[str] = None """Caption of the video to be sent, 0-1024 characters after entities parsing""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in the media caption.""" + """Mode for parsing entities in the video caption. See formatting options for more details.""" width: Optional[int] = None """Video width""" height: Optional[int] = None diff --git a/aiogram/api/types/input_text_message_content.py b/aiogram/api/types/input_text_message_content.py index 3c5bda13..389cb48e 100644 --- a/aiogram/api/types/input_text_message_content.py +++ b/aiogram/api/types/input_text_message_content.py @@ -16,7 +16,6 @@ class InputTextMessageContent(InputMessageContent): message_text: str """Text of the message to be sent, 1-4096 characters""" parse_mode: Optional[str] = UNSET - """Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or - inline URLs in your bot's message.""" + """Mode for parsing entities in the message text. See formatting options for more details.""" disable_web_page_preview: Optional[bool] = None """Disables link previews for links in the sent message""" diff --git a/aiogram/api/types/message.py b/aiogram/api/types/message.py index 68b56209..589de26e 100644 --- a/aiogram/api/types/message.py +++ b/aiogram/api/types/message.py @@ -90,6 +90,8 @@ class Message(TelegramObject): reply_to_message: Optional[Message] = None """For replies, the original message. Note that the Message object in this field will not contain further reply_to_message fields even if it itself is a reply.""" + via_bot: Optional[User] = None + """Bot through which the message was sent""" edit_date: Optional[int] = None """Date the message was last edited in Unix time""" media_group_id: Optional[str] = None @@ -101,40 +103,41 @@ class Message(TelegramObject): entities: Optional[List[MessageEntity]] = None """For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text""" - caption_entities: Optional[List[MessageEntity]] = None - """For messages with a caption, special entities like usernames, URLs, bot commands, etc. that - appear in the caption""" + animation: Optional[Animation] = None + """Message is an animation, information about the animation. For backward compatibility, when + this field is set, the document field will also be set""" audio: Optional[Audio] = None """Message is an audio file, information about the file""" document: Optional[Document] = None """Message is a general file, information about the file""" - animation: Optional[Animation] = None - """Message is an animation, information about the animation. For backward compatibility, when - this field is set, the document field will also be set""" - game: Optional[Game] = None - """Message is a game, information about the game.""" photo: Optional[List[PhotoSize]] = None """Message is a photo, available sizes of the photo""" sticker: Optional[Sticker] = None """Message is a sticker, information about the sticker""" video: Optional[Video] = None """Message is a video, information about the video""" - voice: Optional[Voice] = None - """Message is a voice message, information about the file""" video_note: Optional[VideoNote] = None """Message is a video note, information about the video message""" + voice: Optional[Voice] = None + """Message is a voice message, information about the file""" caption: Optional[str] = None """Caption for the animation, audio, document, photo, video or voice, 0-1024 characters""" + caption_entities: Optional[List[MessageEntity]] = None + """For messages with a caption, special entities like usernames, URLs, bot commands, etc. that + appear in the caption""" contact: Optional[Contact] = None """Message is a shared contact, information about the contact""" - location: Optional[Location] = None - """Message is a shared location, information about the location""" - venue: Optional[Venue] = None - """Message is a venue, information about the venue""" - poll: Optional[Poll] = None - """Message is a native poll, information about the poll""" dice: Optional[Dice] = None """Message is a dice with random value from 1 to 6""" + game: Optional[Game] = None + """Message is a game, information about the game.""" + poll: Optional[Poll] = None + """Message is a native poll, information about the poll""" + venue: Optional[Venue] = None + """Message is a venue, information about the venue. For backward compatibility, when this + field is set, the location field will also be set""" + location: Optional[Location] = None + """Message is a shared location, information about the location""" new_chat_members: Optional[List[User]] = None """New members that were added to the group or supergroup and information about them (the bot itself may be one of these members)""" @@ -150,13 +153,13 @@ class Message(TelegramObject): group_chat_created: Optional[bool] = None """Service message: the group has been created""" supergroup_chat_created: Optional[bool] = None - """Service message: the supergroup has been created. This field can‘t be received in a message - coming through updates, because bot can’t be a member of a supergroup when it is created. + """Service message: the supergroup has been created. This field can't be received in a message + coming through updates, because bot can't be a member of a supergroup when it is created. It can only be found in reply_to_message if someone replies to a very first message in a directly created supergroup.""" channel_chat_created: Optional[bool] = None - """Service message: the channel has been created. This field can‘t be received in a message - coming through updates, because bot can’t be a member of a channel when it is created. It + """Service message: the channel has been created. This field can't be received in a message + coming through updates, because bot can't be a member of a channel when it is created. It can only be found in reply_to_message if someone replies to a very first message in a channel.""" migrate_to_chat_id: Optional[int] = None diff --git a/aiogram/api/types/update.py b/aiogram/api/types/update.py index fa89aa74..84803baa 100644 --- a/aiogram/api/types/update.py +++ b/aiogram/api/types/update.py @@ -24,8 +24,8 @@ class Update(TelegramObject): """ update_id: int - """The update‘s unique identifier. Update identifiers start from a certain positive number and - increase sequentially. This ID becomes especially handy if you’re using Webhooks, since it + """The update's unique identifier. Update identifiers start from a certain positive number and + increase sequentially. This ID becomes especially handy if you're using Webhooks, since it allows you to ignore repeated updates or to restore the correct update sequence, should they get out of order. If there are no new updates for at least a week, then identifier of the next update will be chosen randomly instead of sequentially.""" diff --git a/aiogram/api/types/user.py b/aiogram/api/types/user.py index e3a9eee1..15c87c12 100644 --- a/aiogram/api/types/user.py +++ b/aiogram/api/types/user.py @@ -17,11 +17,11 @@ class User(TelegramObject): is_bot: bool """True, if this user is a bot""" first_name: str - """User‘s or bot’s first name""" + """User's or bot's first name""" last_name: Optional[str] = None - """User‘s or bot’s last name""" + """User's or bot's last name""" username: Optional[str] = None - """User‘s or bot’s username""" + """User's or bot's username""" language_code: Optional[str] = None """IETF language tag of the user's language""" can_join_groups: Optional[bool] = None diff --git a/docs/_api_version.md b/docs/_api_version.md index ef216a53..86a9588a 100644 --- a/docs/_api_version.md +++ b/docs/_api_version.md @@ -1 +1 @@ -4.8 +4.9 diff --git a/docs/_package_version.md b/docs/_package_version.md index 255dd065..78e56ffb 100644 --- a/docs/_package_version.md +++ b/docs/_package_version.md @@ -1 +1 @@ -3.0.0a4 +3.0.0a5 diff --git a/poetry.lock b/poetry.lock index 72a5c042..d81c8b2f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -130,7 +130,7 @@ description = "Specifications for callback functions passed in to an API" name = "backcall" optional = false python-versions = "*" -version = "0.1.0" +version = "0.2.0" [[package]] category = "dev" @@ -191,7 +191,7 @@ description = "Python package for providing Mozilla's CA Bundle." name = "certifi" optional = false python-versions = "*" -version = "2020.4.5.1" +version = "2020.4.5.2" [[package]] category = "dev" @@ -322,7 +322,7 @@ description = "the modular source code checker: pep8 pyflakes and co" name = "flake8" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "3.8.2" +version = "3.8.3" [package.dependencies] mccabe = ">=0.6.0,<0.7.0" @@ -380,7 +380,7 @@ description = "File identification library for Python" name = "identify" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "1.4.16" +version = "1.4.19" [package.extras] license = ["editdistance"] @@ -414,14 +414,14 @@ description = "Read metadata from Python packages" name = "importlib-metadata" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -version = "1.6.0" +version = "1.6.1" [package.dependencies] zipp = ">=0.5" [package.extras] docs = ["sphinx", "rst.linker"] -testing = ["packaging", "importlib-resources"] +testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] [[package]] category = "dev" @@ -429,7 +429,7 @@ description = "IPython: Productive Interactive Computing" name = "ipython" optional = false python-versions = ">=3.6" -version = "7.14.0" +version = "7.15.0" [package.dependencies] appnope = "*" @@ -445,7 +445,7 @@ setuptools = ">=18.5" traitlets = ">=4.2" [package.extras] -all = ["nose (>=0.10.1)", "Sphinx (>=1.3)", "testpath", "nbformat", "ipywidgets", "qtconsole", "numpy (>=1.14)", "notebook", "ipyparallel", "ipykernel", "pygments", "requests", "nbconvert"] +all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.14)", "pygments", "qtconsole", "requests", "testpath"] doc = ["Sphinx (>=1.3)"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] @@ -576,11 +576,14 @@ description = "Python LiveReload is an awesome tool for web developers" name = "livereload" optional = false python-versions = "*" -version = "2.6.1" +version = "2.6.2" [package.dependencies] six = "*" -tornado = "*" + +[package.dependencies.tornado] +python = ">=2.8" +version = "*" [[package]] category = "dev" @@ -715,7 +718,7 @@ description = "More routines for operating on iterables, beyond itertools" name = "more-itertools" optional = false python-versions = ">=3.5" -version = "8.3.0" +version = "8.4.0" [[package]] category = "dev" @@ -786,7 +789,7 @@ description = "Node.js virtual environment builder" name = "nodeenv" optional = false python-versions = "*" -version = "1.3.5" +version = "1.4.0" [[package]] category = "dev" @@ -879,7 +882,7 @@ description = "Python dependency management and packaging made easy." name = "poetry" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.0.5" +version = "1.0.9" [package.dependencies] cachy = ">=0.3.0,<0.4.0" @@ -914,7 +917,7 @@ description = "A framework for managing and maintaining multi-language pre-commi name = "pre-commit" optional = false python-versions = ">=3.6.1" -version = "2.4.0" +version = "2.5.1" [package.dependencies] cfgv = ">=2.0.0" @@ -942,7 +945,6 @@ wcwidth = "*" [[package]] category = "dev" description = "Run a subprocess in a pseudo terminal" -marker = "sys_platform != \"win32\"" name = "ptyprocess" optional = false python-versions = "*" @@ -1046,7 +1048,7 @@ description = "pytest: simple powerful testing with Python" name = "pytest" optional = false python-versions = ">=3.5" -version = "5.4.2" +version = "5.4.3" [package.dependencies] atomicwrites = ">=1.0" @@ -1086,11 +1088,11 @@ description = "Pytest plugin for measuring coverage." name = "pytest-cov" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "2.9.0" +version = "2.10.0" [package.dependencies] coverage = ">=4.4" -pytest = ">=3.6" +pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "pytest-xdist", "virtualenv"] @@ -1184,7 +1186,7 @@ description = "Alternative regular expression module, to replace re." name = "regex" optional = false python-versions = "*" -version = "2020.5.14" +version = "2020.6.8" [[package]] category = "dev" @@ -1275,7 +1277,7 @@ marker = "python_version > \"2.7\"" name = "tqdm" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "4.46.0" +version = "4.46.1" [package.extras] dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown"] @@ -1340,7 +1342,7 @@ description = "Virtual Python Environment builder" name = "virtualenv" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "20.0.21" +version = "20.0.23" [package.dependencies] appdirs = ">=1.4.3,<2" @@ -1354,15 +1356,15 @@ version = ">=0.12,<2" [package.extras] docs = ["sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)", "proselint (>=0.10.2)"] -testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout", "packaging (>=20.0)", "xonsh (>=0.9.16)"] +testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "flaky (>=3)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] [[package]] category = "dev" -description = "Measures number of Terminal column cells of wide-character codes" +description = "Measures the displayed width of unicode strings in a terminal" name = "wcwidth" optional = false python-versions = "*" -version = "0.1.9" +version = "0.2.4" [[package]] category = "dev" @@ -1463,8 +1465,8 @@ babel = [ {file = "Babel-2.8.0.tar.gz", hash = "sha256:1aac2ae2d0d8ea368fa90906567f5c08463d98ade155c0c4bfedd6a0f7160e38"}, ] backcall = [ - {file = "backcall-0.1.0.tar.gz", hash = "sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4"}, - {file = "backcall-0.1.0.zip", hash = "sha256:bbbf4b1e5cd2bdb08f915895b51081c041bac22394fdfcfdfbe9f14b77c08bf2"}, + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] black = [ {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, @@ -1479,8 +1481,8 @@ cachy = [ {file = "cachy-0.3.0.tar.gz", hash = "sha256:186581f4ceb42a0bbe040c407da73c14092379b1e4c0e327fdb72ae4a9b269b1"}, ] certifi = [ - {file = "certifi-2020.4.5.1-py2.py3-none-any.whl", hash = "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304"}, - {file = "certifi-2020.4.5.1.tar.gz", hash = "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519"}, + {file = "certifi-2020.4.5.2-py2.py3-none-any.whl", hash = "sha256:9cd41137dc19af6a5e03b630eefe7d1f458d964d406342dd3edf625839b944cc"}, + {file = "certifi-2020.4.5.2.tar.gz", hash = "sha256:5ad7e9a056d25ffa5082862e36f119f7f7cec6457fa07ee2f8c339814b80c9b1"}, ] cffi = [ {file = "cffi-1.14.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1cae98a7054b5c9391eb3249b86e0e99ab1e02bb0cc0575da191aedadbdf4384"}, @@ -1602,8 +1604,8 @@ filelock = [ {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, ] flake8 = [ - {file = "flake8-3.8.2-py2.py3-none-any.whl", hash = "sha256:ccaa799ef9893cebe69fdfefed76865aeaefbb94cb8545617b2298786a4de9a5"}, - {file = "flake8-3.8.2.tar.gz", hash = "sha256:c69ac1668e434d37a2d2880b3ca9aafd54b3a10a3ac1ab101d22f29e29cf8634"}, + {file = "flake8-3.8.3-py2.py3-none-any.whl", hash = "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c"}, + {file = "flake8-3.8.3.tar.gz", hash = "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208"}, ] flake8-html = [ {file = "flake8-html-0.4.1.tar.gz", hash = "sha256:2fb436cbfe1e109275bc8fb7fdd0cb00e67b3b48cfeb397309b6b2c61eeb4cb4"}, @@ -1617,8 +1619,8 @@ html5lib = [ {file = "html5lib-1.0.1.tar.gz", hash = "sha256:66cb0dcfdbbc4f9c3ba1a63fdb511ffdbd4f513b2b6d81b80cd26ce6b3fb3736"}, ] identify = [ - {file = "identify-1.4.16-py2.py3-none-any.whl", hash = "sha256:0f3c3aac62b51b86fea6ff52fe8ff9e06f57f10411502443809064d23e16f1c2"}, - {file = "identify-1.4.16.tar.gz", hash = "sha256:f9ad3d41f01e98eb066b6e05c5b184fd1e925fadec48eb165b4e01c72a1ef3a7"}, + {file = "identify-1.4.19-py2.py3-none-any.whl", hash = "sha256:781fd3401f5d2b17b22a8b18b493a48d5d948e3330634e82742e23f9c20234ef"}, + {file = "identify-1.4.19.tar.gz", hash = "sha256:249ebc7e2066d6393d27c1b1be3b70433f824a120b1d8274d362f1eb419e3b52"}, ] idna = [ {file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"}, @@ -1627,12 +1629,12 @@ idna = [ importlib-metadata = [ {file = "importlib_metadata-1.1.3-py2.py3-none-any.whl", hash = "sha256:7c7f8ac40673f507f349bef2eed21a0e5f01ddf5b2a7356a6c65eb2099b53764"}, {file = "importlib_metadata-1.1.3.tar.gz", hash = "sha256:7a99fb4084ffe6dae374961ba7a6521b79c1d07c658ab3a28aa264ee1d1b14e3"}, - {file = "importlib_metadata-1.6.0-py2.py3-none-any.whl", hash = "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f"}, - {file = "importlib_metadata-1.6.0.tar.gz", hash = "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e"}, + {file = "importlib_metadata-1.6.1-py2.py3-none-any.whl", hash = "sha256:15ec6c0fd909e893e3a08b3a7c76ecb149122fb14b7efe1199ddd4c7c57ea958"}, + {file = "importlib_metadata-1.6.1.tar.gz", hash = "sha256:0505dd08068cfec00f53a74a0ad927676d7757da81b7436a6eefe4c7cf75c545"}, ] ipython = [ - {file = "ipython-7.14.0-py3-none-any.whl", hash = "sha256:5b241b84bbf0eb085d43ae9d46adf38a13b45929ca7774a740990c2c242534bb"}, - {file = "ipython-7.14.0.tar.gz", hash = "sha256:f0126781d0f959da852fb3089e170ed807388e986a8dd4e6ac44855845b0fb1c"}, + {file = "ipython-7.15.0-py3-none-any.whl", hash = "sha256:1b85d65632211bf5d3e6f1406f3393c8c429a47d7b947b9a87812aa5bce6595c"}, + {file = "ipython-7.15.0.tar.gz", hash = "sha256:0ef1433879816a960cd3ae1ae1dc82c64732ca75cec8dab5a4e29783fb571d0e"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, @@ -1667,8 +1669,7 @@ keyring = [ {file = "keyring-20.0.1.tar.gz", hash = "sha256:963bfa7f090269d30bdc5e25589e5fd9dad2cf2a7c6f176a7f2386910e5d0d8d"}, ] livereload = [ - {file = "livereload-2.6.1-py2.py3-none-any.whl", hash = "sha256:78d55f2c268a8823ba499305dcac64e28ddeb9a92571e12d543cd304faf5817b"}, - {file = "livereload-2.6.1.tar.gz", hash = "sha256:89254f78d7529d7ea0a3417d224c34287ebfe266b05e67e51facaf82c27f0f66"}, + {file = "livereload-2.6.2.tar.gz", hash = "sha256:d1eddcb5c5eb8d2ca1fa1f750e580da624c0f7fcb734aa5780dc81b7dcbd89be"}, ] lockfile = [ {file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"}, @@ -1760,8 +1761,8 @@ mkdocs-material = [ {file = "mkdocs_material-4.6.3-py2.py3-none-any.whl", hash = "sha256:7f3afa0a09c07d0b89a6a9755fdb00513aee8f0cec3538bb903325c80f66f444"}, ] more-itertools = [ - {file = "more-itertools-8.3.0.tar.gz", hash = "sha256:558bb897a2232f5e4f8e2399089e35aecb746e1f9191b6584a151647e89267be"}, - {file = "more_itertools-8.3.0-py3-none-any.whl", hash = "sha256:7818f596b1e87be009031c7653d01acc46ed422e6656b394b0f765ce66ed4982"}, + {file = "more-itertools-8.4.0.tar.gz", hash = "sha256:68c70cc7167bdf5c7c9d8f6954a7837089c6a36bf565383919bb595efb8a17e5"}, + {file = "more_itertools-8.4.0-py3-none-any.whl", hash = "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2"}, ] msgpack = [ {file = "msgpack-1.0.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:cec8bf10981ed70998d98431cd814db0ecf3384e6b113366e7f36af71a0fca08"}, @@ -1826,7 +1827,7 @@ nltk = [ {file = "nltk-3.5.zip", hash = "sha256:845365449cd8c5f9731f7cb9f8bd6fd0767553b9d53af9eb1b3abf7700936b35"}, ] nodeenv = [ - {file = "nodeenv-1.3.5-py2.py3-none-any.whl", hash = "sha256:5b2438f2e42af54ca968dd1b374d14a1194848955187b0e5e4be1f73813a5212"}, + {file = "nodeenv-1.4.0-py2.py3-none-any.whl", hash = "sha256:4b0b77afa3ba9b54f4b6396e60b0c83f59eaeb2d63dc3cc7a70f7f4af96c82bc"}, ] packaging = [ {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, @@ -1861,12 +1862,12 @@ pluggy = [ {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] poetry = [ - {file = "poetry-1.0.5-py2.py3-none-any.whl", hash = "sha256:81cdb3c708fe03cdef484ccd6c3becc74811dce2b15cb67444c2495b1240a278"}, - {file = "poetry-1.0.5.tar.gz", hash = "sha256:8e195ea8a4bce4f418a23fd828aa2f9ce06be7655720efd1d95beb0ee641030a"}, + {file = "poetry-1.0.9-py2.py3-none-any.whl", hash = "sha256:27e0c9c16f785156a8d8d0e98a73e239c8d2083306c180718825d11d5664aea0"}, + {file = "poetry-1.0.9.tar.gz", hash = "sha256:0a4c56983546964b47cbbe0e1b49fef5662277bbf0673e3e350e1215560377ab"}, ] pre-commit = [ - {file = "pre_commit-2.4.0-py2.py3-none-any.whl", hash = "sha256:5559e09afcac7808933951ffaf4ff9aac524f31efbc3f24d021540b6c579813c"}, - {file = "pre_commit-2.4.0.tar.gz", hash = "sha256:703e2e34cbe0eedb0d319eff9f7b83e2022bb5a3ab5289a6a8841441076514d0"}, + {file = "pre_commit-2.5.1-py2.py3-none-any.whl", hash = "sha256:c5c8fd4d0e1c363723aaf0a8f9cba0f434c160b48c4028f4bae6d219177945b3"}, + {file = "pre_commit-2.5.1.tar.gz", hash = "sha256:da463cf8f0e257f9af49047ba514f6b90dbd9b4f92f4c8847a3ccd36834874c7"}, ] prompt-toolkit = [ {file = "prompt_toolkit-3.0.5-py3-none-any.whl", hash = "sha256:df7e9e63aea609b1da3a65641ceaf5bc7d05e0a04de5bd45d05dbeffbabf9e04"}, @@ -1931,16 +1932,16 @@ pyrsistent = [ {file = "pyrsistent-0.14.11.tar.gz", hash = "sha256:3ca82748918eb65e2d89f222b702277099aca77e34843c5eb9d52451173970e2"}, ] pytest = [ - {file = "pytest-5.4.2-py3-none-any.whl", hash = "sha256:95c710d0a72d91c13fae35dce195633c929c3792f54125919847fdcdf7caa0d3"}, - {file = "pytest-5.4.2.tar.gz", hash = "sha256:eb2b5e935f6a019317e455b6da83dd8650ac9ffd2ee73a7b657a30873d67a698"}, + {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, + {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, ] pytest-asyncio = [ {file = "pytest-asyncio-0.10.0.tar.gz", hash = "sha256:9fac5100fd716cbecf6ef89233e8590a4ad61d729d1732e0a96b84182df1daaf"}, {file = "pytest_asyncio-0.10.0-py3-none-any.whl", hash = "sha256:d734718e25cfc32d2bf78d346e99d33724deeba774cc4afdf491530c6184b63b"}, ] pytest-cov = [ - {file = "pytest-cov-2.9.0.tar.gz", hash = "sha256:b6a814b8ed6247bd81ff47f038511b57fe1ce7f4cc25b9106f1a4b106f1d9322"}, - {file = "pytest_cov-2.9.0-py2.py3-none-any.whl", hash = "sha256:c87dfd8465d865655a8213859f1b4749b43448b5fae465cb981e16d52a811424"}, + {file = "pytest-cov-2.10.0.tar.gz", hash = "sha256:1a629dc9f48e53512fcbfda6b07de490c374b0c83c55ff7a1720b3fccff0ac87"}, + {file = "pytest_cov-2.10.0-py2.py3-none-any.whl", hash = "sha256:6e6d18092dce6fad667cd7020deed816f858ad3b49d5b5e2b1cc1c97a4dba65c"}, ] pytest-html = [ {file = "pytest-html-2.1.1.tar.gz", hash = "sha256:6a4ac391e105e391208e3eb9bd294a60dd336447fd8e1acddff3a6de7f4e57c5"}, @@ -1980,27 +1981,27 @@ pyyaml = [ {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, ] regex = [ - {file = "regex-2020.5.14-cp27-cp27m-win32.whl", hash = "sha256:e565569fc28e3ba3e475ec344d87ed3cd8ba2d575335359749298a0899fe122e"}, - {file = "regex-2020.5.14-cp27-cp27m-win_amd64.whl", hash = "sha256:d466967ac8e45244b9dfe302bbe5e3337f8dc4dec8d7d10f5e950d83b140d33a"}, - {file = "regex-2020.5.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:27ff7325b297fb6e5ebb70d10437592433601c423f5acf86e5bc1ee2919b9561"}, - {file = "regex-2020.5.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ea55b80eb0d1c3f1d8d784264a6764f931e172480a2f1868f2536444c5f01e01"}, - {file = "regex-2020.5.14-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:c9bce6e006fbe771a02bda468ec40ffccbf954803b470a0345ad39c603402577"}, - {file = "regex-2020.5.14-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:d881c2e657c51d89f02ae4c21d9adbef76b8325fe4d5cf0e9ad62f850f3a98fd"}, - {file = "regex-2020.5.14-cp36-cp36m-win32.whl", hash = "sha256:99568f00f7bf820c620f01721485cad230f3fb28f57d8fbf4a7967ec2e446994"}, - {file = "regex-2020.5.14-cp36-cp36m-win_amd64.whl", hash = "sha256:70c14743320a68c5dac7fc5a0f685be63bc2024b062fe2aaccc4acc3d01b14a1"}, - {file = "regex-2020.5.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a7c37f048ec3920783abab99f8f4036561a174f1314302ccfa4e9ad31cb00eb4"}, - {file = "regex-2020.5.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:89d76ce33d3266173f5be80bd4efcbd5196cafc34100fdab814f9b228dee0fa4"}, - {file = "regex-2020.5.14-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:51f17abbe973c7673a61863516bdc9c0ef467407a940f39501e786a07406699c"}, - {file = "regex-2020.5.14-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:ce5cc53aa9fbbf6712e92c7cf268274eaff30f6bd12a0754e8133d85a8fb0f5f"}, - {file = "regex-2020.5.14-cp37-cp37m-win32.whl", hash = "sha256:8044d1c085d49673aadb3d7dc20ef5cb5b030c7a4fa253a593dda2eab3059929"}, - {file = "regex-2020.5.14-cp37-cp37m-win_amd64.whl", hash = "sha256:c2062c7d470751b648f1cacc3f54460aebfc261285f14bc6da49c6943bd48bdd"}, - {file = "regex-2020.5.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:329ba35d711e3428db6b45a53b1b13a0a8ba07cbbcf10bbed291a7da45f106c3"}, - {file = "regex-2020.5.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:579ea215c81d18da550b62ff97ee187b99f1b135fd894a13451e00986a080cad"}, - {file = "regex-2020.5.14-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:3a9394197664e35566242686d84dfd264c07b20f93514e2e09d3c2b3ffdf78fe"}, - {file = "regex-2020.5.14-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ce367d21f33e23a84fb83a641b3834dd7dd8e9318ad8ff677fbfae5915a239f7"}, - {file = "regex-2020.5.14-cp38-cp38-win32.whl", hash = "sha256:1386e75c9d1574f6aa2e4eb5355374c8e55f9aac97e224a8a5a6abded0f9c927"}, - {file = "regex-2020.5.14-cp38-cp38-win_amd64.whl", hash = "sha256:7e61be8a2900897803c293247ef87366d5df86bf701083b6c43119c7c6c99108"}, - {file = "regex-2020.5.14.tar.gz", hash = "sha256:ce450ffbfec93821ab1fea94779a8440e10cf63819be6e176eb1973a6017aff5"}, + {file = "regex-2020.6.8-cp27-cp27m-win32.whl", hash = "sha256:fbff901c54c22425a5b809b914a3bfaf4b9570eee0e5ce8186ac71eb2025191c"}, + {file = "regex-2020.6.8-cp27-cp27m-win_amd64.whl", hash = "sha256:112e34adf95e45158c597feea65d06a8124898bdeac975c9087fe71b572bd938"}, + {file = "regex-2020.6.8-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:92d8a043a4241a710c1cf7593f5577fbb832cf6c3a00ff3fc1ff2052aff5dd89"}, + {file = "regex-2020.6.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bae83f2a56ab30d5353b47f9b2a33e4aac4de9401fb582b55c42b132a8ac3868"}, + {file = "regex-2020.6.8-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:b2ba0f78b3ef375114856cbdaa30559914d081c416b431f2437f83ce4f8b7f2f"}, + {file = "regex-2020.6.8-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:95fa7726d073c87141f7bbfb04c284901f8328e2d430eeb71b8ffdd5742a5ded"}, + {file = "regex-2020.6.8-cp36-cp36m-win32.whl", hash = "sha256:e3cdc9423808f7e1bb9c2e0bdb1c9dc37b0607b30d646ff6faf0d4e41ee8fee3"}, + {file = "regex-2020.6.8-cp36-cp36m-win_amd64.whl", hash = "sha256:c78e66a922de1c95a208e4ec02e2e5cf0bb83a36ceececc10a72841e53fbf2bd"}, + {file = "regex-2020.6.8-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:08997a37b221a3e27d68ffb601e45abfb0093d39ee770e4257bd2f5115e8cb0a"}, + {file = "regex-2020.6.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2f6f211633ee8d3f7706953e9d3edc7ce63a1d6aad0be5dcee1ece127eea13ae"}, + {file = "regex-2020.6.8-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:55b4c25cbb3b29f8d5e63aeed27b49fa0f8476b0d4e1b3171d85db891938cc3a"}, + {file = "regex-2020.6.8-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:89cda1a5d3e33ec9e231ece7307afc101b5217523d55ef4dc7fb2abd6de71ba3"}, + {file = "regex-2020.6.8-cp37-cp37m-win32.whl", hash = "sha256:690f858d9a94d903cf5cada62ce069b5d93b313d7d05456dbcd99420856562d9"}, + {file = "regex-2020.6.8-cp37-cp37m-win_amd64.whl", hash = "sha256:1700419d8a18c26ff396b3b06ace315b5f2a6e780dad387e4c48717a12a22c29"}, + {file = "regex-2020.6.8-cp38-cp38-manylinux1_i686.whl", hash = "sha256:654cb773b2792e50151f0e22be0f2b6e1c3a04c5328ff1d9d59c0398d37ef610"}, + {file = "regex-2020.6.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:52e1b4bef02f4040b2fd547357a170fc1146e60ab310cdbdd098db86e929b387"}, + {file = "regex-2020.6.8-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:cf59bbf282b627130f5ba68b7fa3abdb96372b24b66bdf72a4920e8153fc7910"}, + {file = "regex-2020.6.8-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:5aaa5928b039ae440d775acea11d01e42ff26e1561c0ffcd3d805750973c6baf"}, + {file = "regex-2020.6.8-cp38-cp38-win32.whl", hash = "sha256:97712e0d0af05febd8ab63d2ef0ab2d0cd9deddf4476f7aa153f76feef4b2754"}, + {file = "regex-2020.6.8-cp38-cp38-win_amd64.whl", hash = "sha256:6ad8663c17db4c5ef438141f99e291c4d4edfeaacc0ce28b5bba2b0bf273d9b5"}, + {file = "regex-2020.6.8.tar.gz", hash = "sha256:e9b64e609d37438f7d6e68c2546d2cb8062f3adb27e6336bc129b51be20773ac"}, ] requests = [ {file = "requests-2.23.0-py2.py3-none-any.whl", hash = "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee"}, @@ -2042,8 +2043,8 @@ tornado = [ {file = "tornado-6.0.4.tar.gz", hash = "sha256:0fe2d45ba43b00a41cd73f8be321a44936dc1aba233dee979f17a042b83eb6dc"}, ] tqdm = [ - {file = "tqdm-4.46.0-py2.py3-none-any.whl", hash = "sha256:acdafb20f51637ca3954150d0405ff1a7edde0ff19e38fb99a80a66210d2a28f"}, - {file = "tqdm-4.46.0.tar.gz", hash = "sha256:4733c4a10d0f2a4d098d801464bdaf5240c7dadd2a7fde4ee93b0a0efd9fb25e"}, + {file = "tqdm-4.46.1-py2.py3-none-any.whl", hash = "sha256:07c06493f1403c1380b630ae3dcbe5ae62abcf369a93bbc052502279f189ab8c"}, + {file = "tqdm-4.46.1.tar.gz", hash = "sha256:cd140979c2bebd2311dfb14781d8f19bd5a9debb92dcab9f6ef899c987fcf71f"}, ] traitlets = [ {file = "traitlets-4.3.3-py2.py3-none-any.whl", hash = "sha256:70b4c6a1d9019d7b4f6846832288f86998aa3b9207c6821f3578a6a6a467fe44"}, @@ -2093,12 +2094,12 @@ uvloop = [ {file = "uvloop-0.14.0.tar.gz", hash = "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e"}, ] virtualenv = [ - {file = "virtualenv-20.0.21-py2.py3-none-any.whl", hash = "sha256:a730548b27366c5e6cbdf6f97406d861cccece2e22275e8e1a757aeff5e00c70"}, - {file = "virtualenv-20.0.21.tar.gz", hash = "sha256:a116629d4e7f4d03433b8afa27f43deba09d48bc48f5ecefa4f015a178efb6cf"}, + {file = "virtualenv-20.0.23-py2.py3-none-any.whl", hash = "sha256:ccfb8e1e05a1174f7bd4c163700277ba730496094fe1a58bea9d4ac140a207c8"}, + {file = "virtualenv-20.0.23.tar.gz", hash = "sha256:5102fbf1ec57e80671ef40ed98a84e980a71194cedf30c87c2b25c3a9e0b0107"}, ] wcwidth = [ - {file = "wcwidth-0.1.9-py2.py3-none-any.whl", hash = "sha256:cafe2186b3c009a04067022ce1dcd79cb38d8d65ee4f4791b8888d6599d1bbe1"}, - {file = "wcwidth-0.1.9.tar.gz", hash = "sha256:ee73862862a156bf77ff92b09034fc4825dd3af9cf81bc5b360668d425f3c5f1"}, + {file = "wcwidth-0.2.4-py2.py3-none-any.whl", hash = "sha256:79375666b9954d4a1a10739315816324c3e73110af9d0e102d906fdb0aec009f"}, + {file = "wcwidth-0.2.4.tar.gz", hash = "sha256:8c6b5b6ee1360b842645f336d9e5d68c55817c26d3050f46b235ef2bc650e48f"}, ] webencodings = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, diff --git a/pyproject.toml b/pyproject.toml index 2db33c6c..22efdce3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aiogram" -version = "3.0.0-alpha.4" +version = "3.0.0-alpha.5" description = "Modern and fully asynchronous framework for Telegram Bot API" authors = ["Alex Root Junior "] license = "MIT" diff --git a/tests/mocked_bot.py b/tests/mocked_bot.py index 9ee5731c..03242388 100644 --- a/tests/mocked_bot.py +++ b/tests/mocked_bot.py @@ -5,6 +5,7 @@ from aiogram import Bot from aiogram.api.client.session.base import BaseSession from aiogram.api.methods import TelegramMethod from aiogram.api.methods.base import Request, Response, T +from aiogram.api.types import UNSET class MockedSession(BaseSession): @@ -23,7 +24,9 @@ class MockedSession(BaseSession): async def close(self): pass - async def make_request(self, token: str, method: TelegramMethod[T]) -> T: + async def make_request( + self, token: str, method: TelegramMethod[T], timeout: Optional[int] = UNSET + ) -> T: self.requests.append(method.build_request()) response: Response[T] = self.responses.pop() self.raise_for_status(response) diff --git a/tests/test_api/test_client/test_session/test_base_session.py b/tests/test_api/test_client/test_session/test_base_session.py index 3ac1254b..42dfedf7 100644 --- a/tests/test_api/test_client/test_session/test_base_session.py +++ b/tests/test_api/test_client/test_session/test_base_session.py @@ -1,12 +1,13 @@ import datetime import json -from typing import AsyncContextManager, AsyncGenerator +from typing import AsyncContextManager, AsyncGenerator, Optional import pytest from aiogram.api.client.session.base import BaseSession, T from aiogram.api.client.telegram import PRODUCTION, TelegramAPIServer from aiogram.api.methods import GetMe, Response, TelegramMethod +from aiogram.api.types import UNSET try: from asynctest import CoroutineMock, patch @@ -18,7 +19,7 @@ class CustomSession(BaseSession): async def close(self): pass - async def make_request(self, token: str, method: TelegramMethod[T]) -> None: # type: ignore + async def make_request(self, token: str, method: TelegramMethod[T], timeout: Optional[int] = UNSET) -> None: # type: ignore assert isinstance(token, str) assert isinstance(method, TelegramMethod) diff --git a/tests/test_api/test_types/test_chat_member.py b/tests/test_api/test_types/test_chat_member.py index e5706e5e..bb88e690 100644 --- a/tests/test_api/test_types/test_chat_member.py +++ b/tests/test_api/test_types/test_chat_member.py @@ -7,12 +7,7 @@ user = User(id=42, is_bot=False, first_name="User", last_name=None) class TestChatMember: @pytest.mark.parametrize( - "status,result", - [ - ["administrator", True], - ["creator", True], - ["member", False] - ] + "status,result", [["administrator", True], ["creator", True], ["member", False]] ) def test_is_chat_admin(self, status: str, result: bool): chat_member = ChatMember(user=user, status=status) @@ -26,8 +21,8 @@ class TestChatMember: ["member", True], ["restricted", True], ["kicked", False], - ["left", False] - ] + ["left", False], + ], ) def test_is_chat_member(self, status: str, result: bool): chat_member = ChatMember(user=user, status=status)