diff --git a/.apiversion b/.apiversion index 4074fe20..341291e5 100644 --- a/.apiversion +++ b/.apiversion @@ -1 +1 @@ -6.6 +6.7 diff --git a/.butcher/enums/EncryptedPassportElement.yml b/.butcher/enums/EncryptedPassportElement.yml new file mode 100644 index 00000000..e0540d7f --- /dev/null +++ b/.butcher/enums/EncryptedPassportElement.yml @@ -0,0 +1,10 @@ +name: EncryptedPassportElement +description: | + This object represents type of encrypted passport element. + + Source: https://core.telegram.org/bots/api#encryptedpassportelement +parse: + entity: EncryptedPassportElement + category: types + attribute: type + regexp: "'([a-z_]+)'" diff --git a/.butcher/enums/InlineQueryResultType.yml b/.butcher/enums/InlineQueryResultType.yml index 74428a3c..2d823438 100644 --- a/.butcher/enums/InlineQueryResultType.yml +++ b/.butcher/enums/InlineQueryResultType.yml @@ -5,7 +5,7 @@ description: | Source: https://core.telegram.org/bots/api#inlinequeryresult multi_parse: attribute: type - regexp: "must be ([a-z_]+)" + regexp: "must be ([a-z_0-9]+)" entities: - InlineQueryResultCachedAudio - InlineQueryResultCachedDocument diff --git a/.butcher/enums/PassportElementErrorType.yml b/.butcher/enums/PassportElementErrorType.yml new file mode 100644 index 00000000..d5d52aeb --- /dev/null +++ b/.butcher/enums/PassportElementErrorType.yml @@ -0,0 +1,18 @@ +name: PassportElementErrorType +description: | + This object represents a passport element error type. + + Source: https://core.telegram.org/bots/api#passportelementerror +multi_parse: + attribute: source + regexp: 'must be ([a-z_]+)' + entities: + - PassportElementErrorDataField + - PassportElementErrorFrontSide + - PassportElementErrorReverseSide + - PassportElementErrorSelfie + - PassportElementErrorFile + - PassportElementErrorFiles + - PassportElementErrorTranslationFile + - PassportElementErrorTranslationFiles + - PassportElementErrorUnspecified diff --git a/.butcher/methods/answerInlineQuery/entity.json b/.butcher/methods/answerInlineQuery/entity.json index 410c1ef4..0a15ee68 100644 --- a/.butcher/methods/answerInlineQuery/entity.json +++ b/.butcher/methods/answerInlineQuery/entity.json @@ -38,9 +38,9 @@ { "type": "Boolean", "required": false, - "description": "Pass True if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query", - "html_description": "Pass True if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query", - "rst_description": "Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query\n", + "description": "Pass True if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query.", + "html_description": "Pass True if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query.", + "rst_description": "Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query.\n", "name": "is_personal" }, { @@ -52,12 +52,12 @@ "name": "next_offset" }, { - "type": "String", + "type": "InlineQueryResultsButton", "required": false, - "description": "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", - "html_description": "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", - "rst_description": "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*\n", - "name": "switch_pm_text" + "description": "A JSON-serialized object describing a button to be shown above inline query results", + "html_description": "A JSON-serialized object describing a button to be shown above inline query results", + "rst_description": "A JSON-serialized object describing a button to be shown above inline query results\n", + "name": "button" }, { "type": "String", @@ -65,7 +65,23 @@ "description": "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.\n\nExample: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a switch_inline button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.", "html_description": "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.
\n
\nExample: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a switch_inline button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.", "rst_description": "`Deep-linking `_ parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed.\n\n\n\n*Example:* An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a `https://core.telegram.org/bots/api#inlinekeyboardmarkup `_ *switch_inline* button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.\n", - "name": "switch_pm_parameter" + "name": "switch_pm_parameter", + "deprecated": { + "version": "6.7", + "release_date": "2023-04-21" + } + }, + { + "type": "String", + "required": false, + "description": "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", + "html_description": "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", + "rst_description": "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*\n", + "name": "switch_pm_text", + "deprecated": { + "version": "6.7", + "release_date": "2023-04-21" + } } ], "category": "methods" diff --git a/.butcher/methods/getMyName/entity.json b/.butcher/methods/getMyName/entity.json new file mode 100644 index 00000000..848fcb86 --- /dev/null +++ b/.butcher/methods/getMyName/entity.json @@ -0,0 +1,25 @@ +{ + "meta": {}, + "group": { + "title": "Available methods", + "anchor": "available-methods" + }, + "object": { + "anchor": "getmyname", + "name": "getMyName", + "description": "Use this method to get the current bot name for the given user language. Returns BotName on success.", + "html_description": "

Use this method to get the current bot name for the given user language. Returns BotName on success.

", + "rst_description": "Use this method to get the current bot name for the given user language. Returns :class:`aiogram.types.bot_name.BotName` on success.", + "annotations": [ + { + "type": "String", + "required": false, + "description": "A two-letter ISO 639-1 language code or an empty string", + "html_description": "A two-letter ISO 639-1 language code or an empty string", + "rst_description": "A two-letter ISO 639-1 language code or an empty string\n", + "name": "language_code" + } + ], + "category": "methods" + } +} diff --git a/.butcher/methods/getUpdates/entity.json b/.butcher/methods/getUpdates/entity.json index 1a5eb7eb..6163ad20 100644 --- a/.butcher/methods/getUpdates/entity.json +++ b/.butcher/methods/getUpdates/entity.json @@ -14,9 +14,9 @@ { "type": "Integer", "required": false, - "description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will forgotten.", - "html_description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will forgotten.", - "rst_description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as :class:`aiogram.methods.get_updates.GetUpdates` is called with an *offset* higher than its *update_id*. The negative offset can be specified to retrieve updates starting from *-offset* update from the end of the updates queue. All previous updates will forgotten.\n", + "description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will be forgotten.", + "html_description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will be forgotten.", + "rst_description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as :class:`aiogram.methods.get_updates.GetUpdates` is called with an *offset* higher than its *update_id*. The negative offset can be specified to retrieve updates starting from *-offset* update from the end of the updates queue. All previous updates will be forgotten.\n", "name": "offset" }, { diff --git a/.butcher/methods/setMyName/entity.json b/.butcher/methods/setMyName/entity.json new file mode 100644 index 00000000..e6461251 --- /dev/null +++ b/.butcher/methods/setMyName/entity.json @@ -0,0 +1,33 @@ +{ + "meta": {}, + "group": { + "title": "Available methods", + "anchor": "available-methods" + }, + "object": { + "anchor": "setmyname", + "name": "setMyName", + "description": "Use this method to change the bot's name. Returns True on success.", + "html_description": "

Use this method to change the bot's name. Returns True on success.

", + "rst_description": "Use this method to change the bot's name. Returns :code:`True` on success.", + "annotations": [ + { + "type": "String", + "required": false, + "description": "New bot name; 0-64 characters. Pass an empty string to remove the dedicated name for the given language.", + "html_description": "New bot name; 0-64 characters. Pass an empty string to remove the dedicated name for the given language.", + "rst_description": "New bot name; 0-64 characters. Pass an empty string to remove the dedicated name for the given language.\n", + "name": "name" + }, + { + "type": "String", + "required": false, + "description": "A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose language there is no dedicated name.", + "html_description": "A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose language there is no dedicated name.", + "rst_description": "A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose language there is no dedicated name.\n", + "name": "language_code" + } + ], + "category": "methods" + } +} diff --git a/.butcher/schema/schema.json b/.butcher/schema/schema.json index 02015146..fa7a76d3 100644 --- a/.butcher/schema/schema.json +++ b/.butcher/schema/schema.json @@ -1,7 +1,7 @@ { "api": { - "version": "6.6", - "release_date": "2023-03-09" + "version": "6.7", + "release_date": "2023-04-21" }, "items": [ { @@ -148,9 +148,9 @@ { "type": "Integer", "required": false, - "description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will forgotten.", - "html_description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will forgotten.", - "rst_description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as :class:`aiogram.methods.get_updates.GetUpdates` is called with an *offset* higher than its *update_id*. The negative offset can be specified to retrieve updates starting from *-offset* update from the end of the updates queue. All previous updates will forgotten.\n", + "description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will be forgotten.", + "html_description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will be forgotten.", + "rst_description": "Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as :class:`aiogram.methods.get_updates.GetUpdates` is called with an *offset* higher than its *update_id*. The negative offset can be specified to retrieve updates starting from *-offset* update from the end of the updates queue. All previous updates will be forgotten.\n", "name": "offset" }, { @@ -2421,10 +2421,19 @@ { "anchor": "writeaccessallowed", "name": "WriteAccessAllowed", - "description": "This object represents a service message about a user allowing a bot added to the attachment menu to write messages. Currently holds no information.", - "html_description": "

This object represents a service message about a user allowing a bot added to the attachment menu to write messages. Currently holds no information.

", - "rst_description": "This object represents a service message about a user allowing a bot added to the attachment menu to write messages. Currently holds no information.", - "annotations": [], + "description": "This object represents a service message about a user allowing a bot to write messages after adding the bot to the attachment menu or launching a Web App from a link.", + "html_description": "

This object represents a service message about a user allowing a bot to write messages after adding the bot to the attachment menu or launching a Web App from a link.

", + "rst_description": "This object represents a service message about a user allowing a bot to write messages after adding the bot to the attachment menu or launching a Web App from a link.", + "annotations": [ + { + "type": "String", + "description": "Name of the Web App which was launched from a link", + "html_description": "Optional. Name of the Web App which was launched from a link", + "rst_description": "*Optional*. Name of the Web App which was launched from a link\n", + "name": "web_app_name", + "required": false + } + ], "category": "types" }, { @@ -2704,8 +2713,8 @@ "anchor": "keyboardbuttonrequestuser", "name": "KeyboardButtonRequestUser", "description": "This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed.", - "html_description": "

This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed.

", - "rst_description": "This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed.", + "html_description": "

This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed. More about requesting users »

", + "rst_description": "This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed. `More about requesting users » `_", "annotations": [ { "type": "Integer", @@ -2738,8 +2747,8 @@ "anchor": "keyboardbuttonrequestchat", "name": "KeyboardButtonRequestChat", "description": "This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed.", - "html_description": "

This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed.

", - "rst_description": "This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed.", + "html_description": "

This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed. More about requesting chats »

", + "rst_description": "This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed. `More about requesting chats » `_", "annotations": [ { "type": "Integer", @@ -2919,9 +2928,9 @@ }, { "type": "String", - "description": "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. May be empty, in which case just the bot's username will be inserted.\n\nNote: This offers an easy way for users to start using your bot in inline mode when they are currently in a private chat with it. Especially useful when combined with switch_pm… actions - in this case the user will be automatically returned to the chat they switched from, skipping the chat selection screen.", - "html_description": "Optional. 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. May be empty, in which case just the bot's username will be inserted.
\n
\nNote: This offers an easy way for users to start using your bot in inline mode when they are currently in a private chat with it. Especially useful when combined with switch_pm… actions - in this case the user will be automatically returned to the chat they switched from, skipping the chat selection screen.", - "rst_description": "*Optional*. 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. May be empty, in which case just the bot's username will be inserted.\n\n\n\n**Note:** This offers an easy way for users to start using your bot in `inline mode `_ when they are currently in a private chat with it. Especially useful when combined with `https://core.telegram.org/bots/api#answerinlinequery `_ *switch_pm…* actions - in this case the user will be automatically returned to the chat they switched from, skipping the chat selection screen.\n", + "description": "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. May be empty, in which case just the bot's username will be inserted.", + "html_description": "Optional. 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. May be empty, in which case just the bot's username will be inserted.", + "rst_description": "*Optional*. 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. May be empty, in which case just the bot's username will be inserted.\n", "name": "switch_inline_query", "required": false }, @@ -2933,6 +2942,14 @@ "name": "switch_inline_query_current_chat", "required": false }, + { + "type": "SwitchInlineQueryChosenChat", + "description": "If set, pressing the button will prompt the user to select one of their chats of the specified type, open that chat and insert the bot's username and the specified inline query in the input field", + "html_description": "Optional. If set, pressing the button will prompt the user to select one of their chats of the specified type, open that chat and insert the bot's username and the specified inline query in the input field", + "rst_description": "*Optional*. If set, pressing the button will prompt the user to select one of their chats of the specified type, open that chat and insert the bot's username and the specified inline query in the input field\n", + "name": "switch_inline_query_chosen_chat", + "required": false + }, { "type": "CallbackGame", "description": "Description of the game that will be launched when the user presses the button.\n\nNOTE: This type of button must always be the first button in the first row.", @@ -2994,6 +3011,56 @@ ], "category": "types" }, + { + "anchor": "switchinlinequerychosenchat", + "name": "SwitchInlineQueryChosenChat", + "description": "This object represents an inline button that switches the current user to inline mode in a chosen chat, with an optional default inline query.", + "html_description": "

This object represents an inline button that switches the current user to inline mode in a chosen chat, with an optional default inline query.

", + "rst_description": "This object represents an inline button that switches the current user to inline mode in a chosen chat, with an optional default inline query.", + "annotations": [ + { + "type": "String", + "description": "The default inline query to be inserted in the input field. If left empty, only the bot's username will be inserted", + "html_description": "Optional. The default inline query to be inserted in the input field. If left empty, only the bot's username will be inserted", + "rst_description": "*Optional*. The default inline query to be inserted in the input field. If left empty, only the bot's username will be inserted\n", + "name": "query", + "required": false + }, + { + "type": "Boolean", + "description": "True, if private chats with users can be chosen", + "html_description": "Optional. True, if private chats with users can be chosen", + "rst_description": "*Optional*. True, if private chats with users can be chosen\n", + "name": "allow_user_chats", + "required": false + }, + { + "type": "Boolean", + "description": "True, if private chats with bots can be chosen", + "html_description": "Optional. True, if private chats with bots can be chosen", + "rst_description": "*Optional*. True, if private chats with bots can be chosen\n", + "name": "allow_bot_chats", + "required": false + }, + { + "type": "Boolean", + "description": "True, if group and supergroup chats can be chosen", + "html_description": "Optional. True, if group and supergroup chats can be chosen", + "rst_description": "*Optional*. True, if group and supergroup chats can be chosen\n", + "name": "allow_group_chats", + "required": false + }, + { + "type": "Boolean", + "description": "True, if channel chats can be chosen", + "html_description": "Optional. True, if channel chats can be chosen", + "rst_description": "*Optional*. True, if channel chats can be chosen\n", + "name": "allow_channel_chats", + "required": false + } + ], + "category": "types" + }, { "anchor": "callbackquery", "name": "CallbackQuery", @@ -3807,6 +3874,14 @@ "rst_description": "*Optional*. Chat invite link, which was used by the user to join the chat; for joining by invite link events only.\n", "name": "invite_link", "required": false + }, + { + "type": "Boolean", + "description": "True, if the user joined the chat via a chat folder invite link", + "html_description": "Optional. True, if the user joined the chat via a chat folder invite link", + "rst_description": "*Optional*. True, if the user joined the chat via a chat folder invite link\n", + "name": "via_chat_folder_invite_link", + "required": false } ], "category": "types" @@ -4252,6 +4327,24 @@ ], "category": "types" }, + { + "anchor": "botname", + "name": "BotName", + "description": "This object represents the bot's name.", + "html_description": "

This object represents the bot's name.

", + "rst_description": "This object represents the bot's name.", + "annotations": [ + { + "type": "String", + "description": "The bot's name", + "html_description": "The bot's name", + "rst_description": "The bot's name\n", + "name": "name", + "required": true + } + ], + "category": "types" + }, { "anchor": "botdescription", "name": "BotDescription", @@ -7988,6 +8081,50 @@ ], "category": "methods" }, + { + "anchor": "setmyname", + "name": "setMyName", + "description": "Use this method to change the bot's name. Returns True on success.", + "html_description": "

Use this method to change the bot's name. Returns True on success.

", + "rst_description": "Use this method to change the bot's name. Returns :code:`True` on success.", + "annotations": [ + { + "type": "String", + "required": false, + "description": "New bot name; 0-64 characters. Pass an empty string to remove the dedicated name for the given language.", + "html_description": "New bot name; 0-64 characters. Pass an empty string to remove the dedicated name for the given language.", + "rst_description": "New bot name; 0-64 characters. Pass an empty string to remove the dedicated name for the given language.\n", + "name": "name" + }, + { + "type": "String", + "required": false, + "description": "A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose language there is no dedicated name.", + "html_description": "A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose language there is no dedicated name.", + "rst_description": "A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose language there is no dedicated name.\n", + "name": "language_code" + } + ], + "category": "methods" + }, + { + "anchor": "getmyname", + "name": "getMyName", + "description": "Use this method to get the current bot name for the given user language. Returns BotName on success.", + "html_description": "

Use this method to get the current bot name for the given user language. Returns BotName on success.

", + "rst_description": "Use this method to get the current bot name for the given user language. Returns :class:`aiogram.types.bot_name.BotName` on success.", + "annotations": [ + { + "type": "String", + "required": false, + "description": "A two-letter ISO 639-1 language code or an empty string", + "html_description": "A two-letter ISO 639-1 language code or an empty string", + "rst_description": "A two-letter ISO 639-1 language code or an empty string\n", + "name": "language_code" + } + ], + "category": "methods" + }, { "anchor": "setmydescription", "name": "setMyDescription", @@ -8841,9 +8978,9 @@ "annotations": [ { "type": "InputFile or String", - "description": "The added sticker. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. Animated and video stickers can't be uploaded via HTTP URL. More information on Sending Files", - "html_description": "The added sticker. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. Animated and video stickers can't be uploaded via HTTP URL. More information on Sending Files »", - "rst_description": "The added sticker. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. Animated and video stickers can't be uploaded via HTTP URL. :ref:`More information on Sending Files » `\n", + "description": "The added sticker. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, upload a new one using multipart/form-data, or pass 'attach://' to upload a new one using multipart/form-data under name. Animated and video stickers can't be uploaded via HTTP URL. More information on Sending Files", + "html_description": "The added sticker. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, upload a new one using multipart/form-data, or pass “attach://<file_attach_name>” to upload a new one using multipart/form-data under <file_attach_name> name. Animated and video stickers can't be uploaded via HTTP URL. More information on Sending Files »", + "rst_description": "The added sticker. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, upload a new one using multipart/form-data, or pass 'attach://' to upload a new one using multipart/form-data under name. Animated and video stickers can't be uploaded via HTTP URL. :ref:`More information on Sending Files » `\n", "name": "sticker", "required": true }, @@ -9451,9 +9588,9 @@ { "type": "Boolean", "required": false, - "description": "Pass True if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query", - "html_description": "Pass True if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query", - "rst_description": "Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query\n", + "description": "Pass True if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query.", + "html_description": "Pass True if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query.", + "rst_description": "Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query.\n", "name": "is_personal" }, { @@ -9465,24 +9602,50 @@ "name": "next_offset" }, { - "type": "String", + "type": "InlineQueryResultsButton", "required": false, - "description": "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", - "html_description": "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", - "rst_description": "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*\n", - "name": "switch_pm_text" - }, - { - "type": "String", - "required": false, - "description": "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.\n\nExample: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a switch_inline button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.", - "html_description": "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.
\n
\nExample: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a switch_inline button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.", - "rst_description": "`Deep-linking `_ parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed.\n\n\n\n*Example:* An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a `https://core.telegram.org/bots/api#inlinekeyboardmarkup `_ *switch_inline* button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.\n", - "name": "switch_pm_parameter" + "description": "A JSON-serialized object describing a button to be shown above inline query results", + "html_description": "A JSON-serialized object describing a button to be shown above inline query results", + "rst_description": "A JSON-serialized object describing a button to be shown above inline query results\n", + "name": "button" } ], "category": "methods" }, + { + "anchor": "inlinequeryresultsbutton", + "name": "InlineQueryResultsButton", + "description": "This object represents a button to be shown above inline query results. You must use exactly one of the optional fields.", + "html_description": "

This object represents a button to be shown above inline query results. You must use exactly one of the optional fields.

", + "rst_description": "This object represents a button to be shown above inline query results. You **must** use exactly one of the optional fields.", + "annotations": [ + { + "type": "String", + "description": "Label text on the button", + "html_description": "Label text on the button", + "rst_description": "Label text on the button\n", + "name": "text", + "required": true + }, + { + "type": "WebAppInfo", + "description": "Description of the Web App that will be launched when the user presses the button. The Web App will be able to switch back to the inline mode using the method switchInlineQuery inside the Web App.", + "html_description": "Optional. Description of the Web App that will be launched when the user presses the button. The Web App will be able to switch back to the inline mode using the method switchInlineQuery inside the Web App.", + "rst_description": "*Optional*. Description of the `Web App `_ that will be launched when the user presses the button. The Web App will be able to switch back to the inline mode using the method `switchInlineQuery `_ inside the Web App.\n", + "name": "web_app", + "required": false + }, + { + "type": "String", + "description": "Deep-linking parameter for the /start message sent to the bot when a user presses the button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed.\n\nExample: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a switch_inline button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.", + "html_description": "Optional. Deep-linking parameter for the /start message sent to the bot when a user presses the button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed.
\n
\nExample: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a switch_inline button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.", + "rst_description": "*Optional*. `Deep-linking `_ parameter for the /start message sent to the bot when a user presses the button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed.\n\n\n\n*Example:* An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a `https://core.telegram.org/bots/api#inlinekeyboardmarkup `_ *switch_inline* button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.\n", + "name": "start_parameter", + "required": false + } + ], + "category": "types" + }, { "anchor": "inlinequeryresult", "name": "InlineQueryResult", diff --git a/.butcher/templates/methods/entity.rst.jinja2 b/.butcher/templates/methods/entity.rst.jinja2 index d2843b17..59fa61e2 100755 --- a/.butcher/templates/methods/entity.rst.jinja2 +++ b/.butcher/templates/methods/entity.rst.jinja2 @@ -8,6 +8,7 @@ Returns: :obj:`{{ object.returning.parsed_type|type }}` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/.butcher/templates/types/entity.rst.jinja2 b/.butcher/templates/types/entity.rst.jinja2 index 6b9907c3..2fd2b06e 100644 --- a/.butcher/templates/types/entity.rst.jinja2 +++ b/.butcher/templates/types/entity.rst.jinja2 @@ -7,3 +7,4 @@ :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/.butcher/types/BotCommandScope/subtypes.yml b/.butcher/types/BotCommandScope/subtypes.yml new file mode 100644 index 00000000..6756ad51 --- /dev/null +++ b/.butcher/types/BotCommandScope/subtypes.yml @@ -0,0 +1 @@ +discriminator: "type" diff --git a/.butcher/types/BotCommandScopeAllChatAdministrators/replace.yml b/.butcher/types/BotCommandScopeAllChatAdministrators/replace.yml deleted file mode 100644 index ddb65490..00000000 --- a/.butcher/types/BotCommandScopeAllChatAdministrators/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - BotCommandScope diff --git a/.butcher/types/BotCommandScopeAllGroupChats/replace.yml b/.butcher/types/BotCommandScopeAllGroupChats/replace.yml deleted file mode 100644 index ddb65490..00000000 --- a/.butcher/types/BotCommandScopeAllGroupChats/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - BotCommandScope diff --git a/.butcher/types/BotCommandScopeAllPrivateChats/replace.yml b/.butcher/types/BotCommandScopeAllPrivateChats/replace.yml deleted file mode 100644 index ddb65490..00000000 --- a/.butcher/types/BotCommandScopeAllPrivateChats/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - BotCommandScope diff --git a/.butcher/types/BotCommandScopeChat/replace.yml b/.butcher/types/BotCommandScopeChat/replace.yml deleted file mode 100644 index ddb65490..00000000 --- a/.butcher/types/BotCommandScopeChat/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - BotCommandScope diff --git a/.butcher/types/BotCommandScopeChatAdministrators/replace.yml b/.butcher/types/BotCommandScopeChatAdministrators/replace.yml deleted file mode 100644 index ddb65490..00000000 --- a/.butcher/types/BotCommandScopeChatAdministrators/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - BotCommandScope diff --git a/.butcher/types/BotCommandScopeChatMember/replace.yml b/.butcher/types/BotCommandScopeChatMember/replace.yml deleted file mode 100644 index ddb65490..00000000 --- a/.butcher/types/BotCommandScopeChatMember/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - BotCommandScope diff --git a/.butcher/types/BotCommandScopeDefault/replace.yml b/.butcher/types/BotCommandScopeDefault/replace.yml deleted file mode 100644 index ddb65490..00000000 --- a/.butcher/types/BotCommandScopeDefault/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - BotCommandScope diff --git a/.butcher/types/BotName/entity.json b/.butcher/types/BotName/entity.json new file mode 100644 index 00000000..d18b4902 --- /dev/null +++ b/.butcher/types/BotName/entity.json @@ -0,0 +1,25 @@ +{ + "meta": {}, + "group": { + "title": "Available types", + "anchor": "available-types" + }, + "object": { + "anchor": "botname", + "name": "BotName", + "description": "This object represents the bot's name.", + "html_description": "

This object represents the bot's name.

", + "rst_description": "This object represents the bot's name.", + "annotations": [ + { + "type": "String", + "description": "The bot's name", + "html_description": "The bot's name", + "rst_description": "The bot's name\n", + "name": "name", + "required": true + } + ], + "category": "types" + } +} diff --git a/.butcher/types/ChatMember/extend.yml b/.butcher/types/ChatMember/extend.yml deleted file mode 100644 index 01ef4960..00000000 --- a/.butcher/types/ChatMember/extend.yml +++ /dev/null @@ -1,27 +0,0 @@ -define: - - type: "String" - description: "The member's status in the chat" - html_description: "The member's status in the chat" - rst_description: "The member's status in the chat" - name: "status" - required: true - -clone: - - ChatMemberOwner: - exclude: - - status - - ChatMemberAdministrator: - exclude: - - status - - ChatMemberMember: - exclude: - - status - - ChatMemberRestricted: - exclude: - - status - - ChatMemberLeft: - exclude: - - status - - ChatMemberBanned: - exclude: - - status diff --git a/.butcher/types/ChatMember/subtypes.yml b/.butcher/types/ChatMember/subtypes.yml new file mode 100644 index 00000000..95832398 --- /dev/null +++ b/.butcher/types/ChatMember/subtypes.yml @@ -0,0 +1 @@ +discriminator: "status" diff --git a/.butcher/types/ChatMemberAdministrator/replace.yml b/.butcher/types/ChatMemberAdministrator/replace.yml deleted file mode 100644 index 619942cd..00000000 --- a/.butcher/types/ChatMemberAdministrator/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - ChatMember diff --git a/.butcher/types/ChatMemberBanned/replace.yml b/.butcher/types/ChatMemberBanned/replace.yml index 6a3882af..0af85473 100644 --- a/.butcher/types/ChatMemberBanned/replace.yml +++ b/.butcher/types/ChatMemberBanned/replace.yml @@ -1,5 +1,3 @@ -bases: - - ChatMember annotations: until_date: parsed_type: diff --git a/.butcher/types/ChatMemberLeft/replace.yml b/.butcher/types/ChatMemberLeft/replace.yml deleted file mode 100644 index 619942cd..00000000 --- a/.butcher/types/ChatMemberLeft/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - ChatMember diff --git a/.butcher/types/ChatMemberMember/replace.yml b/.butcher/types/ChatMemberMember/replace.yml deleted file mode 100644 index 619942cd..00000000 --- a/.butcher/types/ChatMemberMember/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - ChatMember diff --git a/.butcher/types/ChatMemberOwner/replace.yml b/.butcher/types/ChatMemberOwner/replace.yml deleted file mode 100644 index 619942cd..00000000 --- a/.butcher/types/ChatMemberOwner/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - ChatMember diff --git a/.butcher/types/ChatMemberRestricted/replace.yml b/.butcher/types/ChatMemberRestricted/replace.yml index 6a3882af..0af85473 100644 --- a/.butcher/types/ChatMemberRestricted/replace.yml +++ b/.butcher/types/ChatMemberRestricted/replace.yml @@ -1,5 +1,3 @@ -bases: - - ChatMember annotations: until_date: parsed_type: diff --git a/.butcher/types/ChatMemberUpdated/entity.json b/.butcher/types/ChatMemberUpdated/entity.json index 7454b512..fbec5160 100644 --- a/.butcher/types/ChatMemberUpdated/entity.json +++ b/.butcher/types/ChatMemberUpdated/entity.json @@ -58,6 +58,14 @@ "rst_description": "*Optional*. Chat invite link, which was used by the user to join the chat; for joining by invite link events only.\n", "name": "invite_link", "required": false + }, + { + "type": "Boolean", + "description": "True, if the user joined the chat via a chat folder invite link", + "html_description": "Optional. True, if the user joined the chat via a chat folder invite link", + "rst_description": "*Optional*. True, if the user joined the chat via a chat folder invite link\n", + "name": "via_chat_folder_invite_link", + "required": false } ], "category": "types" diff --git a/.butcher/types/ChatMemberUpdated/replace.yml b/.butcher/types/ChatMemberUpdated/replace.yml index 66c1b64c..9a3a2842 100644 --- a/.butcher/types/ChatMemberUpdated/replace.yml +++ b/.butcher/types/ChatMemberUpdated/replace.yml @@ -3,32 +3,3 @@ annotations: parsed_type: type: std name: datetime.datetime - old_chat_member: &chat-member-type - parsed_type: - type: union - items: - - type: entity - references: - category: types - name: ChatMemberOwner - - type: entity - references: - category: types - name: ChatMemberAdministrator - - type: entity - references: - category: types - name: ChatMemberMember - - type: entity - references: - category: types - name: ChatMemberRestricted - - type: entity - references: - category: types - name: ChatMemberLeft - - type: entity - references: - category: types - name: ChatMemberBanned - new_chat_member: *chat-member-type diff --git a/.butcher/types/InlineKeyboardButton/entity.json b/.butcher/types/InlineKeyboardButton/entity.json index e73ff4dc..9c1baae5 100644 --- a/.butcher/types/InlineKeyboardButton/entity.json +++ b/.butcher/types/InlineKeyboardButton/entity.json @@ -53,9 +53,9 @@ }, { "type": "String", - "description": "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. May be empty, in which case just the bot's username will be inserted.\n\nNote: This offers an easy way for users to start using your bot in inline mode when they are currently in a private chat with it. Especially useful when combined with switch_pm… actions - in this case the user will be automatically returned to the chat they switched from, skipping the chat selection screen.", - "html_description": "Optional. 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. May be empty, in which case just the bot's username will be inserted.
\n
\nNote: This offers an easy way for users to start using your bot in inline mode when they are currently in a private chat with it. Especially useful when combined with switch_pm… actions - in this case the user will be automatically returned to the chat they switched from, skipping the chat selection screen.", - "rst_description": "*Optional*. 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. May be empty, in which case just the bot's username will be inserted.\n\n\n\n**Note:** This offers an easy way for users to start using your bot in `inline mode `_ when they are currently in a private chat with it. Especially useful when combined with `https://core.telegram.org/bots/api#answerinlinequery `_ *switch_pm…* actions - in this case the user will be automatically returned to the chat they switched from, skipping the chat selection screen.\n", + "description": "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. May be empty, in which case just the bot's username will be inserted.", + "html_description": "Optional. 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. May be empty, in which case just the bot's username will be inserted.", + "rst_description": "*Optional*. 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. May be empty, in which case just the bot's username will be inserted.\n", "name": "switch_inline_query", "required": false }, @@ -67,6 +67,14 @@ "name": "switch_inline_query_current_chat", "required": false }, + { + "type": "SwitchInlineQueryChosenChat", + "description": "If set, pressing the button will prompt the user to select one of their chats of the specified type, open that chat and insert the bot's username and the specified inline query in the input field", + "html_description": "Optional. If set, pressing the button will prompt the user to select one of their chats of the specified type, open that chat and insert the bot's username and the specified inline query in the input field", + "rst_description": "*Optional*. If set, pressing the button will prompt the user to select one of their chats of the specified type, open that chat and insert the bot's username and the specified inline query in the input field\n", + "name": "switch_inline_query_chosen_chat", + "required": false + }, { "type": "CallbackGame", "description": "Description of the game that will be launched when the user presses the button.\n\nNOTE: This type of button must always be the first button in the first row.", diff --git a/.butcher/types/InlineQueryResult/subtypes.yml b/.butcher/types/InlineQueryResult/subtypes.yml new file mode 100644 index 00000000..6756ad51 --- /dev/null +++ b/.butcher/types/InlineQueryResult/subtypes.yml @@ -0,0 +1 @@ +discriminator: "type" diff --git a/.butcher/types/InlineQueryResultArticle/replace.yml b/.butcher/types/InlineQueryResultArticle/replace.yml deleted file mode 100644 index cbe6bc26..00000000 --- a/.butcher/types/InlineQueryResultArticle/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - InlineQueryResult diff --git a/.butcher/types/InlineQueryResultAudio/replace.yml b/.butcher/types/InlineQueryResultAudio/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultAudio/replace.yml +++ b/.butcher/types/InlineQueryResultAudio/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultCachedAudio/replace.yml b/.butcher/types/InlineQueryResultCachedAudio/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultCachedAudio/replace.yml +++ b/.butcher/types/InlineQueryResultCachedAudio/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultCachedDocument/replace.yml b/.butcher/types/InlineQueryResultCachedDocument/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultCachedDocument/replace.yml +++ b/.butcher/types/InlineQueryResultCachedDocument/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultCachedGif/replace.yml b/.butcher/types/InlineQueryResultCachedGif/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultCachedGif/replace.yml +++ b/.butcher/types/InlineQueryResultCachedGif/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultCachedMpeg4Gif/replace.yml b/.butcher/types/InlineQueryResultCachedMpeg4Gif/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultCachedMpeg4Gif/replace.yml +++ b/.butcher/types/InlineQueryResultCachedMpeg4Gif/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultCachedPhoto/replace.yml b/.butcher/types/InlineQueryResultCachedPhoto/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultCachedPhoto/replace.yml +++ b/.butcher/types/InlineQueryResultCachedPhoto/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultCachedSticker/replace.yml b/.butcher/types/InlineQueryResultCachedSticker/replace.yml deleted file mode 100644 index cbe6bc26..00000000 --- a/.butcher/types/InlineQueryResultCachedSticker/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - InlineQueryResult diff --git a/.butcher/types/InlineQueryResultCachedVideo/replace.yml b/.butcher/types/InlineQueryResultCachedVideo/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultCachedVideo/replace.yml +++ b/.butcher/types/InlineQueryResultCachedVideo/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultCachedVoice/replace.yml b/.butcher/types/InlineQueryResultCachedVoice/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultCachedVoice/replace.yml +++ b/.butcher/types/InlineQueryResultCachedVoice/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultContact/replace.yml b/.butcher/types/InlineQueryResultContact/replace.yml deleted file mode 100644 index cbe6bc26..00000000 --- a/.butcher/types/InlineQueryResultContact/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - InlineQueryResult diff --git a/.butcher/types/InlineQueryResultDocument/replace.yml b/.butcher/types/InlineQueryResultDocument/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultDocument/replace.yml +++ b/.butcher/types/InlineQueryResultDocument/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultGame/replace.yml b/.butcher/types/InlineQueryResultGame/replace.yml deleted file mode 100644 index cbe6bc26..00000000 --- a/.butcher/types/InlineQueryResultGame/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - InlineQueryResult diff --git a/.butcher/types/InlineQueryResultGif/replace.yml b/.butcher/types/InlineQueryResultGif/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultGif/replace.yml +++ b/.butcher/types/InlineQueryResultGif/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultLocation/replace.yml b/.butcher/types/InlineQueryResultLocation/replace.yml deleted file mode 100644 index cbe6bc26..00000000 --- a/.butcher/types/InlineQueryResultLocation/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - InlineQueryResult diff --git a/.butcher/types/InlineQueryResultMpeg4Gif/replace.yml b/.butcher/types/InlineQueryResultMpeg4Gif/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultMpeg4Gif/replace.yml +++ b/.butcher/types/InlineQueryResultMpeg4Gif/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultPhoto/replace.yml b/.butcher/types/InlineQueryResultPhoto/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultPhoto/replace.yml +++ b/.butcher/types/InlineQueryResultPhoto/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultVenue/replace.yml b/.butcher/types/InlineQueryResultVenue/replace.yml deleted file mode 100644 index cbe6bc26..00000000 --- a/.butcher/types/InlineQueryResultVenue/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - InlineQueryResult diff --git a/.butcher/types/InlineQueryResultVideo/replace.yml b/.butcher/types/InlineQueryResultVideo/replace.yml index cd89306d..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultVideo/replace.yml +++ b/.butcher/types/InlineQueryResultVideo/replace.yml @@ -1,6 +1,3 @@ -bases: - - InlineQueryResult - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultVoice/replace.yml b/.butcher/types/InlineQueryResultVoice/replace.yml index 6c32c60f..e87fb9b3 100644 --- a/.butcher/types/InlineQueryResultVoice/replace.yml +++ b/.butcher/types/InlineQueryResultVoice/replace.yml @@ -1,5 +1,3 @@ -bases: - - InlineQueryResult annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InlineQueryResultsButton/entity.json b/.butcher/types/InlineQueryResultsButton/entity.json new file mode 100644 index 00000000..ce4cdf1e --- /dev/null +++ b/.butcher/types/InlineQueryResultsButton/entity.json @@ -0,0 +1,41 @@ +{ + "meta": {}, + "group": { + "title": "Inline mode", + "anchor": "inline-mode" + }, + "object": { + "anchor": "inlinequeryresultsbutton", + "name": "InlineQueryResultsButton", + "description": "This object represents a button to be shown above inline query results. You must use exactly one of the optional fields.", + "html_description": "

This object represents a button to be shown above inline query results. You must use exactly one of the optional fields.

", + "rst_description": "This object represents a button to be shown above inline query results. You **must** use exactly one of the optional fields.", + "annotations": [ + { + "type": "String", + "description": "Label text on the button", + "html_description": "Label text on the button", + "rst_description": "Label text on the button\n", + "name": "text", + "required": true + }, + { + "type": "WebAppInfo", + "description": "Description of the Web App that will be launched when the user presses the button. The Web App will be able to switch back to the inline mode using the method switchInlineQuery inside the Web App.", + "html_description": "Optional. Description of the Web App that will be launched when the user presses the button. The Web App will be able to switch back to the inline mode using the method switchInlineQuery inside the Web App.", + "rst_description": "*Optional*. Description of the `Web App `_ that will be launched when the user presses the button. The Web App will be able to switch back to the inline mode using the method `switchInlineQuery `_ inside the Web App.\n", + "name": "web_app", + "required": false + }, + { + "type": "String", + "description": "Deep-linking parameter for the /start message sent to the bot when a user presses the button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed.\n\nExample: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a switch_inline button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.", + "html_description": "Optional. Deep-linking parameter for the /start message sent to the bot when a user presses the button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed.
\n
\nExample: An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a switch_inline button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.", + "rst_description": "*Optional*. `Deep-linking `_ parameter for the /start message sent to the bot when a user presses the button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed.\n\n\n\n*Example:* An inline bot that sends YouTube videos can ask the user to connect the bot to their YouTube account to adapt search results accordingly. To do this, it displays a 'Connect your YouTube account' button above the results, or even before showing any. The user presses the button, switches to a private chat with the bot and, in doing so, passes a start parameter that instructs the bot to return an OAuth link. Once done, the bot can offer a `https://core.telegram.org/bots/api#inlinekeyboardmarkup `_ *switch_inline* button so that the user can easily return to the chat where they wanted to use the bot's inline capabilities.\n", + "name": "start_parameter", + "required": false + } + ], + "category": "types" + } +} diff --git a/.butcher/types/InputContactMessageContent/replace.yml b/.butcher/types/InputContactMessageContent/replace.yml deleted file mode 100644 index 29166299..00000000 --- a/.butcher/types/InputContactMessageContent/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - InputMessageContent diff --git a/.butcher/types/InputInvoiceMessageContent/replace.yml b/.butcher/types/InputInvoiceMessageContent/replace.yml deleted file mode 100644 index 29166299..00000000 --- a/.butcher/types/InputInvoiceMessageContent/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - InputMessageContent diff --git a/.butcher/types/InputLocationMessageContent/replace.yml b/.butcher/types/InputLocationMessageContent/replace.yml deleted file mode 100644 index 29166299..00000000 --- a/.butcher/types/InputLocationMessageContent/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - InputMessageContent diff --git a/.butcher/types/InputMedia/subtypes.yml b/.butcher/types/InputMedia/subtypes.yml new file mode 100644 index 00000000..6756ad51 --- /dev/null +++ b/.butcher/types/InputMedia/subtypes.yml @@ -0,0 +1 @@ +discriminator: "type" diff --git a/.butcher/types/InputMediaAnimation/replace.yml b/.butcher/types/InputMediaAnimation/replace.yml index a2756429..be3f441b 100644 --- a/.butcher/types/InputMediaAnimation/replace.yml +++ b/.butcher/types/InputMediaAnimation/replace.yml @@ -1,5 +1,3 @@ -bases: - - InputMedia annotations: media: parsed_type: diff --git a/.butcher/types/InputMediaAudio/replace.yml b/.butcher/types/InputMediaAudio/replace.yml index a2756429..be3f441b 100644 --- a/.butcher/types/InputMediaAudio/replace.yml +++ b/.butcher/types/InputMediaAudio/replace.yml @@ -1,5 +1,3 @@ -bases: - - InputMedia annotations: media: parsed_type: diff --git a/.butcher/types/InputMediaDocument/replace.yml b/.butcher/types/InputMediaDocument/replace.yml index a2756429..be3f441b 100644 --- a/.butcher/types/InputMediaDocument/replace.yml +++ b/.butcher/types/InputMediaDocument/replace.yml @@ -1,5 +1,3 @@ -bases: - - InputMedia annotations: media: parsed_type: diff --git a/.butcher/types/InputMediaPhoto/replace.yml b/.butcher/types/InputMediaPhoto/replace.yml index a2756429..be3f441b 100644 --- a/.butcher/types/InputMediaPhoto/replace.yml +++ b/.butcher/types/InputMediaPhoto/replace.yml @@ -1,5 +1,3 @@ -bases: - - InputMedia annotations: media: parsed_type: diff --git a/.butcher/types/InputMediaVideo/replace.yml b/.butcher/types/InputMediaVideo/replace.yml index a2756429..be3f441b 100644 --- a/.butcher/types/InputMediaVideo/replace.yml +++ b/.butcher/types/InputMediaVideo/replace.yml @@ -1,5 +1,3 @@ -bases: - - InputMedia annotations: media: parsed_type: diff --git a/.butcher/types/InputMessageContent/subtypes.yml b/.butcher/types/InputMessageContent/subtypes.yml new file mode 100644 index 00000000..ffcd4415 --- /dev/null +++ b/.butcher/types/InputMessageContent/subtypes.yml @@ -0,0 +1 @@ +{ } diff --git a/.butcher/types/InputSticker/entity.json b/.butcher/types/InputSticker/entity.json index a58690aa..9968d594 100644 --- a/.butcher/types/InputSticker/entity.json +++ b/.butcher/types/InputSticker/entity.json @@ -13,9 +13,9 @@ "annotations": [ { "type": "InputFile or String", - "description": "The added sticker. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. Animated and video stickers can't be uploaded via HTTP URL. More information on Sending Files", - "html_description": "The added sticker. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. Animated and video stickers can't be uploaded via HTTP URL. More information on Sending Files »", - "rst_description": "The added sticker. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. Animated and video stickers can't be uploaded via HTTP URL. :ref:`More information on Sending Files » `\n", + "description": "The added sticker. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, upload a new one using multipart/form-data, or pass 'attach://' to upload a new one using multipart/form-data under name. Animated and video stickers can't be uploaded via HTTP URL. More information on Sending Files", + "html_description": "The added sticker. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, upload a new one using multipart/form-data, or pass “attach://<file_attach_name>” to upload a new one using multipart/form-data under <file_attach_name> name. Animated and video stickers can't be uploaded via HTTP URL. More information on Sending Files »", + "rst_description": "The added sticker. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, upload a new one using multipart/form-data, or pass 'attach://' to upload a new one using multipart/form-data under name. Animated and video stickers can't be uploaded via HTTP URL. :ref:`More information on Sending Files » `\n", "name": "sticker", "required": true }, diff --git a/.butcher/types/InputTextMessageContent/replace.yml b/.butcher/types/InputTextMessageContent/replace.yml index 63741e83..ebc1d7e9 100644 --- a/.butcher/types/InputTextMessageContent/replace.yml +++ b/.butcher/types/InputTextMessageContent/replace.yml @@ -1,6 +1,3 @@ -bases: - - InputMessageContent - annotations: parse_mode: value: UNSET_PARSE_MODE diff --git a/.butcher/types/InputVenueMessageContent/replace.yml b/.butcher/types/InputVenueMessageContent/replace.yml deleted file mode 100644 index 29166299..00000000 --- a/.butcher/types/InputVenueMessageContent/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - InputMessageContent diff --git a/.butcher/types/KeyboardButtonRequestChat/entity.json b/.butcher/types/KeyboardButtonRequestChat/entity.json index 616025e4..a8674be8 100644 --- a/.butcher/types/KeyboardButtonRequestChat/entity.json +++ b/.butcher/types/KeyboardButtonRequestChat/entity.json @@ -8,8 +8,8 @@ "anchor": "keyboardbuttonrequestchat", "name": "KeyboardButtonRequestChat", "description": "This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed.", - "html_description": "

This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed.

", - "rst_description": "This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed.", + "html_description": "

This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed. More about requesting chats »

", + "rst_description": "This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed. `More about requesting chats » `_", "annotations": [ { "type": "Integer", diff --git a/.butcher/types/KeyboardButtonRequestUser/entity.json b/.butcher/types/KeyboardButtonRequestUser/entity.json index 46f792aa..0540e916 100644 --- a/.butcher/types/KeyboardButtonRequestUser/entity.json +++ b/.butcher/types/KeyboardButtonRequestUser/entity.json @@ -8,8 +8,8 @@ "anchor": "keyboardbuttonrequestuser", "name": "KeyboardButtonRequestUser", "description": "This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed.", - "html_description": "

This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed.

", - "rst_description": "This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed.", + "html_description": "

This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed. More about requesting users »

", + "rst_description": "This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed. `More about requesting users » `_", "annotations": [ { "type": "Integer", diff --git a/.butcher/types/MenuButton/subtypes.yml b/.butcher/types/MenuButton/subtypes.yml new file mode 100644 index 00000000..6756ad51 --- /dev/null +++ b/.butcher/types/MenuButton/subtypes.yml @@ -0,0 +1 @@ +discriminator: "type" diff --git a/.butcher/types/MenuButtonCommands/replace.yml b/.butcher/types/MenuButtonCommands/replace.yml deleted file mode 100644 index cc566462..00000000 --- a/.butcher/types/MenuButtonCommands/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - MenuButton diff --git a/.butcher/types/MenuButtonDefault/replace.yml b/.butcher/types/MenuButtonDefault/replace.yml deleted file mode 100644 index cc566462..00000000 --- a/.butcher/types/MenuButtonDefault/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - MenuButton diff --git a/.butcher/types/MenuButtonWebApp/replace.yml b/.butcher/types/MenuButtonWebApp/replace.yml deleted file mode 100644 index cc566462..00000000 --- a/.butcher/types/MenuButtonWebApp/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - MenuButton diff --git a/.butcher/types/PassportElementError/subtypes.yml b/.butcher/types/PassportElementError/subtypes.yml new file mode 100644 index 00000000..fd3f58ea --- /dev/null +++ b/.butcher/types/PassportElementError/subtypes.yml @@ -0,0 +1 @@ +discriminator: "source" diff --git a/.butcher/types/PassportElementErrorDataField/replace.yml b/.butcher/types/PassportElementErrorDataField/replace.yml deleted file mode 100644 index 105b390f..00000000 --- a/.butcher/types/PassportElementErrorDataField/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - PassportElementError diff --git a/.butcher/types/PassportElementErrorFile/replace.yml b/.butcher/types/PassportElementErrorFile/replace.yml deleted file mode 100644 index 105b390f..00000000 --- a/.butcher/types/PassportElementErrorFile/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - PassportElementError diff --git a/.butcher/types/PassportElementErrorFiles/replace.yml b/.butcher/types/PassportElementErrorFiles/replace.yml deleted file mode 100644 index 105b390f..00000000 --- a/.butcher/types/PassportElementErrorFiles/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - PassportElementError diff --git a/.butcher/types/PassportElementErrorFrontSide/replace.yml b/.butcher/types/PassportElementErrorFrontSide/replace.yml deleted file mode 100644 index 105b390f..00000000 --- a/.butcher/types/PassportElementErrorFrontSide/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - PassportElementError diff --git a/.butcher/types/PassportElementErrorReverseSide/replace.yml b/.butcher/types/PassportElementErrorReverseSide/replace.yml deleted file mode 100644 index 105b390f..00000000 --- a/.butcher/types/PassportElementErrorReverseSide/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - PassportElementError diff --git a/.butcher/types/PassportElementErrorSelfie/replace.yml b/.butcher/types/PassportElementErrorSelfie/replace.yml deleted file mode 100644 index 105b390f..00000000 --- a/.butcher/types/PassportElementErrorSelfie/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - PassportElementError diff --git a/.butcher/types/PassportElementErrorTranslationFile/replace.yml b/.butcher/types/PassportElementErrorTranslationFile/replace.yml deleted file mode 100644 index 105b390f..00000000 --- a/.butcher/types/PassportElementErrorTranslationFile/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - PassportElementError diff --git a/.butcher/types/PassportElementErrorTranslationFiles/replace.yml b/.butcher/types/PassportElementErrorTranslationFiles/replace.yml deleted file mode 100644 index 105b390f..00000000 --- a/.butcher/types/PassportElementErrorTranslationFiles/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - PassportElementError diff --git a/.butcher/types/PassportElementErrorUnspecified/replace.yml b/.butcher/types/PassportElementErrorUnspecified/replace.yml deleted file mode 100644 index 105b390f..00000000 --- a/.butcher/types/PassportElementErrorUnspecified/replace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bases: - - PassportElementError diff --git a/.butcher/types/SwitchInlineQueryChosenChat/entity.json b/.butcher/types/SwitchInlineQueryChosenChat/entity.json new file mode 100644 index 00000000..f36f3c33 --- /dev/null +++ b/.butcher/types/SwitchInlineQueryChosenChat/entity.json @@ -0,0 +1,57 @@ +{ + "meta": {}, + "group": { + "title": "Available types", + "anchor": "available-types" + }, + "object": { + "anchor": "switchinlinequerychosenchat", + "name": "SwitchInlineQueryChosenChat", + "description": "This object represents an inline button that switches the current user to inline mode in a chosen chat, with an optional default inline query.", + "html_description": "

This object represents an inline button that switches the current user to inline mode in a chosen chat, with an optional default inline query.

", + "rst_description": "This object represents an inline button that switches the current user to inline mode in a chosen chat, with an optional default inline query.", + "annotations": [ + { + "type": "String", + "description": "The default inline query to be inserted in the input field. If left empty, only the bot's username will be inserted", + "html_description": "Optional. The default inline query to be inserted in the input field. If left empty, only the bot's username will be inserted", + "rst_description": "*Optional*. The default inline query to be inserted in the input field. If left empty, only the bot's username will be inserted\n", + "name": "query", + "required": false + }, + { + "type": "Boolean", + "description": "True, if private chats with users can be chosen", + "html_description": "Optional. True, if private chats with users can be chosen", + "rst_description": "*Optional*. True, if private chats with users can be chosen\n", + "name": "allow_user_chats", + "required": false + }, + { + "type": "Boolean", + "description": "True, if private chats with bots can be chosen", + "html_description": "Optional. True, if private chats with bots can be chosen", + "rst_description": "*Optional*. True, if private chats with bots can be chosen\n", + "name": "allow_bot_chats", + "required": false + }, + { + "type": "Boolean", + "description": "True, if group and supergroup chats can be chosen", + "html_description": "Optional. True, if group and supergroup chats can be chosen", + "rst_description": "*Optional*. True, if group and supergroup chats can be chosen\n", + "name": "allow_group_chats", + "required": false + }, + { + "type": "Boolean", + "description": "True, if channel chats can be chosen", + "html_description": "Optional. True, if channel chats can be chosen", + "rst_description": "*Optional*. True, if channel chats can be chosen\n", + "name": "allow_channel_chats", + "required": false + } + ], + "category": "types" + } +} diff --git a/.butcher/types/WriteAccessAllowed/entity.json b/.butcher/types/WriteAccessAllowed/entity.json index 2ddeba40..62d83fdd 100644 --- a/.butcher/types/WriteAccessAllowed/entity.json +++ b/.butcher/types/WriteAccessAllowed/entity.json @@ -7,10 +7,19 @@ "object": { "anchor": "writeaccessallowed", "name": "WriteAccessAllowed", - "description": "This object represents a service message about a user allowing a bot added to the attachment menu to write messages. Currently holds no information.", - "html_description": "

This object represents a service message about a user allowing a bot added to the attachment menu to write messages. Currently holds no information.

", - "rst_description": "This object represents a service message about a user allowing a bot added to the attachment menu to write messages. Currently holds no information.", - "annotations": [], + "description": "This object represents a service message about a user allowing a bot to write messages after adding the bot to the attachment menu or launching a Web App from a link.", + "html_description": "

This object represents a service message about a user allowing a bot to write messages after adding the bot to the attachment menu or launching a Web App from a link.

", + "rst_description": "This object represents a service message about a user allowing a bot to write messages after adding the bot to the attachment menu or launching a Web App from a link.", + "annotations": [ + { + "type": "String", + "description": "Name of the Web App which was launched from a link", + "html_description": "Optional. Name of the Web App which was launched from a link", + "rst_description": "*Optional*. Name of the Web App which was launched from a link\n", + "name": "web_app_name", + "required": false + } + ], "category": "types" } } diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index d643b3f0..6b2da3b6 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,2 @@ open_collective: aiogram -patreon: aiogram + diff --git a/.github/workflows/pypi-release.yml b/.github/workflows/pypi-release.yml index 1cfe82b1..6991e206 100644 --- a/.github/workflows/pypi-release.yml +++ b/.github/workflows/pypi-release.yml @@ -12,14 +12,21 @@ jobs: steps: - uses: actions/checkout@master - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - name: Install build dependencies run: python -m pip install --upgrade build + - name: Resolve version + id: package-version + run: echo "value=$(echo ${{ github.ref }} | sed -e 's/refs\/tags\/v//')" >> $GITHUB_OUTPUT + + # - name: Bump version + # run: hatch version ${{ steps.package-version.outputs.value }} + - name: Build source distribution run: python -m build . @@ -40,8 +47,12 @@ jobs: publish: name: Publish needs: build - if: "success() && startsWith(github.ref, 'refs/tags/')" runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/project/aiogram/${{ steps.package-version.outputs.value }}/ + permissions: + id-token: write steps: - name: Download artifacts uses: actions/download-artifact@v1 @@ -49,17 +60,5 @@ jobs: name: dist path: dist - # - name: Publish a Python distribution to Test PyPI - # uses: pypa/gh-action-pypi-publish@master - ## if: github.event.action != 'published' - # with: - # user: __token__ - # password: ${{ secrets.PYPI_TEST_TOKEN }} - # repository_url: https://test.pypi.org/legacy/ - - name: Publish a Python distribution to PyPI - uses: pypa/gh-action-pypi-publish@master - # if: github.event.action == 'published' - with: - user: __token__ - password: ${{ secrets.PYPI_TOKEN }} + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/CHANGES.rst b/CHANGES.rst index afbb2d4a..a778b4b5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -16,6 +16,136 @@ Changelog .. towncrier release notes start +3.0.0b8 (2023-07-17) +===================== + +Features +-------- + +- Added possibility to use custom events in routers (If router does not support custom event it does not break and passes it to included routers). + `#1147 `_ +- Added support for FSM in Forum topics. + + The strategy can be changed in dispatcher: + + .. code-block:: python + + from aiogram.fsm.strategy import FSMStrategy + ... + dispatcher = Dispatcher( + fsm_strategy=FSMStrategy.USER_IN_TOPIC, + storage=..., # Any persistent storage + ) + + .. note:: + + If you have implemented you own storages you should extend record key generation + with new one attribute - :code:`thread_id` + `#1161 `_ +- Improved CallbackData serialization. + + - Minimized UUID (hex without dashes) + - Replaced bool values with int (true=1, false=0) + `#1163 `_ +- Added a tool to make text formatting flexible and easy. + More details on the :ref:`corresponding documentation page ` + `#1172 `_ +- Added :code:`X-Telegram-Bot-Api-Secret-Token` header check + `#1173 `_ +- Made :code:`allowed_updates` list to revolve automatically in start_polling method if not set explicitly. + `#1178 `_ +- Added possibility to pass custom headers to :class:`URLInputFile` object + `#1191 `_ + + +Bugfixes +-------- + +- Change type of result in InlineQueryResult enum for :code:`InlineQueryResultCachedMpeg4Gif` + and :code:`InlineQueryResultMpeg4Gif` to more correct according to documentation. + + Change regexp for entities parsing to more correct (:code:`InlineQueryResultType.yml`). + `#1146 `_ +- Fixed signature of startup/shutdown events to include the :code:`**dispatcher.workflow_data` as the handler arguments. + `#1155 `_ +- Added missing :code:`FORUM_TOPIC_EDITED` value to content_type property + `#1160 `_ +- Fixed compatibility with Python 3.8-3.9 (from previous release) + `#1162 `_ +- Fixed the markdown spoiler parser. + `#1176 `_ +- Fixed workflow data propagation + `#1196 `_ +- Fixed the serialization error associated with nested subtypes + like InputMedia, ChatMember, etc. + + The previously generated code resulted in an invalid schema under pydantic v2, + which has stricter type parsing. + Hence, subtypes without the specification of all subtype unions were generating + an empty object. This has been rectified now. + `#1213 `_ + + +Improved Documentation +---------------------- + +- Changed small grammar typos for :code:`upload_file` + `#1133 `_ + + +Deprecations and Removals +------------------------- + +- Removed text filter in due to is planned to remove this filter few versions ago. + + Use :code:`F.text` instead + `#1170 `_ + + +Misc +---- + +- Added full support of `Bot API 6.6 `_ + + .. danger:: + + Note that this issue has breaking changes described in in the Bot API changelog, + this changes is not breaking in the API but breaking inside aiogram because + Beta stage is not finished. + `#1139 `_ +- Added full support of `Bot API 6.7 `_ + + .. warning:: + + Note that arguments *switch_pm_parameter* and *switch_pm_text* was deprecated + and should be changed to *button* argument as described in API docs. + `#1168 `_ +- Updated `Pydantic to V2 `_ + + .. warning:: + + Be careful, not all libraries is already updated to using V2 + `#1202 `_ +- Added global defaults :code:`disable_web_page_preview` and :code:`protect_content` in addition to :code:`parse_mode` to the Bot instance, + reworked internal request builder mechanism. + `#1142 `_ +- Removed bot parameters from storages + `#1144 `_ + +- Replaced ContextVar's with a new feature called `Validation Context `_ + in Pydantic to improve the clarity, usability, and versatility of handling the Bot instance within method shortcuts. + + .. danger:: + + **Breaking**: The 'bot' argument now is required in `URLInputFile` + `#1210 `_ +- Updated magic-filter with new features + + - Added hint for :code:`len(F)` error + - Added not in operation + `#1221 `_ + + 3.0.0b7 (2023-02-18) ===================== diff --git a/CHANGES/1133.doc.rst b/CHANGES/1133.doc.rst deleted file mode 100644 index a5ab681d..00000000 --- a/CHANGES/1133.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Changed small grammar typos for `upload_file` diff --git a/CHANGES/1139.misc.rst b/CHANGES/1139.misc.rst deleted file mode 100644 index 432607e0..00000000 --- a/CHANGES/1139.misc.rst +++ /dev/null @@ -1,7 +0,0 @@ -Added full support of `Bot API 6.6 `_ - -.. danger:: - - Note that this issue has breaking changes described in in the Bot API changelog, - this changes is not breaking in the API but breaking inside aiogram because - Beta stage is not finished. diff --git a/CHANGES/1142.misc.rst b/CHANGES/1142.misc.rst deleted file mode 100644 index c17fb588..00000000 --- a/CHANGES/1142.misc.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added global defaults `disable_web_page_preview` and `protect_content` in addition to `parse_mode` to the Bot instance, -reworked internal request builder mechanism. diff --git a/CHANGES/1230.removal.rst b/CHANGES/1230.removal.rst new file mode 100644 index 00000000..bc1bc5b8 --- /dev/null +++ b/CHANGES/1230.removal.rst @@ -0,0 +1,2 @@ +Removed the use of the context instance (Bot.get_current) from all placements that were used previously. +This is to avoid the use of the context instance in the wrong place. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ada02324..93f96099 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1 +1 @@ -Please read the [Contributing](https://docs.aiogram.dev/en/dev-3.x/contributing/) guidelines in the documentation site. +Please read the [Contributing](https://docs.aiogram.dev/en/dev-3.x/contributing.html) guidelines in the documentation site. diff --git a/README.rst b/README.rst index 3c2297a8..c7505fce 100644 --- a/README.rst +++ b/README.rst @@ -63,7 +63,7 @@ Features - Asynchronous (`asyncio docs `_, :pep:`492`) - Has type hints (:pep:`484`) and can be used with `mypy `_ - Supports `PyPy `_ -- Supports `Telegram Bot API 6.6 `_ and gets fast updates to the latest versions of the Bot API +- Supports `Telegram Bot API 6.7 `_ and gets fast updates to the latest versions of the Bot API - Telegram Bot API integration code was `autogenerated `_ and can be easily re-generated when API gets updated - Updates router (Blueprints) - Has Finite State Machine diff --git a/aiogram/__init__.py b/aiogram/__init__.py index 4ed355fc..2ea9f79f 100644 --- a/aiogram/__init__.py +++ b/aiogram/__init__.py @@ -3,6 +3,7 @@ from contextlib import suppress from aiogram.dispatcher.flags import FlagGenerator from . import enums, methods, types +from .__meta__ import __api_version__, __version__ from .client import session from .client.bot import Bot from .dispatcher.dispatcher import Dispatcher @@ -36,6 +37,3 @@ __all__ = ( "md", "flags", ) - -__version__ = "3.0.0b8" -__api_version__ = "6.6" diff --git a/aiogram/__meta__.py b/aiogram/__meta__.py new file mode 100644 index 00000000..f2a9528b --- /dev/null +++ b/aiogram/__meta__.py @@ -0,0 +1,2 @@ +__version__ = "3.0.0b9" +__api_version__ = "6.7" diff --git a/aiogram/client/bot.py b/aiogram/client/bot.py index 6f874a88..b7cda3ea 100644 --- a/aiogram/client/bot.py +++ b/aiogram/client/bot.py @@ -71,6 +71,7 @@ from ..methods import ( GetMyCommands, GetMyDefaultAdministratorRights, GetMyDescription, + GetMyName, GetMyShortDescription, GetStickerSet, GetUpdates, @@ -115,6 +116,7 @@ from ..methods import ( SetMyCommands, SetMyDefaultAdministratorRights, SetMyDescription, + SetMyName, SetMyShortDescription, SetPassportDataErrors, SetStickerEmojiList, @@ -138,8 +140,15 @@ from ..methods import ( from ..types import ( UNSET_PARSE_MODE, BotCommand, - BotCommandScope, + BotCommandScopeAllChatAdministrators, + BotCommandScopeAllGroupChats, + BotCommandScopeAllPrivateChats, + BotCommandScopeChat, + BotCommandScopeChatAdministrators, + BotCommandScopeChatMember, + BotCommandScopeDefault, BotDescription, + BotName, BotShortDescription, Chat, ChatAdministratorRights, @@ -157,9 +166,29 @@ from ..types import ( ForumTopic, GameHighScore, InlineKeyboardMarkup, - InlineQueryResult, + InlineQueryResultArticle, + InlineQueryResultAudio, + InlineQueryResultCachedAudio, + InlineQueryResultCachedDocument, + InlineQueryResultCachedGif, + InlineQueryResultCachedMpeg4Gif, + InlineQueryResultCachedPhoto, + InlineQueryResultCachedSticker, + InlineQueryResultCachedVideo, + InlineQueryResultCachedVoice, + InlineQueryResultContact, + InlineQueryResultDocument, + InlineQueryResultGame, + InlineQueryResultGif, + InlineQueryResultLocation, + InlineQueryResultMpeg4Gif, + InlineQueryResultPhoto, + InlineQueryResultsButton, + InlineQueryResultVenue, + InlineQueryResultVideo, + InlineQueryResultVoice, InputFile, - InputMedia, + InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, @@ -173,7 +202,15 @@ from ..types import ( Message, MessageEntity, MessageId, - PassportElementError, + PassportElementErrorDataField, + PassportElementErrorFile, + PassportElementErrorFiles, + PassportElementErrorFrontSide, + PassportElementErrorReverseSide, + PassportElementErrorSelfie, + PassportElementErrorTranslationFile, + PassportElementErrorTranslationFiles, + PassportElementErrorUnspecified, Poll, ReplyKeyboardMarkup, ReplyKeyboardRemove, @@ -193,7 +230,7 @@ from .session.base import BaseSession T = TypeVar("T") -class Bot(ContextInstanceMixin["Bot"]): +class Bot: def __init__( self, token: str, @@ -247,16 +284,14 @@ class Bot(ContextInstanceMixin["Bot"]): """ Generate bot context - :param auto_close: + :param auto_close: close session on exit :return: """ - token = self.set_current(self) try: yield self finally: if auto_close: await self.session.close() - self.reset_current(token) async def me(self) -> User: """ @@ -477,12 +512,36 @@ class Bot(ContextInstanceMixin["Bot"]): async def answer_inline_query( self, inline_query_id: str, - results: List[InlineQueryResult], + results: List[ + Union[ + InlineQueryResultCachedAudio, + InlineQueryResultCachedDocument, + InlineQueryResultCachedGif, + InlineQueryResultCachedMpeg4Gif, + InlineQueryResultCachedPhoto, + InlineQueryResultCachedSticker, + InlineQueryResultCachedVideo, + InlineQueryResultCachedVoice, + InlineQueryResultArticle, + InlineQueryResultAudio, + InlineQueryResultContact, + InlineQueryResultGame, + InlineQueryResultDocument, + InlineQueryResultGif, + InlineQueryResultLocation, + InlineQueryResultMpeg4Gif, + InlineQueryResultPhoto, + InlineQueryResultVenue, + InlineQueryResultVideo, + InlineQueryResultVoice, + ] + ], cache_time: Optional[int] = None, is_personal: Optional[bool] = None, next_offset: Optional[str] = None, - switch_pm_text: Optional[str] = None, + button: Optional[InlineQueryResultsButton] = None, switch_pm_parameter: Optional[str] = None, + switch_pm_text: Optional[str] = None, request_timeout: Optional[int] = None, ) -> bool: """ @@ -495,10 +554,11 @@ class Bot(ContextInstanceMixin["Bot"]): :param inline_query_id: Unique identifier for the answered query :param results: A JSON-serialized array of results for the inline query :param cache_time: The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300. - :param is_personal: Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query + :param is_personal: Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any 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. - :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 button: A JSON-serialized object describing a button to be shown above inline query results :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 :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed. + :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 request_timeout: Request timeout :return: On success, :code:`True` is returned. """ @@ -509,8 +569,9 @@ class Bot(ContextInstanceMixin["Bot"]): cache_time=cache_time, is_personal=is_personal, next_offset=next_offset, - switch_pm_text=switch_pm_text, + button=button, switch_pm_parameter=switch_pm_parameter, + switch_pm_text=switch_pm_text, ) return await self(call, request_timeout=request_timeout) @@ -572,7 +633,28 @@ class Bot(ContextInstanceMixin["Bot"]): async def answer_web_app_query( self, web_app_query_id: str, - result: InlineQueryResult, + result: Union[ + InlineQueryResultCachedAudio, + InlineQueryResultCachedDocument, + InlineQueryResultCachedGif, + InlineQueryResultCachedMpeg4Gif, + InlineQueryResultCachedPhoto, + InlineQueryResultCachedSticker, + InlineQueryResultCachedVideo, + InlineQueryResultCachedVoice, + InlineQueryResultArticle, + InlineQueryResultAudio, + InlineQueryResultContact, + InlineQueryResultGame, + InlineQueryResultDocument, + InlineQueryResultGif, + InlineQueryResultLocation, + InlineQueryResultMpeg4Gif, + InlineQueryResultPhoto, + InlineQueryResultVenue, + InlineQueryResultVideo, + InlineQueryResultVoice, + ], request_timeout: Optional[int] = None, ) -> SentWebAppMessage: """ @@ -1066,7 +1148,17 @@ class Bot(ContextInstanceMixin["Bot"]): async def delete_my_commands( self, - scope: Optional[BotCommandScope] = None, + scope: Optional[ + Union[ + BotCommandScopeDefault, + BotCommandScopeAllPrivateChats, + BotCommandScopeAllGroupChats, + BotCommandScopeAllChatAdministrators, + BotCommandScopeChat, + BotCommandScopeChatAdministrators, + BotCommandScopeChatMember, + ] + ] = None, language_code: Optional[str] = None, request_timeout: Optional[int] = None, ) -> bool: @@ -1275,7 +1367,13 @@ class Bot(ContextInstanceMixin["Bot"]): async def edit_message_media( self, - media: InputMedia, + media: Union[ + InputMediaAnimation, + InputMediaDocument, + InputMediaAudio, + InputMediaPhoto, + InputMediaVideo, + ], chat_id: Optional[Union[int, str]] = None, message_id: Optional[int] = None, inline_message_id: Optional[str] = None, @@ -1657,7 +1755,17 @@ class Bot(ContextInstanceMixin["Bot"]): async def get_my_commands( self, - scope: Optional[BotCommandScope] = None, + scope: Optional[ + Union[ + BotCommandScopeDefault, + BotCommandScopeAllPrivateChats, + BotCommandScopeAllGroupChats, + BotCommandScopeAllChatAdministrators, + BotCommandScopeChat, + BotCommandScopeChatAdministrators, + BotCommandScopeChatMember, + ] + ] = None, language_code: Optional[str] = None, request_timeout: Optional[int] = None, ) -> List[BotCommand]: @@ -1737,7 +1845,7 @@ class Bot(ContextInstanceMixin["Bot"]): Source: https://core.telegram.org/bots/api#getupdates - :param offset: Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as :class:`aiogram.methods.get_updates.GetUpdates` is called with an *offset* higher than its *update_id*. The negative offset can be specified to retrieve updates starting from *-offset* update from the end of the updates queue. All previous updates will forgotten. + :param offset: Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as :class:`aiogram.methods.get_updates.GetUpdates` is called with an *offset* higher than its *update_id*. The negative offset can be specified to retrieve updates starting from *-offset* update from the end of the updates queue. All previous updates will be forgotten. :param limit: Limits the number of updates to be retrieved. Values between 1-100 are accepted. Defaults to 100. :param timeout: Timeout in seconds for long polling. Defaults to 0, i.e. usual short polling. Should be positive, short polling should be used for testing purposes only. :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 :class:`aiogram.types.update.Update` for a complete list of available update types. Specify an empty list to receive all update types except *chat_member* (default). If not specified, the previous setting will be used. @@ -3070,7 +3178,7 @@ class Bot(ContextInstanceMixin["Bot"]): self, chat_id: Optional[int] = None, menu_button: Optional[ - Union[MenuButtonDefault, MenuButtonWebApp, MenuButtonCommands] + Union[MenuButtonCommands, MenuButtonWebApp, MenuButtonDefault] ] = None, request_timeout: Optional[int] = None, ) -> bool: @@ -3227,7 +3335,17 @@ class Bot(ContextInstanceMixin["Bot"]): async def set_my_commands( self, commands: List[BotCommand], - scope: Optional[BotCommandScope] = None, + scope: Optional[ + Union[ + BotCommandScopeDefault, + BotCommandScopeAllPrivateChats, + BotCommandScopeAllGroupChats, + BotCommandScopeAllChatAdministrators, + BotCommandScopeChat, + BotCommandScopeChatAdministrators, + BotCommandScopeChatMember, + ] + ] = None, language_code: Optional[str] = None, request_timeout: Optional[int] = None, ) -> bool: @@ -3276,7 +3394,19 @@ class Bot(ContextInstanceMixin["Bot"]): async def set_passport_data_errors( self, user_id: int, - errors: List[PassportElementError], + errors: List[ + Union[ + PassportElementErrorDataField, + PassportElementErrorFrontSide, + PassportElementErrorReverseSide, + PassportElementErrorSelfie, + PassportElementErrorFile, + PassportElementErrorFiles, + PassportElementErrorTranslationFile, + PassportElementErrorTranslationFiles, + PassportElementErrorUnspecified, + ] + ], request_timeout: Optional[int] = None, ) -> bool: """ @@ -3913,3 +4043,46 @@ class Bot(ContextInstanceMixin["Bot"]): title=title, ) return await self(call, request_timeout=request_timeout) + + async def get_my_name( + self, + language_code: Optional[str] = None, + request_timeout: Optional[int] = None, + ) -> BotName: + """ + Use this method to get the current bot name for the given user language. Returns :class:`aiogram.types.bot_name.BotName` on success. + + Source: https://core.telegram.org/bots/api#getmyname + + :param language_code: A two-letter ISO 639-1 language code or an empty string + :param request_timeout: Request timeout + :return: Returns :class:`aiogram.types.bot_name.BotName` on success. + """ + + call = GetMyName( + language_code=language_code, + ) + return await self(call, request_timeout=request_timeout) + + async def set_my_name( + self, + name: Optional[str] = None, + language_code: Optional[str] = None, + request_timeout: Optional[int] = None, + ) -> bool: + """ + Use this method to change the bot's name. Returns :code:`True` on success. + + Source: https://core.telegram.org/bots/api#setmyname + + :param name: New bot name; 0-64 characters. Pass an empty string to remove the dedicated name for the given language. + :param language_code: A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose language there is no dedicated name. + :param request_timeout: Request timeout + :return: Returns :code:`True` on success. + """ + + call = SetMyName( + name=name, + language_code=language_code, + ) + return await self(call, request_timeout=request_timeout) diff --git a/aiogram/client/context_controller.py b/aiogram/client/context_controller.py new file mode 100644 index 00000000..97795a73 --- /dev/null +++ b/aiogram/client/context_controller.py @@ -0,0 +1,33 @@ +from typing import TYPE_CHECKING, Any, Optional + +from pydantic import BaseModel, PrivateAttr +from typing_extensions import Self + +if TYPE_CHECKING: + from aiogram.client.bot import Bot + + +class BotContextController(BaseModel): + _bot: Optional["Bot"] = PrivateAttr() + + def model_post_init(self, __context: Any) -> None: + self._bot = __context.get("bot") if __context else None + + def as_(self, bot: Optional["Bot"]) -> Self: + """ + Bind object to a bot instance. + + :param bot: Bot instance + :return: self + """ + self._bot = bot + return self + + @property + def bot(self) -> Optional["Bot"]: + """ + Get bot instance. + + :return: Bot instance + """ + return self._bot diff --git a/aiogram/client/session/aiohttp.py b/aiogram/client/session/aiohttp.py index 279f61f9..79e2fa4f 100644 --- a/aiogram/client/session/aiohttp.py +++ b/aiogram/client/session/aiohttp.py @@ -18,7 +18,10 @@ from typing import ( import certifi from aiohttp import BasicAuth, ClientError, ClientSession, FormData, TCPConnector +from aiohttp.hdrs import USER_AGENT +from aiohttp.http import SERVER_SOFTWARE +from aiogram.__meta__ import __version__ from aiogram.methods import TelegramMethod from ...exceptions import TelegramNetworkError @@ -121,7 +124,12 @@ class AiohttpSession(BaseSession): await self.close() if self._session is None or self._session.closed: - self._session = ClientSession(connector=self._connector_type(**self._connector_init)) + self._session = ClientSession( + connector=self._connector_type(**self._connector_init), + headers={ + USER_AGENT: f"{SERVER_SOFTWARE} aiogram/{__version__}", + }, + ) self._should_reset_connector = False return self._session @@ -133,7 +141,7 @@ class AiohttpSession(BaseSession): def build_form_data(self, bot: Bot, method: TelegramMethod[TelegramType]) -> FormData: form = FormData(quote_fields=False) files: Dict[str, InputFile] = {} - for key, value in method.dict().items(): + for key, value in method.model_dump(warnings=False).items(): value = self.prepare_value(value, bot=bot, files=files) if not value: continue @@ -159,15 +167,27 @@ class AiohttpSession(BaseSession): raise TelegramNetworkError(method=method, message="Request timeout error") except ClientError as e: raise TelegramNetworkError(method=method, message=f"{type(e).__name__}: {e}") - response = self.check_response(method=method, status_code=resp.status, content=raw_result) + response = self.check_response( + bot=bot, method=method, status_code=resp.status, content=raw_result + ) return cast(TelegramType, response.result) async def stream_content( - self, url: str, timeout: int, chunk_size: int, raise_for_status: bool + self, + url: str, + headers: Optional[Dict[str, Any]] = None, + timeout: int = 30, + chunk_size: int = 65536, + raise_for_status: bool = True, ) -> AsyncGenerator[bytes, None]: + if headers is None: + headers = {} + session = await self.create_session() - async with session.get(url, timeout=timeout, raise_for_status=raise_for_status) as resp: + async with session.get( + url, timeout=timeout, headers=headers, raise_for_status=raise_for_status + ) as resp: async for chunk in resp.content.iter_chunked(chunk_size): yield chunk diff --git a/aiogram/client/session/base.py b/aiogram/client/session/base.py index a66eb7cc..9342cbcc 100644 --- a/aiogram/client/session/base.py +++ b/aiogram/client/session/base.py @@ -75,7 +75,7 @@ class BaseSession(abc.ABC): self.middleware = RequestMiddlewareManager() def check_response( - self, method: TelegramMethod[TelegramType], status_code: int, content: str + self, bot: Bot, method: TelegramMethod[TelegramType], status_code: int, content: str ) -> Response[TelegramType]: """ Check response status @@ -89,7 +89,8 @@ class BaseSession(abc.ABC): raise ClientDecodeError("Failed to decode object", e, content) try: - response = method.build_response(json_data) + response_type = Response[method.__returning__] # type: ignore + response = response_type.model_validate(json_data, context={"bot": bot}) except ValidationError as e: raise ClientDecodeError("Failed to deserialize object", e, json_data) @@ -158,7 +159,12 @@ class BaseSession(abc.ABC): @abc.abstractmethod async def stream_content( - self, url: str, timeout: int, chunk_size: int, raise_for_status: bool + self, + url: str, + headers: Optional[Dict[str, Any]] = None, + timeout: int = 30, + chunk_size: int = 65536, + raise_for_status: bool = True, ) -> AsyncGenerator[bytes, None]: # pragma: no cover """ Stream reader diff --git a/aiogram/client/session/middlewares/base.py b/aiogram/client/session/middlewares/base.py index 90dcd09f..c5f3e7cf 100644 --- a/aiogram/client/session/middlewares/base.py +++ b/aiogram/client/session/middlewares/base.py @@ -1,7 +1,7 @@ from __future__ import annotations from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Awaitable, Callable, Union +from typing import TYPE_CHECKING, Protocol from aiogram.methods import Response, TelegramMethod from aiogram.methods.base import TelegramType @@ -9,16 +9,24 @@ from aiogram.methods.base import TelegramType if TYPE_CHECKING: from ...bot import Bot -NextRequestMiddlewareType = Callable[ - ["Bot", TelegramMethod[TelegramType]], Awaitable[Response[TelegramType]] -] -RequestMiddlewareType = Union[ - "BaseRequestMiddleware", - Callable[ - [NextRequestMiddlewareType[TelegramType], "Bot", TelegramMethod[TelegramType]], - Awaitable[Response[TelegramType]], - ], -] + +class NextRequestMiddlewareType(Protocol[TelegramType]): # pragma: no cover + async def __call__( + self, + bot: "Bot", + method: TelegramMethod[TelegramType], + ) -> Response[TelegramType]: + pass + + +class RequestMiddlewareType(Protocol): # pragma: no cover + async def __call__( + self, + make_request: NextRequestMiddlewareType[TelegramType], + bot: "Bot", + method: TelegramMethod[TelegramType], + ) -> Response[TelegramType]: + pass class BaseRequestMiddleware(ABC): diff --git a/aiogram/client/session/middlewares/manager.py b/aiogram/client/session/middlewares/manager.py index 0e76801e..78015309 100644 --- a/aiogram/client/session/middlewares/manager.py +++ b/aiogram/client/session/middlewares/manager.py @@ -1,68 +1,48 @@ from __future__ import annotations from functools import partial -from typing import ( - TYPE_CHECKING, - Any, - Awaitable, - Callable, - List, - Optional, - Sequence, - Union, - overload, -) +from typing import Any, Callable, List, Optional, Sequence, Union, cast, overload from aiogram.client.session.middlewares.base import ( NextRequestMiddlewareType, RequestMiddlewareType, ) -from aiogram.methods import Response -from aiogram.methods.base import TelegramMethod, TelegramType -from aiogram.types import TelegramObject - -if TYPE_CHECKING: - from aiogram import Bot +from aiogram.methods.base import TelegramType -class RequestMiddlewareManager(Sequence[RequestMiddlewareType[TelegramObject]]): +class RequestMiddlewareManager(Sequence[RequestMiddlewareType]): def __init__(self) -> None: - self._middlewares: List[RequestMiddlewareType[TelegramObject]] = [] + self._middlewares: List[RequestMiddlewareType] = [] def register( self, - middleware: RequestMiddlewareType[TelegramObject], - ) -> RequestMiddlewareType[TelegramObject]: + middleware: RequestMiddlewareType, + ) -> RequestMiddlewareType: self._middlewares.append(middleware) return middleware - def unregister(self, middleware: RequestMiddlewareType[TelegramObject]) -> None: + def unregister(self, middleware: RequestMiddlewareType) -> None: self._middlewares.remove(middleware) def __call__( self, - middleware: Optional[RequestMiddlewareType[TelegramObject]] = None, - ) -> Union[ - Callable[[RequestMiddlewareType[TelegramObject]], RequestMiddlewareType[TelegramObject]], - RequestMiddlewareType[TelegramObject], - ]: + middleware: Optional[RequestMiddlewareType] = None, + ) -> Union[Callable[[RequestMiddlewareType], RequestMiddlewareType], RequestMiddlewareType,]: if middleware is None: return self.register return self.register(middleware) @overload - def __getitem__(self, item: int) -> RequestMiddlewareType[TelegramObject]: + def __getitem__(self, item: int) -> RequestMiddlewareType: pass @overload - def __getitem__(self, item: slice) -> Sequence[RequestMiddlewareType[TelegramObject]]: + def __getitem__(self, item: slice) -> Sequence[RequestMiddlewareType]: pass def __getitem__( self, item: Union[int, slice] - ) -> Union[ - RequestMiddlewareType[TelegramObject], Sequence[RequestMiddlewareType[TelegramObject]] - ]: + ) -> Union[RequestMiddlewareType, Sequence[RequestMiddlewareType]]: return self._middlewares[item] def __len__(self) -> int: @@ -70,10 +50,10 @@ class RequestMiddlewareManager(Sequence[RequestMiddlewareType[TelegramObject]]): def wrap_middlewares( self, - callback: Callable[[Bot, TelegramMethod[TelegramType]], Awaitable[Response[TelegramType]]], + callback: NextRequestMiddlewareType[TelegramType], **kwargs: Any, ) -> NextRequestMiddlewareType[TelegramType]: middleware = partial(callback, **kwargs) for m in reversed(self._middlewares): - middleware = partial(m, middleware) # type: ignore - return middleware + middleware = partial(m, middleware) + return cast(NextRequestMiddlewareType[TelegramType], middleware) diff --git a/aiogram/dispatcher/dispatcher.py b/aiogram/dispatcher/dispatcher.py index 71791f72..eb2d55f2 100644 --- a/aiogram/dispatcher/dispatcher.py +++ b/aiogram/dispatcher/dispatcher.py @@ -18,6 +18,7 @@ from ..fsm.strategy import FSMStrategy from ..methods import GetUpdates, TelegramMethod from ..methods.base import TelegramType from ..types import Update, User +from ..types.base import UNSET, UNSET_TYPE from ..types.update import UpdateTypeLookupError from ..utils.backoff import Backoff, BackoffConfig from .event.bases import UNHANDLED, SkipHandler @@ -80,9 +81,9 @@ class Dispatcher(Router): # FSM middleware should always be registered after User context middleware # because here is used context from previous step self.fsm = FSMContextMiddleware( - storage=storage if storage else MemoryStorage(), + storage=storage or MemoryStorage(), strategy=fsm_strategy, - events_isolation=events_isolation if events_isolation else DisabledEventIsolation(), + events_isolation=events_isolation or DisabledEventIsolation(), ) if not disable_fsm: # Note that when FSM middleware is disabled, the event isolation is also disabled @@ -92,8 +93,8 @@ class Dispatcher(Router): self.workflow_data: Dict[str, Any] = kwargs self._running_lock = Lock() - self._stop_signal = Event() - self._stopped_signal = Event() + self._stop_signal: Optional[Event] = None + self._stopped_signal: Optional[Event] = None def __getitem__(self, item: str) -> Any: return self.workflow_data[item] @@ -142,7 +143,16 @@ class Dispatcher(Router): handled = False start_time = loop.time() - token = Bot.set_current(bot) + if update.bot != bot: + # Re-mounting update to the current bot instance for making possible to + # use it in shortcuts. + # Here is update is re-created because we need to propagate context to + # all nested objects and attributes of the Update, but it + # is impossible without roundtrip to JSON :( + # The preferred way is that pass already mounted Bot instance to this update + # before call feed_update method + update = Update.model_validate(update.model_dump(), context={"bot": bot}) + try: response = await self.update.wrap_outer_middleware( self.update.trigger, @@ -165,7 +175,6 @@ class Dispatcher(Router): duration, bot.id, ) - Bot.reset_current(token) async def feed_raw_update(self, bot: Bot, update: Dict[str, Any], **kwargs: Any) -> Any: """ @@ -175,7 +184,7 @@ class Dispatcher(Router): :param update: :param kwargs: """ - parsed_update = Update(**update) + parsed_update = Update.model_validate(update, context={"bot": bot}) return await self.feed_update(bot=bot, update=parsed_update, **kwargs) @classmethod @@ -251,14 +260,14 @@ class Dispatcher(Router): try: update_type = update.event_type event = update.event - except UpdateTypeLookupError: + except UpdateTypeLookupError as e: warnings.warn( "Detected unknown update type.\n" "Seems like Telegram Bot API was updated and you have " "installed not latest version of aiogram framework", RuntimeWarning, ) - raise SkipHandler() + raise SkipHandler() from e kwargs.update(event_update=update) @@ -367,13 +376,13 @@ class Dispatcher(Router): self, bot: Bot, update: Union[Update, Dict[str, Any]], _timeout: float = 55, **kwargs: Any ) -> Optional[TelegramMethod[TelegramType]]: if not isinstance(update, Update): # Allow to use raw updates - update = Update(**update) + update = Update.model_validate(update, context={"bot": bot}) ctx = contextvars.copy_context() loop = asyncio.get_running_loop() waiter = loop.create_future() - def release_waiter(*args: Any) -> None: + def release_waiter(*_: Any) -> None: if not waiter.done(): waiter.set_result(None) @@ -430,6 +439,8 @@ class Dispatcher(Router): """ if not self._running_lock.locked(): raise RuntimeError("Polling is not started") + if not self._stop_signal or not self._stopped_signal: + return self._stop_signal.set() await self._stopped_signal.wait() @@ -438,6 +449,8 @@ class Dispatcher(Router): return loggers.dispatcher.warning("Received %s signal", sig.name) + if not self._stop_signal: + return self._stop_signal.set() async def start_polling( @@ -446,7 +459,7 @@ class Dispatcher(Router): polling_timeout: int = 10, handle_as_tasks: bool = True, backoff_config: BackoffConfig = DEFAULT_BACKOFF_CONFIG, - allowed_updates: Optional[List[str]] = None, + allowed_updates: Optional[Union[List[str], UNSET_TYPE]] = UNSET, handle_signals: bool = True, close_bot_session: bool = True, **kwargs: Any, @@ -454,11 +467,12 @@ class Dispatcher(Router): """ Polling runner - :param bots: Bot instances (one or mre) + :param bots: Bot instances (one or more) :param polling_timeout: Long-polling wait time :param handle_as_tasks: Run task for each event and no wait result :param backoff_config: backoff-retry config :param allowed_updates: List of the update types you want your bot to receive + By default, all used update types are enabled (resolved from handlers) :param handle_signals: handle signals (SIGINT/SIGTERM) :param close_bot_session: close bot sessions on shutdown :param kwargs: contextual data @@ -473,6 +487,14 @@ class Dispatcher(Router): ) async with self._running_lock: # Prevent to run this method twice at a once + if self._stop_signal is None: + self._stop_signal = Event() + if self._stopped_signal is None: + self._stopped_signal = Event() + + if allowed_updates is UNSET: + allowed_updates = self.resolve_used_update_types() + self._stop_signal.clear() self._stopped_signal.clear() @@ -488,9 +510,13 @@ class Dispatcher(Router): signal.SIGINT, self._signal_stop_polling, signal.SIGINT ) - workflow_data = {"dispatcher": self, "bots": bots, "bot": bots[-1]} - workflow_data.update(kwargs) - await self.emit_startup(**workflow_data) + workflow_data = { + "dispatcher": self, + "bots": bots, + **self.workflow_data, + **kwargs, + } + await self.emit_startup(bot=bots[-1], **workflow_data) loggers.dispatcher.info("Start polling") try: tasks: List[asyncio.Task[Any]] = [ @@ -501,7 +527,7 @@ class Dispatcher(Router): polling_timeout=polling_timeout, backoff_config=backoff_config, allowed_updates=allowed_updates, - **kwargs, + **workflow_data, ) ) for bot in bots @@ -520,7 +546,7 @@ class Dispatcher(Router): finally: loggers.dispatcher.info("Polling stopped") try: - await self.emit_shutdown(**workflow_data) + await self.emit_shutdown(bot=bots[-1], **workflow_data) finally: if close_bot_session: await asyncio.gather(*(bot.session.close() for bot in bots)) @@ -532,7 +558,7 @@ class Dispatcher(Router): polling_timeout: int = 10, handle_as_tasks: bool = True, backoff_config: BackoffConfig = DEFAULT_BACKOFF_CONFIG, - allowed_updates: Optional[List[str]] = None, + allowed_updates: Optional[Union[List[str], UNSET_TYPE]] = UNSET, handle_signals: bool = True, close_bot_session: bool = True, **kwargs: Any, diff --git a/aiogram/dispatcher/event/telegram.py b/aiogram/dispatcher/event/telegram.py index bb943004..a468816c 100644 --- a/aiogram/dispatcher/event/telegram.py +++ b/aiogram/dispatcher/event/telegram.py @@ -49,8 +49,9 @@ class TelegramEventObserver: def _resolve_middlewares(self) -> List[MiddlewareType[TelegramObject]]: middlewares: List[MiddlewareType[TelegramObject]] = [] for router in reversed(tuple(self.router.chain_head)): - observer = router.observers[self.event_name] - middlewares.extend(observer.middleware) + observer = router.observers.get(self.event_name) + if observer: + middlewares.extend(observer.middleware) return middlewares diff --git a/aiogram/dispatcher/middlewares/user_context.py b/aiogram/dispatcher/middlewares/user_context.py index 3531beb7..12bb4864 100644 --- a/aiogram/dispatcher/middlewares/user_context.py +++ b/aiogram/dispatcher/middlewares/user_context.py @@ -1,9 +1,12 @@ -from contextlib import contextmanager -from typing import Any, Awaitable, Callable, Dict, Iterator, Optional, Tuple +from typing import Any, Awaitable, Callable, Dict, Optional, Tuple from aiogram.dispatcher.middlewares.base import BaseMiddleware from aiogram.types import Chat, TelegramObject, Update, User +EVENT_FROM_USER_KEY = "event_from_user" +EVENT_CHAT_KEY = "event_chat" +EVENT_THREAD_ID_KEY = "event_thread_id" + class UserContextMiddleware(BaseMiddleware): async def __call__( @@ -14,61 +17,64 @@ class UserContextMiddleware(BaseMiddleware): ) -> Any: if not isinstance(event, Update): raise RuntimeError("UserContextMiddleware got an unexpected event type!") - chat, user = self.resolve_event_context(event=event) - with self.context(chat=chat, user=user): - if user is not None: - data["event_from_user"] = user - if chat is not None: - data["event_chat"] = chat - return await handler(event, data) - - @contextmanager - def context(self, chat: Optional[Chat] = None, user: Optional[User] = None) -> Iterator[None]: - chat_token = None - user_token = None - if chat: - chat_token = chat.set_current(chat) - if user: - user_token = user.set_current(user) - try: - yield - finally: - if chat and chat_token: - chat.reset_current(chat_token) - if user and user_token: - user.reset_current(user_token) + chat, user, thread_id = self.resolve_event_context(event=event) + if user is not None: + data[EVENT_FROM_USER_KEY] = user + if chat is not None: + data[EVENT_CHAT_KEY] = chat + if thread_id is not None: + data[EVENT_THREAD_ID_KEY] = thread_id + return await handler(event, data) @classmethod - def resolve_event_context(cls, event: Update) -> Tuple[Optional[Chat], Optional[User]]: + def resolve_event_context( + cls, event: Update + ) -> Tuple[Optional[Chat], Optional[User], Optional[int]]: """ Resolve chat and user instance from Update object """ if event.message: - return event.message.chat, event.message.from_user + return ( + event.message.chat, + event.message.from_user, + event.message.message_thread_id if event.message.is_topic_message else None, + ) if event.edited_message: - return event.edited_message.chat, event.edited_message.from_user + return ( + event.edited_message.chat, + event.edited_message.from_user, + event.edited_message.message_thread_id + if event.edited_message.is_topic_message + else None, + ) if event.channel_post: - return event.channel_post.chat, None + return event.channel_post.chat, None, None if event.edited_channel_post: - return event.edited_channel_post.chat, None + return event.edited_channel_post.chat, None, None if event.inline_query: - return None, event.inline_query.from_user + return None, event.inline_query.from_user, None if event.chosen_inline_result: - return None, event.chosen_inline_result.from_user + return None, event.chosen_inline_result.from_user, None if event.callback_query: if event.callback_query.message: - return event.callback_query.message.chat, event.callback_query.from_user - return None, event.callback_query.from_user + return ( + event.callback_query.message.chat, + event.callback_query.from_user, + event.callback_query.message.message_thread_id + if event.callback_query.message.is_topic_message + else None, + ) + return None, event.callback_query.from_user, None if event.shipping_query: - return None, event.shipping_query.from_user + return None, event.shipping_query.from_user, None if event.pre_checkout_query: - return None, event.pre_checkout_query.from_user + return None, event.pre_checkout_query.from_user, None if event.poll_answer: - return None, event.poll_answer.user + return None, event.poll_answer.user, None if event.my_chat_member: - return event.my_chat_member.chat, event.my_chat_member.from_user + return event.my_chat_member.chat, event.my_chat_member.from_user, None if event.chat_member: - return event.chat_member.chat, event.chat_member.from_user + return event.chat_member.chat, event.chat_member.from_user, None if event.chat_join_request: - return event.chat_join_request.chat, event.chat_join_request.from_user - return None, None + return event.chat_join_request.chat, event.chat_join_request.from_user, None + return None, None, None diff --git a/aiogram/dispatcher/router.py b/aiogram/dispatcher/router.py index 86359ce0..85c41ae8 100644 --- a/aiogram/dispatcher/router.py +++ b/aiogram/dispatcher/router.py @@ -105,27 +105,31 @@ class Router: async def propagate_event(self, update_type: str, event: TelegramObject, **kwargs: Any) -> Any: kwargs.update(event_router=self) - observer = self.observers[update_type] + observer = self.observers.get(update_type) async def _wrapped(telegram_event: TelegramObject, **data: Any) -> Any: return await self._propagate_event( observer=observer, update_type=update_type, event=telegram_event, **data ) - return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs) + if observer: + return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs) + return await _wrapped(event, **kwargs) async def _propagate_event( self, - observer: TelegramEventObserver, + observer: Optional[TelegramEventObserver], update_type: str, event: TelegramObject, **kwargs: Any, ) -> Any: - response = await observer.trigger(event, **kwargs) - if response is REJECTED: - return UNHANDLED - if response is not UNHANDLED: - return response + response = UNHANDLED + if observer: + response = await observer.trigger(event, **kwargs) + if response is REJECTED: + return UNHANDLED + if response is not UNHANDLED: + return response for router in self.sub_routers: response = await router.propagate_event(update_type=update_type, event=event, **kwargs) diff --git a/aiogram/enums/__init__.py b/aiogram/enums/__init__.py index 73422378..ab49c599 100644 --- a/aiogram/enums/__init__.py +++ b/aiogram/enums/__init__.py @@ -4,12 +4,14 @@ from .chat_member_status import ChatMemberStatus from .chat_type import ChatType from .content_type import ContentType from .dice_emoji import DiceEmoji +from .encrypted_passport_element import EncryptedPassportElement from .inline_query_result_type import InlineQueryResultType from .input_media_type import InputMediaType from .mask_position_point import MaskPositionPoint from .menu_button_type import MenuButtonType from .message_entity_type import MessageEntityType from .parse_mode import ParseMode +from .passport_element_error_type import PassportElementErrorType from .poll_type import PollType from .sticker_format import StickerFormat from .sticker_type import StickerType @@ -23,12 +25,14 @@ __all__ = ( "ChatType", "ContentType", "DiceEmoji", + "EncryptedPassportElement", "InlineQueryResultType", "InputMediaType", "MaskPositionPoint", "MenuButtonType", "MessageEntityType", "ParseMode", + "PassportElementErrorType", "PollType", "StickerFormat", "StickerType", diff --git a/aiogram/enums/encrypted_passport_element.py b/aiogram/enums/encrypted_passport_element.py new file mode 100644 index 00000000..ebb4b2e6 --- /dev/null +++ b/aiogram/enums/encrypted_passport_element.py @@ -0,0 +1,23 @@ +from enum import Enum + + +class EncryptedPassportElement(str, Enum): + """ + This object represents type of encrypted passport element. + + Source: https://core.telegram.org/bots/api#encryptedpassportelement + """ + + PERSONAL_DETAILS = "personal_details" + PASSPORT = "passport" + DRIVER_LICENSE = "driver_license" + IDENTITY_CARD = "identity_card" + INTERNAL_PASSPORT = "internal_passport" + ADDRESS = "address" + UTILITY_BILL = "utility_bill" + BANK_STATEMENT = "bank_statement" + RENTAL_AGREEMENT = "rental_agreement" + PASSPORT_REGISTRATION = "passport_registration" + TEMPORARY_REGISTRATION = "temporary_registration" + PHONE_NUMBER = "phone_number" + EMAIL = "email" diff --git a/aiogram/enums/inline_query_result_type.py b/aiogram/enums/inline_query_result_type.py index 771dc498..ae20045a 100644 --- a/aiogram/enums/inline_query_result_type.py +++ b/aiogram/enums/inline_query_result_type.py @@ -11,7 +11,7 @@ class InlineQueryResultType(str, Enum): AUDIO = "audio" DOCUMENT = "document" GIF = "gif" - MPEG = "mpeg" + MPEG4_GIF = "mpeg4_gif" PHOTO = "photo" STICKER = "sticker" VIDEO = "video" diff --git a/aiogram/enums/passport_element_error_type.py b/aiogram/enums/passport_element_error_type.py new file mode 100644 index 00000000..cdcb4806 --- /dev/null +++ b/aiogram/enums/passport_element_error_type.py @@ -0,0 +1,19 @@ +from enum import Enum + + +class PassportElementErrorType(str, Enum): + """ + This object represents a passport element error type. + + Source: https://core.telegram.org/bots/api#passportelementerror + """ + + DATA = "data" + FRONT_SIDE = "front_side" + REVERSE_SIDE = "reverse_side" + SELFIE = "selfie" + FILE = "file" + FILES = "files" + TRANSLATION_FILE = "translation_file" + TRANSLATION_FILES = "translation_files" + UNSPECIFIED = "unspecified" diff --git a/aiogram/exceptions.py b/aiogram/exceptions.py index 1c1e59fb..7ca7dcdd 100644 --- a/aiogram/exceptions.py +++ b/aiogram/exceptions.py @@ -34,6 +34,8 @@ class UnsupportedKeywordArgument(DetailedAiogramError): class TelegramAPIError(DetailedAiogramError): + label: str = "Telegram server says" + def __init__( self, method: TelegramMethod[TelegramType], @@ -44,11 +46,11 @@ class TelegramAPIError(DetailedAiogramError): def __str__(self) -> str: original_message = super().__str__() - return f"Telegram server says {original_message}" + return f"{self.label} - {original_message}" class TelegramNetworkError(TelegramAPIError): - pass + label = "HTTP Client says" class TelegramRetryAfter(TelegramAPIError): diff --git a/aiogram/filters/__init__.py b/aiogram/filters/__init__.py index b3bee0d8..bcadc178 100644 --- a/aiogram/filters/__init__.py +++ b/aiogram/filters/__init__.py @@ -19,14 +19,12 @@ from .exception import ExceptionMessageFilter, ExceptionTypeFilter from .logic import and_f, invert_f, or_f from .magic_data import MagicData from .state import StateFilter -from .text import Text BaseFilter = Filter __all__ = ( "Filter", "BaseFilter", - "Text", "Command", "CommandObject", "CommandStart", diff --git a/aiogram/filters/callback_data.py b/aiogram/filters/callback_data.py index 84ec1e88..7a09dedb 100644 --- a/aiogram/filters/callback_data.py +++ b/aiogram/filters/callback_data.py @@ -67,7 +67,11 @@ class CallbackData(BaseModel): return "" if isinstance(value, Enum): return str(value.value) - if isinstance(value, (int, str, float, Decimal, Fraction, UUID)): + if isinstance(value, UUID): + return value.hex + if isinstance(value, bool): + return str(int(value)) + if isinstance(value, (int, str, float, Decimal, Fraction)): return str(value) raise ValueError( f"Attribute {key}={value!r} of type {type(value).__name__!r}" @@ -81,7 +85,7 @@ class CallbackData(BaseModel): :return: valid callback data for Telegram Bot API """ result = [self.__prefix__] - for key, value in self.dict().items(): + for key, value in self.model_dump(mode="json").items(): encoded = self._encode_value(key, value) if self.__separator__ in encoded: raise ValueError( @@ -106,7 +110,7 @@ class CallbackData(BaseModel): :return: instance of CallbackData """ prefix, *parts = value.split(cls.__separator__) - names = cls.__fields__.keys() + names = cls.model_fields.keys() if len(parts) != len(names): raise TypeError( f"Callback data {cls.__name__!r} takes {len(names)} arguments " @@ -116,8 +120,8 @@ class CallbackData(BaseModel): raise ValueError(f"Bad prefix ({prefix!r} != {cls.__prefix__!r})") payload = {} for k, v in zip(names, parts): # type: str, Optional[str] - if field := cls.__fields__.get(k): - if v == "" and not field.required: + if field := cls.model_fields.get(k): + if v == "" and not field.is_required(): v = None payload[k] = v return cls(**payload) diff --git a/aiogram/filters/chat_member_updated.py b/aiogram/filters/chat_member_updated.py index 7671ba4e..23cf0e9c 100644 --- a/aiogram/filters/chat_member_updated.py +++ b/aiogram/filters/chat_member_updated.py @@ -74,9 +74,12 @@ class _MemberStatusMarker: return hash((self.name, self.is_member)) def check(self, *, member: ChatMember) -> bool: - if self.is_member is not None and member.is_member != self.is_member: + # Not all member types have `is_member` attribute + is_member = getattr(member, "is_member", None) + status = getattr(member, "status", None) + if self.is_member is not None and is_member != self.is_member: return False - return self.name == member.status + return self.name == status class _MemberStatusGroupMarker: diff --git a/aiogram/filters/command.py b/aiogram/filters/command.py index 85ff4de6..6e654531 100644 --- a/aiogram/filters/command.py +++ b/aiogram/filters/command.py @@ -191,7 +191,7 @@ class Command(Filter): return command # noqa: RET504 def do_magic(self, command: CommandObject) -> Any: - if not self.magic: + if self.magic is None: return command result = self.magic.resolve(command) if not result: diff --git a/aiogram/filters/magic_data.py b/aiogram/filters/magic_data.py index 351c8e4f..5b3c31d7 100644 --- a/aiogram/filters/magic_data.py +++ b/aiogram/filters/magic_data.py @@ -18,7 +18,7 @@ class MagicData(Filter): async def __call__(self, event: TelegramObject, *args: Any, **kwargs: Any) -> Any: return self.magic_data.resolve( - AttrDict({"event": event, **{k: v for k, v in enumerate(args)}, **kwargs}) + AttrDict({"event": event, **dict(enumerate(args)), **kwargs}) ) def __str__(self) -> str: diff --git a/aiogram/filters/state.py b/aiogram/filters/state.py index 5ad65ae5..82a141c9 100644 --- a/aiogram/filters/state.py +++ b/aiogram/filters/state.py @@ -27,7 +27,7 @@ class StateFilter(Filter): ) async def __call__( - self, obj: Union[TelegramObject], raw_state: Optional[str] = None + self, obj: TelegramObject, raw_state: Optional[str] = None ) -> Union[bool, Dict[str, Any]]: allowed_states = cast(Sequence[StateType], self.states) for allowed_state in allowed_states: diff --git a/aiogram/filters/text.py b/aiogram/filters/text.py deleted file mode 100644 index bdef26f0..00000000 --- a/aiogram/filters/text.py +++ /dev/null @@ -1,136 +0,0 @@ -from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, Union - -from aiogram.filters.base import Filter -from aiogram.types import CallbackQuery, InlineQuery, Message, Poll - -if TYPE_CHECKING: - from aiogram.utils.i18n.lazy_proxy import LazyProxy # NOQA - -TextType = Union[str, "LazyProxy"] - - -class Text(Filter): - """ - Is useful for filtering text :class:`aiogram.types.message.Message`, - any :class:`aiogram.types.callback_query.CallbackQuery` with `data`, - :class:`aiogram.types.inline_query.InlineQuery` or :class:`aiogram.types.poll.Poll` question. - - .. warning:: - - Only one of `text`, `contains`, `startswith` or `endswith` argument can be used at once. - Any of that arguments can be string, list, set or tuple of strings. - - .. deprecated:: 3.0 - - use :ref:`magic-filter `. For example do :pycode:`F.text == "text"` instead - """ - - __slots__ = ( - "text", - "contains", - "startswith", - "endswith", - "ignore_case", - ) - - def __init__( - self, - text: Optional[Union[Sequence[TextType], TextType]] = None, - *, - contains: Optional[Union[Sequence[TextType], TextType]] = None, - startswith: Optional[Union[Sequence[TextType], TextType]] = None, - endswith: Optional[Union[Sequence[TextType], TextType]] = None, - ignore_case: bool = False, - ): - """ - - :param text: Text equals value or one of values - :param contains: Text contains value or one of values - :param startswith: Text starts with value or one of values - :param endswith: Text ends with value or one of values - :param ignore_case: Ignore case when checks - """ - self._validate_constraints( - text=text, - contains=contains, - startswith=startswith, - endswith=endswith, - ) - self.text = self._prepare_argument(text) - self.contains = self._prepare_argument(contains) - self.startswith = self._prepare_argument(startswith) - self.endswith = self._prepare_argument(endswith) - self.ignore_case = ignore_case - - def __str__(self) -> str: - return self._signature_to_string( - text=self.text, - contains=self.contains, - startswith=self.startswith, - endswith=self.endswith, - ignore_case=self.ignore_case, - ) - - @classmethod - def _prepare_argument( - cls, value: Optional[Union[Sequence[TextType], TextType]] - ) -> Optional[Sequence[TextType]]: - from aiogram.utils.i18n.lazy_proxy import LazyProxy - - if isinstance(value, (str, LazyProxy)): - return [value] - return value - - @classmethod - def _validate_constraints(cls, **values: Any) -> None: - # Validate that only one text filter type is presented - used_args = {key for key, value in values.items() if value is not None} - if len(used_args) < 1: - raise ValueError(f"Filter should contain one of arguments: {set(values.keys())}") - if len(used_args) > 1: - raise ValueError(f"Arguments {used_args} cannot be used together") - - async def __call__( - self, obj: Union[Message, CallbackQuery, InlineQuery, Poll] - ) -> Union[bool, Dict[str, Any]]: - if isinstance(obj, Message): - text = obj.text or obj.caption or "" - if not text and obj.poll: - text = obj.poll.question - elif isinstance(obj, CallbackQuery) and obj.data: - text = obj.data - elif isinstance(obj, InlineQuery): - text = obj.query - elif isinstance(obj, Poll): - text = obj.question - else: - return False - - if not text: - return False - if self.ignore_case: - text = text.lower() - - if self.text is not None: - equals = map(self.prepare_text, self.text) - return text in equals - - if self.contains is not None: - contains = map(self.prepare_text, self.contains) - return all(map(text.__contains__, contains)) - - if self.startswith is not None: - startswith = map(self.prepare_text, self.startswith) - return any(map(text.startswith, startswith)) - - if self.endswith is not None: - endswith = map(self.prepare_text, self.endswith) - return any(map(text.endswith, endswith)) - - # Impossible because the validator prevents this situation - return False # pragma: no cover - - def prepare_text(self, text: str) -> str: - if self.ignore_case: - return str(text).lower() - return str(text) diff --git a/aiogram/fsm/context.py b/aiogram/fsm/context.py index a66bcdbd..53a8ea46 100644 --- a/aiogram/fsm/context.py +++ b/aiogram/fsm/context.py @@ -1,33 +1,31 @@ from typing import Any, Dict, Optional -from aiogram import Bot from aiogram.fsm.storage.base import BaseStorage, StateType, StorageKey class FSMContext: - def __init__(self, bot: Bot, storage: BaseStorage, key: StorageKey) -> None: - self.bot = bot + def __init__(self, storage: BaseStorage, key: StorageKey) -> None: self.storage = storage self.key = key async def set_state(self, state: StateType = None) -> None: - await self.storage.set_state(bot=self.bot, key=self.key, state=state) + await self.storage.set_state(key=self.key, state=state) async def get_state(self) -> Optional[str]: - return await self.storage.get_state(bot=self.bot, key=self.key) + return await self.storage.get_state(key=self.key) async def set_data(self, data: Dict[str, Any]) -> None: - await self.storage.set_data(bot=self.bot, key=self.key, data=data) + await self.storage.set_data(key=self.key, data=data) async def get_data(self) -> Dict[str, Any]: - return await self.storage.get_data(bot=self.bot, key=self.key) + return await self.storage.get_data(key=self.key) async def update_data( self, data: Optional[Dict[str, Any]] = None, **kwargs: Any ) -> Dict[str, Any]: if data: kwargs.update(data) - return await self.storage.update_data(bot=self.bot, key=self.key, data=kwargs) + return await self.storage.update_data(key=self.key, data=kwargs) async def clear(self) -> None: await self.set_state(state=None) diff --git a/aiogram/fsm/middleware.py b/aiogram/fsm/middleware.py index 11faca61..6de91a83 100644 --- a/aiogram/fsm/middleware.py +++ b/aiogram/fsm/middleware.py @@ -35,7 +35,7 @@ class FSMContextMiddleware(BaseMiddleware): data["fsm_storage"] = self.storage if context: data.update({"state": context, "raw_state": await context.get_state()}) - async with self.events_isolation.lock(bot=bot, key=context.key): + async with self.events_isolation.lock(key=context.key): return await handler(event, data) return await handler(event, data) @@ -47,25 +47,42 @@ class FSMContextMiddleware(BaseMiddleware): ) -> Optional[FSMContext]: user = data.get("event_from_user") chat = data.get("event_chat") + thread_id = data.get("event_thread_id") chat_id = chat.id if chat else None user_id = user.id if user else None - return self.resolve_context(bot=bot, chat_id=chat_id, user_id=user_id, destiny=destiny) + return self.resolve_context( + bot=bot, + chat_id=chat_id, + user_id=user_id, + thread_id=thread_id, + destiny=destiny, + ) def resolve_context( self, bot: Bot, chat_id: Optional[int], user_id: Optional[int], + thread_id: Optional[int] = None, destiny: str = DEFAULT_DESTINY, ) -> Optional[FSMContext]: if chat_id is None: chat_id = user_id if chat_id is not None and user_id is not None: - chat_id, user_id = apply_strategy( - chat_id=chat_id, user_id=user_id, strategy=self.strategy + chat_id, user_id, thread_id = apply_strategy( + chat_id=chat_id, + user_id=user_id, + thread_id=thread_id, + strategy=self.strategy, + ) + return self.get_context( + bot=bot, + chat_id=chat_id, + user_id=user_id, + thread_id=thread_id, + destiny=destiny, ) - return self.get_context(bot=bot, chat_id=chat_id, user_id=user_id, destiny=destiny) return None def get_context( @@ -73,15 +90,16 @@ class FSMContextMiddleware(BaseMiddleware): bot: Bot, chat_id: int, user_id: int, + thread_id: Optional[int] = None, destiny: str = DEFAULT_DESTINY, ) -> FSMContext: return FSMContext( - bot=bot, storage=self.storage, key=StorageKey( user_id=user_id, chat_id=chat_id, bot_id=bot.id, + thread_id=thread_id, destiny=destiny, ), ) diff --git a/aiogram/fsm/storage/base.py b/aiogram/fsm/storage/base.py index 70c62f34..52cb62f2 100644 --- a/aiogram/fsm/storage/base.py +++ b/aiogram/fsm/storage/base.py @@ -3,7 +3,6 @@ from contextlib import asynccontextmanager from dataclasses import dataclass from typing import Any, AsyncGenerator, Dict, Optional, Union -from aiogram import Bot from aiogram.fsm.state import State StateType = Optional[Union[str, State]] @@ -16,6 +15,7 @@ class StorageKey: bot_id: int chat_id: int user_id: int + thread_id: Optional[int] = None destiny: str = DEFAULT_DESTINY @@ -25,61 +25,56 @@ class BaseStorage(ABC): """ @abstractmethod - async def set_state(self, bot: Bot, key: StorageKey, state: StateType = None) -> None: + async def set_state(self, key: StorageKey, state: StateType = None) -> None: """ Set state for specified key - :param bot: instance of the current bot :param key: storage key :param state: new state """ pass @abstractmethod - async def get_state(self, bot: Bot, key: StorageKey) -> Optional[str]: + async def get_state(self, key: StorageKey) -> Optional[str]: """ Get key state - :param bot: instance of the current bot :param key: storage key :return: current state """ pass @abstractmethod - async def set_data(self, bot: Bot, key: StorageKey, data: Dict[str, Any]) -> None: + async def set_data(self, key: StorageKey, data: Dict[str, Any]) -> None: """ Write data (replace) - :param bot: instance of the current bot :param key: storage key :param data: new data """ pass @abstractmethod - async def get_data(self, bot: Bot, key: StorageKey) -> Dict[str, Any]: + async def get_data(self, key: StorageKey) -> Dict[str, Any]: """ Get current data for key - :param bot: instance of the current bot :param key: storage key :return: current data """ pass - async def update_data(self, bot: Bot, key: StorageKey, data: Dict[str, Any]) -> Dict[str, Any]: + async def update_data(self, key: StorageKey, data: Dict[str, Any]) -> Dict[str, Any]: """ Update date in the storage for key (like dict.update) - :param bot: instance of the current bot :param key: storage key :param data: partial data :return: new data """ - current_data = await self.get_data(bot=bot, key=key) + current_data = await self.get_data(key=key) current_data.update(data) - await self.set_data(bot=bot, key=key, data=current_data) + await self.set_data(key=key, data=current_data) return current_data.copy() @abstractmethod @@ -93,12 +88,11 @@ class BaseStorage(ABC): class BaseEventIsolation(ABC): @abstractmethod @asynccontextmanager - async def lock(self, bot: Bot, key: StorageKey) -> AsyncGenerator[None, None]: + async def lock(self, key: StorageKey) -> AsyncGenerator[None, None]: """ Isolate events with lock. Will be used as context manager - :param bot: instance of the current bot :param key: storage key :return: An async generator """ diff --git a/aiogram/fsm/storage/memory.py b/aiogram/fsm/storage/memory.py index 8be371b6..d80a9fff 100644 --- a/aiogram/fsm/storage/memory.py +++ b/aiogram/fsm/storage/memory.py @@ -4,7 +4,6 @@ from contextlib import asynccontextmanager from dataclasses import dataclass, field from typing import Any, AsyncGenerator, DefaultDict, Dict, Hashable, Optional -from aiogram import Bot from aiogram.fsm.state import State from aiogram.fsm.storage.base import ( BaseEventIsolation, @@ -38,22 +37,22 @@ class MemoryStorage(BaseStorage): async def close(self) -> None: pass - async def set_state(self, bot: Bot, key: StorageKey, state: StateType = None) -> None: + async def set_state(self, key: StorageKey, state: StateType = None) -> None: self.storage[key].state = state.state if isinstance(state, State) else state - async def get_state(self, bot: Bot, key: StorageKey) -> Optional[str]: + async def get_state(self, key: StorageKey) -> Optional[str]: return self.storage[key].state - async def set_data(self, bot: Bot, key: StorageKey, data: Dict[str, Any]) -> None: + async def set_data(self, key: StorageKey, data: Dict[str, Any]) -> None: self.storage[key].data = data.copy() - async def get_data(self, bot: Bot, key: StorageKey) -> Dict[str, Any]: + async def get_data(self, key: StorageKey) -> Dict[str, Any]: return self.storage[key].data.copy() class DisabledEventIsolation(BaseEventIsolation): @asynccontextmanager - async def lock(self, bot: Bot, key: StorageKey) -> AsyncGenerator[None, None]: + async def lock(self, key: StorageKey) -> AsyncGenerator[None, None]: yield async def close(self) -> None: @@ -66,7 +65,7 @@ class SimpleEventIsolation(BaseEventIsolation): self._locks: DefaultDict[Hashable, Lock] = defaultdict(Lock) @asynccontextmanager - async def lock(self, bot: Bot, key: StorageKey) -> AsyncGenerator[None, None]: + async def lock(self, key: StorageKey) -> AsyncGenerator[None, None]: lock = self._locks[key] async with lock: yield diff --git a/aiogram/fsm/storage/redis.py b/aiogram/fsm/storage/redis.py index 2d8d5076..6a55d881 100644 --- a/aiogram/fsm/storage/redis.py +++ b/aiogram/fsm/storage/redis.py @@ -1,13 +1,13 @@ +import json from abc import ABC, abstractmethod from contextlib import asynccontextmanager -from typing import Any, AsyncGenerator, Dict, Literal, Optional, cast +from typing import Any, AsyncGenerator, Callable, Dict, Literal, Optional, cast from redis.asyncio.client import Redis from redis.asyncio.connection import ConnectionPool from redis.asyncio.lock import Lock from redis.typing import ExpiryT -from aiogram import Bot from aiogram.fsm.state import State from aiogram.fsm.storage.base import ( DEFAULT_DESTINY, @@ -18,6 +18,8 @@ from aiogram.fsm.storage.base import ( ) DEFAULT_REDIS_LOCK_KWARGS = {"timeout": 60} +_JsonLoads = Callable[..., Any] +_JsonDumps = Callable[..., str] class KeyBuilder(ABC): @@ -68,7 +70,10 @@ class DefaultKeyBuilder(KeyBuilder): parts = [self.prefix] if self.with_bot_id: parts.append(str(key.bot_id)) - parts.extend([str(key.chat_id), str(key.user_id)]) + parts.append(str(key.chat_id)) + if key.thread_id: + parts.append(str(key.thread_id)) + parts.append(str(key.user_id)) if self.with_destiny: parts.append(key.destiny) elif key.destiny != DEFAULT_DESTINY: @@ -93,13 +98,14 @@ class RedisStorage(BaseStorage): key_builder: Optional[KeyBuilder] = None, state_ttl: Optional[ExpiryT] = None, data_ttl: Optional[ExpiryT] = None, + json_loads: _JsonLoads = json.loads, + json_dumps: _JsonDumps = json.dumps, ) -> None: """ :param redis: Instance of Redis connection :param key_builder: builder that helps to convert contextual key to string :param state_ttl: TTL for state records :param data_ttl: TTL for data records - :param lock_kwargs: Custom arguments for Redis lock """ if key_builder is None: key_builder = DefaultKeyBuilder() @@ -107,6 +113,8 @@ class RedisStorage(BaseStorage): self.key_builder = key_builder self.state_ttl = state_ttl self.data_ttl = data_ttl + self.json_loads = json_loads + self.json_dumps = json_dumps @classmethod def from_url( @@ -134,7 +142,6 @@ class RedisStorage(BaseStorage): async def set_state( self, - bot: Bot, key: StorageKey, state: StateType = None, ) -> None: @@ -150,7 +157,6 @@ class RedisStorage(BaseStorage): async def get_state( self, - bot: Bot, key: StorageKey, ) -> Optional[str]: redis_key = self.key_builder.build(key, "state") @@ -161,7 +167,6 @@ class RedisStorage(BaseStorage): async def set_data( self, - bot: Bot, key: StorageKey, data: Dict[str, Any], ) -> None: @@ -171,13 +176,12 @@ class RedisStorage(BaseStorage): return await self.redis.set( redis_key, - bot.session.json_dumps(data), + self.json_dumps(data), ex=self.data_ttl, ) async def get_data( self, - bot: Bot, key: StorageKey, ) -> Dict[str, Any]: redis_key = self.key_builder.build(key, "data") @@ -186,7 +190,7 @@ class RedisStorage(BaseStorage): return {} if isinstance(value, bytes): value = value.decode("utf-8") - return cast(Dict[str, Any], bot.session.json_loads(value)) + return cast(Dict[str, Any], self.json_loads(value)) class RedisEventIsolation(BaseEventIsolation): @@ -220,7 +224,6 @@ class RedisEventIsolation(BaseEventIsolation): @asynccontextmanager async def lock( self, - bot: Bot, key: StorageKey, ) -> AsyncGenerator[None, None]: redis_key = self.key_builder.build(key, "lock") diff --git a/aiogram/fsm/strategy.py b/aiogram/fsm/strategy.py index 4f540a4a..2695d60e 100644 --- a/aiogram/fsm/strategy.py +++ b/aiogram/fsm/strategy.py @@ -1,16 +1,24 @@ from enum import Enum, auto -from typing import Tuple +from typing import Optional, Tuple class FSMStrategy(Enum): USER_IN_CHAT = auto() CHAT = auto() GLOBAL_USER = auto() + USER_IN_TOPIC = auto() -def apply_strategy(chat_id: int, user_id: int, strategy: FSMStrategy) -> Tuple[int, int]: +def apply_strategy( + strategy: FSMStrategy, + chat_id: int, + user_id: int, + thread_id: Optional[int] = None, +) -> Tuple[int, int, Optional[int]]: if strategy == FSMStrategy.CHAT: - return chat_id, chat_id + return chat_id, chat_id, None if strategy == FSMStrategy.GLOBAL_USER: - return user_id, user_id - return chat_id, user_id + return user_id, user_id, None + if strategy == FSMStrategy.USER_IN_TOPIC: + return chat_id, user_id, thread_id + return chat_id, user_id, None diff --git a/aiogram/handlers/base.py b/aiogram/handlers/base.py index 076016fa..0eb1b420 100644 --- a/aiogram/handlers/base.py +++ b/aiogram/handlers/base.py @@ -32,7 +32,7 @@ class BaseHandler(BaseHandlerMixin[T], ABC): if "bot" in self.data: return cast(Bot, self.data["bot"]) - return Bot.get_current(no_error=False) + raise RuntimeError("Bot instance not found in the context") @property def update(self) -> Update: diff --git a/aiogram/methods/__init__.py b/aiogram/methods/__init__.py index 5bf0edf5..fd887d7e 100644 --- a/aiogram/methods/__init__.py +++ b/aiogram/methods/__init__.py @@ -48,6 +48,7 @@ from .get_me import GetMe from .get_my_commands import GetMyCommands from .get_my_default_administrator_rights import GetMyDefaultAdministratorRights from .get_my_description import GetMyDescription +from .get_my_name import GetMyName from .get_my_short_description import GetMyShortDescription from .get_sticker_set import GetStickerSet from .get_updates import GetUpdates @@ -92,6 +93,7 @@ from .set_game_score import SetGameScore from .set_my_commands import SetMyCommands from .set_my_default_administrator_rights import SetMyDefaultAdministratorRights from .set_my_description import SetMyDescription +from .set_my_name import SetMyName from .set_my_short_description import SetMyShortDescription from .set_passport_data_errors import SetPassportDataErrors from .set_sticker_emoji_list import SetStickerEmojiList @@ -161,6 +163,7 @@ __all__ = ( "GetMyCommands", "GetMyDefaultAdministratorRights", "GetMyDescription", + "GetMyName", "GetMyShortDescription", "GetStickerSet", "GetUpdates", @@ -207,6 +210,7 @@ __all__ = ( "SetMyCommands", "SetMyDefaultAdministratorRights", "SetMyDescription", + "SetMyName", "SetMyShortDescription", "SetPassportDataErrors", "SetStickerEmojiList", diff --git a/aiogram/methods/add_sticker_to_set.py b/aiogram/methods/add_sticker_to_set.py index 49759b84..2c6502a5 100644 --- a/aiogram/methods/add_sticker_to_set.py +++ b/aiogram/methods/add_sticker_to_set.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from ..types import InputSticker from .base import TelegramMethod diff --git a/aiogram/methods/answer_callback_query.py b/aiogram/methods/answer_callback_query.py index 4b3e16fd..067c8b34 100644 --- a/aiogram/methods/answer_callback_query.py +++ b/aiogram/methods/answer_callback_query.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from .base import TelegramMethod diff --git a/aiogram/methods/answer_inline_query.py b/aiogram/methods/answer_inline_query.py index f7760cb0..70dc1169 100644 --- a/aiogram/methods/answer_inline_query.py +++ b/aiogram/methods/answer_inline_query.py @@ -1,8 +1,32 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional, Union -from ..types import InlineQueryResult +from pydantic import Field + +from ..types import ( + InlineQueryResultArticle, + InlineQueryResultAudio, + InlineQueryResultCachedAudio, + InlineQueryResultCachedDocument, + InlineQueryResultCachedGif, + InlineQueryResultCachedMpeg4Gif, + InlineQueryResultCachedPhoto, + InlineQueryResultCachedSticker, + InlineQueryResultCachedVideo, + InlineQueryResultCachedVoice, + InlineQueryResultContact, + InlineQueryResultDocument, + InlineQueryResultGame, + InlineQueryResultGif, + InlineQueryResultLocation, + InlineQueryResultMpeg4Gif, + InlineQueryResultPhoto, + InlineQueryResultsButton, + InlineQueryResultVenue, + InlineQueryResultVideo, + InlineQueryResultVoice, +) from .base import TelegramMethod @@ -20,15 +44,46 @@ class AnswerInlineQuery(TelegramMethod[bool]): inline_query_id: str """Unique identifier for the answered query""" - results: List[InlineQueryResult] + results: List[ + Union[ + InlineQueryResultCachedAudio, + InlineQueryResultCachedDocument, + InlineQueryResultCachedGif, + InlineQueryResultCachedMpeg4Gif, + InlineQueryResultCachedPhoto, + InlineQueryResultCachedSticker, + InlineQueryResultCachedVideo, + InlineQueryResultCachedVoice, + InlineQueryResultArticle, + InlineQueryResultAudio, + InlineQueryResultContact, + InlineQueryResultGame, + InlineQueryResultDocument, + InlineQueryResultGif, + InlineQueryResultLocation, + InlineQueryResultMpeg4Gif, + InlineQueryResultPhoto, + InlineQueryResultVenue, + InlineQueryResultVideo, + InlineQueryResultVoice, + ] + ] """A JSON-serialized array of results for the inline query""" cache_time: Optional[int] = None """The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300.""" is_personal: Optional[bool] = None - """Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query""" + """Pass :code:`True` if results may be cached on the server side only for the user that sent the 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.""" - 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 *switch_pm_parameter*""" - switch_pm_parameter: Optional[str] = None - """`Deep-linking `_ parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed.""" + button: Optional[InlineQueryResultsButton] = None + """A JSON-serialized object describing a button to be shown above inline query results""" + switch_pm_parameter: Optional[str] = Field(None, json_schema_extra={"deprecated": True}) + """`Deep-linking `_ parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed. + +.. deprecated:: API:6.7 + https://core.telegram.org/bots/api-changelog#april-21-2023""" + switch_pm_text: Optional[str] = Field(None, json_schema_extra={"deprecated": True}) + """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* + +.. deprecated:: API:6.7 + https://core.telegram.org/bots/api-changelog#april-21-2023""" diff --git a/aiogram/methods/answer_pre_checkout_query.py b/aiogram/methods/answer_pre_checkout_query.py index a87929fb..8d1679cd 100644 --- a/aiogram/methods/answer_pre_checkout_query.py +++ b/aiogram/methods/answer_pre_checkout_query.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from .base import TelegramMethod diff --git a/aiogram/methods/answer_shipping_query.py b/aiogram/methods/answer_shipping_query.py index 4e62d0cb..81c1eaa6 100644 --- a/aiogram/methods/answer_shipping_query.py +++ b/aiogram/methods/answer_shipping_query.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional from ..types import ShippingOption from .base import TelegramMethod diff --git a/aiogram/methods/answer_web_app_query.py b/aiogram/methods/answer_web_app_query.py index d45e249d..23def3e4 100644 --- a/aiogram/methods/answer_web_app_query.py +++ b/aiogram/methods/answer_web_app_query.py @@ -1,8 +1,30 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import Union -from ..types import InlineQueryResult, SentWebAppMessage +from ..types import ( + InlineQueryResultArticle, + InlineQueryResultAudio, + InlineQueryResultCachedAudio, + InlineQueryResultCachedDocument, + InlineQueryResultCachedGif, + InlineQueryResultCachedMpeg4Gif, + InlineQueryResultCachedPhoto, + InlineQueryResultCachedSticker, + InlineQueryResultCachedVideo, + InlineQueryResultCachedVoice, + InlineQueryResultContact, + InlineQueryResultDocument, + InlineQueryResultGame, + InlineQueryResultGif, + InlineQueryResultLocation, + InlineQueryResultMpeg4Gif, + InlineQueryResultPhoto, + InlineQueryResultVenue, + InlineQueryResultVideo, + InlineQueryResultVoice, + SentWebAppMessage, +) from .base import TelegramMethod @@ -18,5 +40,26 @@ class AnswerWebAppQuery(TelegramMethod[SentWebAppMessage]): web_app_query_id: str """Unique identifier for the query to be answered""" - result: InlineQueryResult + result: Union[ + InlineQueryResultCachedAudio, + InlineQueryResultCachedDocument, + InlineQueryResultCachedGif, + InlineQueryResultCachedMpeg4Gif, + InlineQueryResultCachedPhoto, + InlineQueryResultCachedSticker, + InlineQueryResultCachedVideo, + InlineQueryResultCachedVoice, + InlineQueryResultArticle, + InlineQueryResultAudio, + InlineQueryResultContact, + InlineQueryResultGame, + InlineQueryResultDocument, + InlineQueryResultGif, + InlineQueryResultLocation, + InlineQueryResultMpeg4Gif, + InlineQueryResultPhoto, + InlineQueryResultVenue, + InlineQueryResultVideo, + InlineQueryResultVoice, + ] """A JSON-serialized object describing the message to be sent""" diff --git a/aiogram/methods/approve_chat_join_request.py b/aiogram/methods/approve_chat_join_request.py index 83e34599..4e4693f8 100644 --- a/aiogram/methods/approve_chat_join_request.py +++ b/aiogram/methods/approve_chat_join_request.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/ban_chat_member.py b/aiogram/methods/ban_chat_member.py index ecc468ee..f64791fd 100644 --- a/aiogram/methods/ban_chat_member.py +++ b/aiogram/methods/ban_chat_member.py @@ -1,7 +1,7 @@ from __future__ import annotations import datetime -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from .base import TelegramMethod diff --git a/aiogram/methods/ban_chat_sender_chat.py b/aiogram/methods/ban_chat_sender_chat.py index e63f2ecc..50d51188 100644 --- a/aiogram/methods/ban_chat_sender_chat.py +++ b/aiogram/methods/ban_chat_sender_chat.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/base.py b/aiogram/methods/base.py index 33045bf0..221ad9c0 100644 --- a/aiogram/methods/base.py +++ b/aiogram/methods/base.py @@ -1,10 +1,21 @@ from __future__ import annotations from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Any, Dict, Generator, Generic, Optional, TypeVar +from typing import ( + TYPE_CHECKING, + Any, + ClassVar, + Dict, + Generator, + Generic, + Optional, + TypeVar, +) -from pydantic import BaseConfig, BaseModel, Extra, root_validator -from pydantic.generics import GenericModel +from pydantic import BaseModel, ConfigDict +from pydantic.functional_validators import model_validator + +from aiogram.client.context_controller import BotContextController from ..types import InputFile, ResponseParameters from ..types.base import UNSET_TYPE @@ -16,16 +27,15 @@ TelegramType = TypeVar("TelegramType", bound=Any) class Request(BaseModel): + model_config = ConfigDict(arbitrary_types_allowed=True) + method: str data: Dict[str, Optional[Any]] files: Optional[Dict[str, InputFile]] - class Config(BaseConfig): - arbitrary_types_allowed = True - -class Response(GenericModel, Generic[TelegramType]): +class Response(BaseModel, Generic[TelegramType]): ok: bool result: Optional[TelegramType] = None description: Optional[str] = None @@ -33,16 +43,15 @@ class Response(GenericModel, Generic[TelegramType]): parameters: Optional[ResponseParameters] = None -class TelegramMethod(ABC, BaseModel, Generic[TelegramType]): - class Config(BaseConfig): - # use_enum_values = True - extra = Extra.allow - allow_population_by_field_name = True - arbitrary_types_allowed = True - orm_mode = True - smart_union = True # https://github.com/aiogram/aiogram/issues/901 +class TelegramMethod(BotContextController, BaseModel, Generic[TelegramType], ABC): + model_config = ConfigDict( + extra="allow", + populate_by_name=True, + arbitrary_types_allowed=True, + ) - @root_validator(pre=True) + @model_validator(mode="before") + @classmethod def remove_unset(cls, values: Dict[str, Any]) -> Dict[str, Any]: """ Remove UNSET before fields validation. @@ -54,33 +63,31 @@ class TelegramMethod(ABC, BaseModel, Generic[TelegramType]): """ return {k: v for k, v in values.items() if not isinstance(v, UNSET_TYPE)} - @property - @abstractmethod - def __returning__(self) -> type: # pragma: no cover - pass + if TYPE_CHECKING: + __returning__: ClassVar[type] + __api_method__: ClassVar[str] + else: - @property - @abstractmethod - def __api_method__(self) -> str: - pass + @property + @abstractmethod + def __returning__(self) -> type: + pass - def dict(self, **kwargs: Any) -> Any: - # override dict of pydantic.BaseModel to overcome exporting request_timeout field - exclude = kwargs.pop("exclude", set()) - - return super().dict(exclude=exclude, **kwargs) - - def build_response(self, data: Dict[str, Any]) -> Response[TelegramType]: - # noinspection PyTypeChecker - return Response[self.__returning__](**data) # type: ignore + @property + @abstractmethod + def __api_method__(self) -> str: + pass async def emit(self, bot: Bot) -> TelegramType: return await bot(self) - as_ = emit - def __await__(self) -> Generator[Any, None, TelegramType]: - from aiogram.client.bot import Bot - - bot = Bot.get_current(no_error=False) + bot = self._bot + if not bot: + raise RuntimeError( + "This method is not mounted to a any bot instance, please call it explicilty " + "with bot instance `await bot(method)`\n" + "or mount method to a bot instance `method.as_(bot)` " + "and then call it `await method()`" + ) return self.emit(bot).__await__() diff --git a/aiogram/methods/close.py b/aiogram/methods/close.py index c8e9008d..7c33eca3 100644 --- a/aiogram/methods/close.py +++ b/aiogram/methods/close.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from .base import TelegramMethod diff --git a/aiogram/methods/close_forum_topic.py b/aiogram/methods/close_forum_topic.py index 7ab5a479..3f9f50ea 100644 --- a/aiogram/methods/close_forum_topic.py +++ b/aiogram/methods/close_forum_topic.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/close_general_forum_topic.py b/aiogram/methods/close_general_forum_topic.py index bc44bde5..3c836177 100644 --- a/aiogram/methods/close_general_forum_topic.py +++ b/aiogram/methods/close_general_forum_topic.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/copy_message.py b/aiogram/methods/copy_message.py index 5e34bb7d..4fc4b5b9 100644 --- a/aiogram/methods/copy_message.py +++ b/aiogram/methods/copy_message.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import ( UNSET_PARSE_MODE, diff --git a/aiogram/methods/create_chat_invite_link.py b/aiogram/methods/create_chat_invite_link.py index 539115bb..1bdae992 100644 --- a/aiogram/methods/create_chat_invite_link.py +++ b/aiogram/methods/create_chat_invite_link.py @@ -1,7 +1,7 @@ from __future__ import annotations import datetime -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ChatInviteLink from .base import TelegramMethod diff --git a/aiogram/methods/create_forum_topic.py b/aiogram/methods/create_forum_topic.py index f4b3f4da..ece98d43 100644 --- a/aiogram/methods/create_forum_topic.py +++ b/aiogram/methods/create_forum_topic.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ForumTopic from .base import TelegramMethod diff --git a/aiogram/methods/create_invoice_link.py b/aiogram/methods/create_invoice_link.py index de6497c1..8b6fc883 100644 --- a/aiogram/methods/create_invoice_link.py +++ b/aiogram/methods/create_invoice_link.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional from ..types import LabeledPrice from .base import TelegramMethod diff --git a/aiogram/methods/create_new_sticker_set.py b/aiogram/methods/create_new_sticker_set.py index 6406df81..abf25d79 100644 --- a/aiogram/methods/create_new_sticker_set.py +++ b/aiogram/methods/create_new_sticker_set.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional from ..types import InputSticker from .base import TelegramMethod diff --git a/aiogram/methods/decline_chat_join_request.py b/aiogram/methods/decline_chat_join_request.py index 7861b7bb..0334c299 100644 --- a/aiogram/methods/decline_chat_join_request.py +++ b/aiogram/methods/decline_chat_join_request.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/delete_chat_photo.py b/aiogram/methods/delete_chat_photo.py index 11a3836e..e146cdac 100644 --- a/aiogram/methods/delete_chat_photo.py +++ b/aiogram/methods/delete_chat_photo.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/delete_chat_sticker_set.py b/aiogram/methods/delete_chat_sticker_set.py index 681293df..2162f860 100644 --- a/aiogram/methods/delete_chat_sticker_set.py +++ b/aiogram/methods/delete_chat_sticker_set.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/delete_forum_topic.py b/aiogram/methods/delete_forum_topic.py index 4733c67d..1e4f9b46 100644 --- a/aiogram/methods/delete_forum_topic.py +++ b/aiogram/methods/delete_forum_topic.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/delete_message.py b/aiogram/methods/delete_message.py index 468411d5..99c972d7 100644 --- a/aiogram/methods/delete_message.py +++ b/aiogram/methods/delete_message.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/delete_my_commands.py b/aiogram/methods/delete_my_commands.py index d73814db..cd91b7e7 100644 --- a/aiogram/methods/delete_my_commands.py +++ b/aiogram/methods/delete_my_commands.py @@ -1,8 +1,16 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional, Union -from ..types import BotCommandScope +from ..types import ( + BotCommandScopeAllChatAdministrators, + BotCommandScopeAllGroupChats, + BotCommandScopeAllPrivateChats, + BotCommandScopeChat, + BotCommandScopeChatAdministrators, + BotCommandScopeChatMember, + BotCommandScopeDefault, +) from .base import TelegramMethod @@ -16,7 +24,17 @@ class DeleteMyCommands(TelegramMethod[bool]): __returning__ = bool __api_method__ = "deleteMyCommands" - scope: Optional[BotCommandScope] = None + scope: Optional[ + Union[ + BotCommandScopeDefault, + BotCommandScopeAllPrivateChats, + BotCommandScopeAllGroupChats, + BotCommandScopeAllChatAdministrators, + BotCommandScopeChat, + BotCommandScopeChatAdministrators, + BotCommandScopeChatMember, + ] + ] = None """A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`.""" language_code: Optional[str] = None """A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands""" diff --git a/aiogram/methods/delete_sticker_from_set.py b/aiogram/methods/delete_sticker_from_set.py index 96219c15..1ab3e3a8 100644 --- a/aiogram/methods/delete_sticker_from_set.py +++ b/aiogram/methods/delete_sticker_from_set.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from .base import TelegramMethod diff --git a/aiogram/methods/delete_sticker_set.py b/aiogram/methods/delete_sticker_set.py index d5a0f67e..27b4cfc2 100644 --- a/aiogram/methods/delete_sticker_set.py +++ b/aiogram/methods/delete_sticker_set.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from .base import TelegramMethod diff --git a/aiogram/methods/delete_webhook.py b/aiogram/methods/delete_webhook.py index b9d6cd7b..ef1bdc88 100644 --- a/aiogram/methods/delete_webhook.py +++ b/aiogram/methods/delete_webhook.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from .base import TelegramMethod diff --git a/aiogram/methods/edit_chat_invite_link.py b/aiogram/methods/edit_chat_invite_link.py index 26f4ccc3..f94111ed 100644 --- a/aiogram/methods/edit_chat_invite_link.py +++ b/aiogram/methods/edit_chat_invite_link.py @@ -1,7 +1,7 @@ from __future__ import annotations import datetime -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ChatInviteLink from .base import TelegramMethod diff --git a/aiogram/methods/edit_forum_topic.py b/aiogram/methods/edit_forum_topic.py index f87d0cea..46ef0e58 100644 --- a/aiogram/methods/edit_forum_topic.py +++ b/aiogram/methods/edit_forum_topic.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from .base import TelegramMethod diff --git a/aiogram/methods/edit_general_forum_topic.py b/aiogram/methods/edit_general_forum_topic.py index f35c2048..1de088cf 100644 --- a/aiogram/methods/edit_general_forum_topic.py +++ b/aiogram/methods/edit_general_forum_topic.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/edit_message_caption.py b/aiogram/methods/edit_message_caption.py index 66cdeac9..ee2f8482 100644 --- a/aiogram/methods/edit_message_caption.py +++ b/aiogram/methods/edit_message_caption.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import UNSET_PARSE_MODE, InlineKeyboardMarkup, Message, MessageEntity from .base import TelegramMethod diff --git a/aiogram/methods/edit_message_live_location.py b/aiogram/methods/edit_message_live_location.py index e35c3225..43ff24e7 100644 --- a/aiogram/methods/edit_message_live_location.py +++ b/aiogram/methods/edit_message_live_location.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import InlineKeyboardMarkup, Message from .base import TelegramMethod diff --git a/aiogram/methods/edit_message_media.py b/aiogram/methods/edit_message_media.py index f986a841..5d006146 100644 --- a/aiogram/methods/edit_message_media.py +++ b/aiogram/methods/edit_message_media.py @@ -1,8 +1,16 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union -from ..types import InlineKeyboardMarkup, InputMedia, Message +from ..types import ( + InlineKeyboardMarkup, + InputMediaAnimation, + InputMediaAudio, + InputMediaDocument, + InputMediaPhoto, + InputMediaVideo, + Message, +) from .base import TelegramMethod @@ -16,7 +24,9 @@ class EditMessageMedia(TelegramMethod[Union[Message, bool]]): __returning__ = Union[Message, bool] __api_method__ = "editMessageMedia" - media: InputMedia + media: Union[ + InputMediaAnimation, InputMediaDocument, InputMediaAudio, InputMediaPhoto, InputMediaVideo + ] """A JSON-serialized object for a new media content of the message""" chat_id: Optional[Union[int, str]] = None """Required if *inline_message_id* is not specified. Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)""" diff --git a/aiogram/methods/edit_message_reply_markup.py b/aiogram/methods/edit_message_reply_markup.py index a828c9d8..7c8be63f 100644 --- a/aiogram/methods/edit_message_reply_markup.py +++ b/aiogram/methods/edit_message_reply_markup.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import InlineKeyboardMarkup, Message from .base import TelegramMethod diff --git a/aiogram/methods/edit_message_text.py b/aiogram/methods/edit_message_text.py index 79887c97..357a757b 100644 --- a/aiogram/methods/edit_message_text.py +++ b/aiogram/methods/edit_message_text.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import UNSET_PARSE_MODE, InlineKeyboardMarkup, Message, MessageEntity from ..types.base import UNSET_DISABLE_WEB_PAGE_PREVIEW diff --git a/aiogram/methods/export_chat_invite_link.py b/aiogram/methods/export_chat_invite_link.py index ba4436ed..61642387 100644 --- a/aiogram/methods/export_chat_invite_link.py +++ b/aiogram/methods/export_chat_invite_link.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/forward_message.py b/aiogram/methods/forward_message.py index 45c084a0..86d33f8d 100644 --- a/aiogram/methods/forward_message.py +++ b/aiogram/methods/forward_message.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import Message from ..types.base import UNSET_PROTECT_CONTENT diff --git a/aiogram/methods/get_chat.py b/aiogram/methods/get_chat.py index a565529a..d0416238 100644 --- a/aiogram/methods/get_chat.py +++ b/aiogram/methods/get_chat.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from ..types import Chat from .base import TelegramMethod diff --git a/aiogram/methods/get_chat_administrators.py b/aiogram/methods/get_chat_administrators.py index 3e0cac3c..b6479ec8 100644 --- a/aiogram/methods/get_chat_administrators.py +++ b/aiogram/methods/get_chat_administrators.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Union +from typing import List, Union from ..types import ( ChatMemberAdministrator, diff --git a/aiogram/methods/get_chat_member.py b/aiogram/methods/get_chat_member.py index ab308024..9e8ba619 100644 --- a/aiogram/methods/get_chat_member.py +++ b/aiogram/methods/get_chat_member.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from ..types import ( ChatMemberAdministrator, diff --git a/aiogram/methods/get_chat_member_count.py b/aiogram/methods/get_chat_member_count.py index c1b08e5b..a411d0c9 100644 --- a/aiogram/methods/get_chat_member_count.py +++ b/aiogram/methods/get_chat_member_count.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/get_chat_menu_button.py b/aiogram/methods/get_chat_menu_button.py index 6679d5df..df280b66 100644 --- a/aiogram/methods/get_chat_menu_button.py +++ b/aiogram/methods/get_chat_menu_button.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import MenuButtonCommands, MenuButtonDefault, MenuButtonWebApp from .base import TelegramMethod diff --git a/aiogram/methods/get_custom_emoji_stickers.py b/aiogram/methods/get_custom_emoji_stickers.py index 3522b539..a98582d9 100644 --- a/aiogram/methods/get_custom_emoji_stickers.py +++ b/aiogram/methods/get_custom_emoji_stickers.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List +from typing import List from ..types import Sticker from .base import TelegramMethod diff --git a/aiogram/methods/get_file.py b/aiogram/methods/get_file.py index b84ff940..8358e250 100644 --- a/aiogram/methods/get_file.py +++ b/aiogram/methods/get_file.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from ..types import File from .base import TelegramMethod diff --git a/aiogram/methods/get_forum_topic_icon_stickers.py b/aiogram/methods/get_forum_topic_icon_stickers.py index 31965661..5c233215 100644 --- a/aiogram/methods/get_forum_topic_icon_stickers.py +++ b/aiogram/methods/get_forum_topic_icon_stickers.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List +from typing import List from ..types import Sticker from .base import TelegramMethod diff --git a/aiogram/methods/get_game_high_scores.py b/aiogram/methods/get_game_high_scores.py index aff1c56a..1251658c 100644 --- a/aiogram/methods/get_game_high_scores.py +++ b/aiogram/methods/get_game_high_scores.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional from ..types import GameHighScore from .base import TelegramMethod diff --git a/aiogram/methods/get_me.py b/aiogram/methods/get_me.py index 1a7f1fe1..c2cc52f9 100644 --- a/aiogram/methods/get_me.py +++ b/aiogram/methods/get_me.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from ..types import User from .base import TelegramMethod diff --git a/aiogram/methods/get_my_commands.py b/aiogram/methods/get_my_commands.py index d1e5c9c3..4be74e21 100644 --- a/aiogram/methods/get_my_commands.py +++ b/aiogram/methods/get_my_commands.py @@ -1,8 +1,17 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional, Union -from ..types import BotCommand, BotCommandScope +from ..types import ( + BotCommand, + BotCommandScopeAllChatAdministrators, + BotCommandScopeAllGroupChats, + BotCommandScopeAllPrivateChats, + BotCommandScopeChat, + BotCommandScopeChatAdministrators, + BotCommandScopeChatMember, + BotCommandScopeDefault, +) from .base import TelegramMethod @@ -16,7 +25,17 @@ class GetMyCommands(TelegramMethod[List[BotCommand]]): __returning__ = List[BotCommand] __api_method__ = "getMyCommands" - scope: Optional[BotCommandScope] = None + scope: Optional[ + Union[ + BotCommandScopeDefault, + BotCommandScopeAllPrivateChats, + BotCommandScopeAllGroupChats, + BotCommandScopeAllChatAdministrators, + BotCommandScopeChat, + BotCommandScopeChatAdministrators, + BotCommandScopeChatMember, + ] + ] = None """A JSON-serialized object, describing scope of users. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`.""" language_code: Optional[str] = None """A two-letter ISO 639-1 language code or an empty string""" diff --git a/aiogram/methods/get_my_default_administrator_rights.py b/aiogram/methods/get_my_default_administrator_rights.py index d20e7a15..1c7c0195 100644 --- a/aiogram/methods/get_my_default_administrator_rights.py +++ b/aiogram/methods/get_my_default_administrator_rights.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from ..types import ChatAdministratorRights from .base import TelegramMethod diff --git a/aiogram/methods/get_my_description.py b/aiogram/methods/get_my_description.py index 3b0534ff..db002daa 100644 --- a/aiogram/methods/get_my_description.py +++ b/aiogram/methods/get_my_description.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from ..types import BotDescription from .base import TelegramMethod diff --git a/aiogram/methods/get_my_name.py b/aiogram/methods/get_my_name.py new file mode 100644 index 00000000..202b21ff --- /dev/null +++ b/aiogram/methods/get_my_name.py @@ -0,0 +1,18 @@ +from typing import Optional + +from ..types import BotName +from .base import TelegramMethod + + +class GetMyName(TelegramMethod[BotName]): + """ + Use this method to get the current bot name for the given user language. Returns :class:`aiogram.types.bot_name.BotName` on success. + + Source: https://core.telegram.org/bots/api#getmyname + """ + + __returning__ = BotName + __api_method__ = "getMyName" + + language_code: Optional[str] = None + """A two-letter ISO 639-1 language code or an empty string""" diff --git a/aiogram/methods/get_my_short_description.py b/aiogram/methods/get_my_short_description.py index 81731142..962642e4 100644 --- a/aiogram/methods/get_my_short_description.py +++ b/aiogram/methods/get_my_short_description.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from ..types import BotShortDescription from .base import TelegramMethod diff --git a/aiogram/methods/get_sticker_set.py b/aiogram/methods/get_sticker_set.py index 87041172..43ab5311 100644 --- a/aiogram/methods/get_sticker_set.py +++ b/aiogram/methods/get_sticker_set.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from ..types import StickerSet from .base import TelegramMethod diff --git a/aiogram/methods/get_updates.py b/aiogram/methods/get_updates.py index 8c60f051..80abf78c 100644 --- a/aiogram/methods/get_updates.py +++ b/aiogram/methods/get_updates.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional from ..types import Update from .base import TelegramMethod @@ -23,7 +23,7 @@ class GetUpdates(TelegramMethod[List[Update]]): __api_method__ = "getUpdates" offset: Optional[int] = None - """Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as :class:`aiogram.methods.get_updates.GetUpdates` is called with an *offset* higher than its *update_id*. The negative offset can be specified to retrieve updates starting from *-offset* update from the end of the updates queue. All previous updates will forgotten.""" + """Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as :class:`aiogram.methods.get_updates.GetUpdates` is called with an *offset* higher than its *update_id*. The negative offset can be specified to retrieve updates starting from *-offset* update from the end of the updates queue. All previous updates will be forgotten.""" limit: Optional[int] = None """Limits the number of updates to be retrieved. Values between 1-100 are accepted. Defaults to 100.""" timeout: Optional[int] = None diff --git a/aiogram/methods/get_user_profile_photos.py b/aiogram/methods/get_user_profile_photos.py index 47abc196..e58bd970 100644 --- a/aiogram/methods/get_user_profile_photos.py +++ b/aiogram/methods/get_user_profile_photos.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from ..types import UserProfilePhotos from .base import TelegramMethod diff --git a/aiogram/methods/get_webhook_info.py b/aiogram/methods/get_webhook_info.py index 5e4e194c..c9f0e46f 100644 --- a/aiogram/methods/get_webhook_info.py +++ b/aiogram/methods/get_webhook_info.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from ..types import WebhookInfo from .base import TelegramMethod diff --git a/aiogram/methods/hide_general_forum_topic.py b/aiogram/methods/hide_general_forum_topic.py index 2587cf9e..25e6421b 100644 --- a/aiogram/methods/hide_general_forum_topic.py +++ b/aiogram/methods/hide_general_forum_topic.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/leave_chat.py b/aiogram/methods/leave_chat.py index 5b2e15cf..f1784f65 100644 --- a/aiogram/methods/leave_chat.py +++ b/aiogram/methods/leave_chat.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/log_out.py b/aiogram/methods/log_out.py index 3f3ea3de..2a626535 100644 --- a/aiogram/methods/log_out.py +++ b/aiogram/methods/log_out.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from .base import TelegramMethod diff --git a/aiogram/methods/pin_chat_message.py b/aiogram/methods/pin_chat_message.py index d1641eea..24e7a7c1 100644 --- a/aiogram/methods/pin_chat_message.py +++ b/aiogram/methods/pin_chat_message.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from .base import TelegramMethod diff --git a/aiogram/methods/promote_chat_member.py b/aiogram/methods/promote_chat_member.py index d8f6096f..c74d1de9 100644 --- a/aiogram/methods/promote_chat_member.py +++ b/aiogram/methods/promote_chat_member.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from .base import TelegramMethod diff --git a/aiogram/methods/reopen_forum_topic.py b/aiogram/methods/reopen_forum_topic.py index efe1c31d..729db37c 100644 --- a/aiogram/methods/reopen_forum_topic.py +++ b/aiogram/methods/reopen_forum_topic.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/reopen_general_forum_topic.py b/aiogram/methods/reopen_general_forum_topic.py index 381278a9..ea3a4a47 100644 --- a/aiogram/methods/reopen_general_forum_topic.py +++ b/aiogram/methods/reopen_general_forum_topic.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/restrict_chat_member.py b/aiogram/methods/restrict_chat_member.py index efea2f97..9240ea60 100644 --- a/aiogram/methods/restrict_chat_member.py +++ b/aiogram/methods/restrict_chat_member.py @@ -1,7 +1,7 @@ from __future__ import annotations import datetime -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ChatPermissions from .base import TelegramMethod diff --git a/aiogram/methods/revoke_chat_invite_link.py b/aiogram/methods/revoke_chat_invite_link.py index ad31e77d..e7d9c50e 100644 --- a/aiogram/methods/revoke_chat_invite_link.py +++ b/aiogram/methods/revoke_chat_invite_link.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from ..types import ChatInviteLink from .base import TelegramMethod diff --git a/aiogram/methods/send_animation.py b/aiogram/methods/send_animation.py index 14029d25..088ce252 100644 --- a/aiogram/methods/send_animation.py +++ b/aiogram/methods/send_animation.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import ( UNSET_PARSE_MODE, diff --git a/aiogram/methods/send_audio.py b/aiogram/methods/send_audio.py index e0f4b900..e947cbde 100644 --- a/aiogram/methods/send_audio.py +++ b/aiogram/methods/send_audio.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import ( UNSET_PARSE_MODE, diff --git a/aiogram/methods/send_chat_action.py b/aiogram/methods/send_chat_action.py index d21dc68c..009fea09 100644 --- a/aiogram/methods/send_chat_action.py +++ b/aiogram/methods/send_chat_action.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from .base import TelegramMethod diff --git a/aiogram/methods/send_contact.py b/aiogram/methods/send_contact.py index 35473338..d0454674 100644 --- a/aiogram/methods/send_contact.py +++ b/aiogram/methods/send_contact.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ( ForceReply, diff --git a/aiogram/methods/send_dice.py b/aiogram/methods/send_dice.py index 9fa2ce70..bc58d53a 100644 --- a/aiogram/methods/send_dice.py +++ b/aiogram/methods/send_dice.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ( ForceReply, diff --git a/aiogram/methods/send_document.py b/aiogram/methods/send_document.py index 5c83beb3..cacb62a5 100644 --- a/aiogram/methods/send_document.py +++ b/aiogram/methods/send_document.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import ( UNSET_PARSE_MODE, diff --git a/aiogram/methods/send_game.py b/aiogram/methods/send_game.py index ab55a459..f713d6a6 100644 --- a/aiogram/methods/send_game.py +++ b/aiogram/methods/send_game.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from ..types import InlineKeyboardMarkup, Message from ..types.base import UNSET_PROTECT_CONTENT diff --git a/aiogram/methods/send_invoice.py b/aiogram/methods/send_invoice.py index d08002a9..aca8aa71 100644 --- a/aiogram/methods/send_invoice.py +++ b/aiogram/methods/send_invoice.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import InlineKeyboardMarkup, LabeledPrice, Message from ..types.base import UNSET_PROTECT_CONTENT diff --git a/aiogram/methods/send_location.py b/aiogram/methods/send_location.py index 845b4741..ddfb3604 100644 --- a/aiogram/methods/send_location.py +++ b/aiogram/methods/send_location.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ( ForceReply, diff --git a/aiogram/methods/send_media_group.py b/aiogram/methods/send_media_group.py index fd8dbb25..a01e4de8 100644 --- a/aiogram/methods/send_media_group.py +++ b/aiogram/methods/send_media_group.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import ( InputMediaAudio, diff --git a/aiogram/methods/send_message.py b/aiogram/methods/send_message.py index 9b7dae7b..1e460239 100644 --- a/aiogram/methods/send_message.py +++ b/aiogram/methods/send_message.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import ( UNSET_PARSE_MODE, diff --git a/aiogram/methods/send_photo.py b/aiogram/methods/send_photo.py index 236d8710..6ce9d928 100644 --- a/aiogram/methods/send_photo.py +++ b/aiogram/methods/send_photo.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import ( UNSET_PARSE_MODE, diff --git a/aiogram/methods/send_poll.py b/aiogram/methods/send_poll.py index fca3dc58..41d7e4c5 100644 --- a/aiogram/methods/send_poll.py +++ b/aiogram/methods/send_poll.py @@ -1,7 +1,7 @@ from __future__ import annotations import datetime -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import ( UNSET_PARSE_MODE, diff --git a/aiogram/methods/send_sticker.py b/aiogram/methods/send_sticker.py index 8429b105..384a5adb 100644 --- a/aiogram/methods/send_sticker.py +++ b/aiogram/methods/send_sticker.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ( ForceReply, diff --git a/aiogram/methods/send_venue.py b/aiogram/methods/send_venue.py index d0859770..ac69fdc6 100644 --- a/aiogram/methods/send_venue.py +++ b/aiogram/methods/send_venue.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ( ForceReply, diff --git a/aiogram/methods/send_video.py b/aiogram/methods/send_video.py index a894e335..1ee7c903 100644 --- a/aiogram/methods/send_video.py +++ b/aiogram/methods/send_video.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import ( UNSET_PARSE_MODE, diff --git a/aiogram/methods/send_video_note.py b/aiogram/methods/send_video_note.py index 761c91a2..cd270e94 100644 --- a/aiogram/methods/send_video_note.py +++ b/aiogram/methods/send_video_note.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ( ForceReply, diff --git a/aiogram/methods/send_voice.py b/aiogram/methods/send_voice.py index ae692ad6..d9c915f4 100644 --- a/aiogram/methods/send_voice.py +++ b/aiogram/methods/send_voice.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import List, Optional, Union from ..types import ( UNSET_PARSE_MODE, diff --git a/aiogram/methods/set_chat_administrator_custom_title.py b/aiogram/methods/set_chat_administrator_custom_title.py index edf79d8c..5415594f 100644 --- a/aiogram/methods/set_chat_administrator_custom_title.py +++ b/aiogram/methods/set_chat_administrator_custom_title.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/set_chat_description.py b/aiogram/methods/set_chat_description.py index 05b51a69..81eaf263 100644 --- a/aiogram/methods/set_chat_description.py +++ b/aiogram/methods/set_chat_description.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from .base import TelegramMethod diff --git a/aiogram/methods/set_chat_menu_button.py b/aiogram/methods/set_chat_menu_button.py index 6eeb3a10..9cbd019b 100644 --- a/aiogram/methods/set_chat_menu_button.py +++ b/aiogram/methods/set_chat_menu_button.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import MenuButtonCommands, MenuButtonDefault, MenuButtonWebApp from .base import TelegramMethod @@ -18,5 +18,5 @@ class SetChatMenuButton(TelegramMethod[bool]): chat_id: Optional[int] = None """Unique identifier for the target private chat. If not specified, default bot's menu button will be changed""" - menu_button: Optional[Union[MenuButtonDefault, MenuButtonWebApp, MenuButtonCommands]] = None + menu_button: Optional[Union[MenuButtonCommands, MenuButtonWebApp, MenuButtonDefault]] = None """A JSON-serialized object for the bot's new menu button. Defaults to :class:`aiogram.types.menu_button_default.MenuButtonDefault`""" diff --git a/aiogram/methods/set_chat_permissions.py b/aiogram/methods/set_chat_permissions.py index af13ddb7..3c3ed008 100644 --- a/aiogram/methods/set_chat_permissions.py +++ b/aiogram/methods/set_chat_permissions.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import ChatPermissions from .base import TelegramMethod diff --git a/aiogram/methods/set_chat_photo.py b/aiogram/methods/set_chat_photo.py index ba7b8de3..dc07a445 100644 --- a/aiogram/methods/set_chat_photo.py +++ b/aiogram/methods/set_chat_photo.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from ..types import InputFile from .base import TelegramMethod diff --git a/aiogram/methods/set_chat_sticker_set.py b/aiogram/methods/set_chat_sticker_set.py index a7f3d216..6df42a0a 100644 --- a/aiogram/methods/set_chat_sticker_set.py +++ b/aiogram/methods/set_chat_sticker_set.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/set_chat_title.py b/aiogram/methods/set_chat_title.py index 07507d0f..b4ce0a4a 100644 --- a/aiogram/methods/set_chat_title.py +++ b/aiogram/methods/set_chat_title.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/set_custom_emoji_sticker_set_thumbnail.py b/aiogram/methods/set_custom_emoji_sticker_set_thumbnail.py index 10a4a267..8c8fa479 100644 --- a/aiogram/methods/set_custom_emoji_sticker_set_thumbnail.py +++ b/aiogram/methods/set_custom_emoji_sticker_set_thumbnail.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from .base import TelegramMethod diff --git a/aiogram/methods/set_game_score.py b/aiogram/methods/set_game_score.py index 170988ec..590ca59d 100644 --- a/aiogram/methods/set_game_score.py +++ b/aiogram/methods/set_game_score.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import Message from .base import TelegramMethod diff --git a/aiogram/methods/set_my_commands.py b/aiogram/methods/set_my_commands.py index a62e7a84..3aff027f 100644 --- a/aiogram/methods/set_my_commands.py +++ b/aiogram/methods/set_my_commands.py @@ -1,8 +1,17 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional, Union -from ..types import BotCommand, BotCommandScope +from ..types import ( + BotCommand, + BotCommandScopeAllChatAdministrators, + BotCommandScopeAllGroupChats, + BotCommandScopeAllPrivateChats, + BotCommandScopeChat, + BotCommandScopeChatAdministrators, + BotCommandScopeChatMember, + BotCommandScopeDefault, +) from .base import TelegramMethod @@ -18,7 +27,17 @@ class SetMyCommands(TelegramMethod[bool]): commands: List[BotCommand] """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.""" - scope: Optional[BotCommandScope] = None + scope: Optional[ + Union[ + BotCommandScopeDefault, + BotCommandScopeAllPrivateChats, + BotCommandScopeAllGroupChats, + BotCommandScopeAllChatAdministrators, + BotCommandScopeChat, + BotCommandScopeChatAdministrators, + BotCommandScopeChatMember, + ] + ] = None """A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`.""" language_code: Optional[str] = None """A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands""" diff --git a/aiogram/methods/set_my_default_administrator_rights.py b/aiogram/methods/set_my_default_administrator_rights.py index 0b1468bc..8817a9dc 100644 --- a/aiogram/methods/set_my_default_administrator_rights.py +++ b/aiogram/methods/set_my_default_administrator_rights.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from ..types import ChatAdministratorRights from .base import TelegramMethod diff --git a/aiogram/methods/set_my_description.py b/aiogram/methods/set_my_description.py index 2af2ed44..fba6b8d3 100644 --- a/aiogram/methods/set_my_description.py +++ b/aiogram/methods/set_my_description.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from .base import TelegramMethod diff --git a/aiogram/methods/set_my_name.py b/aiogram/methods/set_my_name.py new file mode 100644 index 00000000..9b392281 --- /dev/null +++ b/aiogram/methods/set_my_name.py @@ -0,0 +1,19 @@ +from typing import Optional + +from .base import TelegramMethod + + +class SetMyName(TelegramMethod[bool]): + """ + Use this method to change the bot's name. Returns :code:`True` on success. + + Source: https://core.telegram.org/bots/api#setmyname + """ + + __returning__ = bool + __api_method__ = "setMyName" + + name: Optional[str] = None + """New bot name; 0-64 characters. Pass an empty string to remove the dedicated name for the given language.""" + language_code: Optional[str] = None + """A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose language there is no dedicated name.""" diff --git a/aiogram/methods/set_my_short_description.py b/aiogram/methods/set_my_short_description.py index 19e5b254..0c697d4b 100644 --- a/aiogram/methods/set_my_short_description.py +++ b/aiogram/methods/set_my_short_description.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from .base import TelegramMethod diff --git a/aiogram/methods/set_passport_data_errors.py b/aiogram/methods/set_passport_data_errors.py index ae127d2b..8dbd52b2 100644 --- a/aiogram/methods/set_passport_data_errors.py +++ b/aiogram/methods/set_passport_data_errors.py @@ -1,8 +1,18 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List +from typing import List, Union -from ..types import PassportElementError +from ..types import ( + PassportElementErrorDataField, + PassportElementErrorFile, + PassportElementErrorFiles, + PassportElementErrorFrontSide, + PassportElementErrorReverseSide, + PassportElementErrorSelfie, + PassportElementErrorTranslationFile, + PassportElementErrorTranslationFiles, + PassportElementErrorUnspecified, +) from .base import TelegramMethod @@ -19,5 +29,17 @@ class SetPassportDataErrors(TelegramMethod[bool]): user_id: int """User identifier""" - errors: List[PassportElementError] + errors: List[ + Union[ + PassportElementErrorDataField, + PassportElementErrorFrontSide, + PassportElementErrorReverseSide, + PassportElementErrorSelfie, + PassportElementErrorFile, + PassportElementErrorFiles, + PassportElementErrorTranslationFile, + PassportElementErrorTranslationFiles, + PassportElementErrorUnspecified, + ] + ] """A JSON-serialized array describing the errors""" diff --git a/aiogram/methods/set_sticker_emoji_list.py b/aiogram/methods/set_sticker_emoji_list.py index f23033c7..b88f609e 100644 --- a/aiogram/methods/set_sticker_emoji_list.py +++ b/aiogram/methods/set_sticker_emoji_list.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List +from typing import List from .base import TelegramMethod diff --git a/aiogram/methods/set_sticker_keywords.py b/aiogram/methods/set_sticker_keywords.py index 0ebef118..1179613b 100644 --- a/aiogram/methods/set_sticker_keywords.py +++ b/aiogram/methods/set_sticker_keywords.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional from .base import TelegramMethod diff --git a/aiogram/methods/set_sticker_mask_position.py b/aiogram/methods/set_sticker_mask_position.py index f3147f2d..7e82b061 100644 --- a/aiogram/methods/set_sticker_mask_position.py +++ b/aiogram/methods/set_sticker_mask_position.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import Optional from ..types import MaskPosition from .base import TelegramMethod diff --git a/aiogram/methods/set_sticker_position_in_set.py b/aiogram/methods/set_sticker_position_in_set.py index ed5792ae..395d2e05 100644 --- a/aiogram/methods/set_sticker_position_in_set.py +++ b/aiogram/methods/set_sticker_position_in_set.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from .base import TelegramMethod diff --git a/aiogram/methods/set_sticker_set_thumbnail.py b/aiogram/methods/set_sticker_set_thumbnail.py index 7da1c397..3624bce4 100644 --- a/aiogram/methods/set_sticker_set_thumbnail.py +++ b/aiogram/methods/set_sticker_set_thumbnail.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import InputFile from .base import TelegramMethod diff --git a/aiogram/methods/set_sticker_set_title.py b/aiogram/methods/set_sticker_set_title.py index 978432ff..1136353f 100644 --- a/aiogram/methods/set_sticker_set_title.py +++ b/aiogram/methods/set_sticker_set_title.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from .base import TelegramMethod diff --git a/aiogram/methods/set_webhook.py b/aiogram/methods/set_webhook.py index 6e63a75a..66ec86ff 100644 --- a/aiogram/methods/set_webhook.py +++ b/aiogram/methods/set_webhook.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional from ..types import InputFile from .base import TelegramMethod diff --git a/aiogram/methods/stop_message_live_location.py b/aiogram/methods/stop_message_live_location.py index 8a16f586..9361dfae 100644 --- a/aiogram/methods/stop_message_live_location.py +++ b/aiogram/methods/stop_message_live_location.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import InlineKeyboardMarkup, Message from .base import TelegramMethod diff --git a/aiogram/methods/stop_poll.py b/aiogram/methods/stop_poll.py index 19ef26ac..2e93f087 100644 --- a/aiogram/methods/stop_poll.py +++ b/aiogram/methods/stop_poll.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from ..types import InlineKeyboardMarkup, Poll from .base import TelegramMethod diff --git a/aiogram/methods/unban_chat_member.py b/aiogram/methods/unban_chat_member.py index 768eea22..19ef9ef7 100644 --- a/aiogram/methods/unban_chat_member.py +++ b/aiogram/methods/unban_chat_member.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from .base import TelegramMethod diff --git a/aiogram/methods/unban_chat_sender_chat.py b/aiogram/methods/unban_chat_sender_chat.py index fbd3f1d3..e81278d3 100644 --- a/aiogram/methods/unban_chat_sender_chat.py +++ b/aiogram/methods/unban_chat_sender_chat.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/unhide_general_forum_topic.py b/aiogram/methods/unhide_general_forum_topic.py index 82524758..cebcec25 100644 --- a/aiogram/methods/unhide_general_forum_topic.py +++ b/aiogram/methods/unhide_general_forum_topic.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/unpin_all_chat_messages.py b/aiogram/methods/unpin_all_chat_messages.py index f8566e33..76927e63 100644 --- a/aiogram/methods/unpin_all_chat_messages.py +++ b/aiogram/methods/unpin_all_chat_messages.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/unpin_all_forum_topic_messages.py b/aiogram/methods/unpin_all_forum_topic_messages.py index 6b735e98..09729e2c 100644 --- a/aiogram/methods/unpin_all_forum_topic_messages.py +++ b/aiogram/methods/unpin_all_forum_topic_messages.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import Union from .base import TelegramMethod diff --git a/aiogram/methods/unpin_chat_message.py b/aiogram/methods/unpin_chat_message.py index 0d5d2b0a..3fb70154 100644 --- a/aiogram/methods/unpin_chat_message.py +++ b/aiogram/methods/unpin_chat_message.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Union +from typing import Optional, Union from .base import TelegramMethod diff --git a/aiogram/methods/upload_sticker_file.py b/aiogram/methods/upload_sticker_file.py index 2194e35f..fd1a229e 100644 --- a/aiogram/methods/upload_sticker_file.py +++ b/aiogram/methods/upload_sticker_file.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from ..types import File, InputFile from .base import TelegramMethod diff --git a/aiogram/types/__init__.py b/aiogram/types/__init__.py index 85fd9338..a669cbe8 100644 --- a/aiogram/types/__init__.py +++ b/aiogram/types/__init__.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import List, Literal, Optional, Union from .animation import Animation from .audio import Audio @@ -15,6 +15,7 @@ from .bot_command_scope_chat_administrators import BotCommandScopeChatAdministra from .bot_command_scope_chat_member import BotCommandScopeChatMember from .bot_command_scope_default import BotCommandScopeDefault from .bot_description import BotDescription +from .bot_name import BotName from .bot_short_description import BotShortDescription from .callback_game import CallbackGame from .callback_query import CallbackQuery @@ -77,6 +78,7 @@ from .inline_query_result_photo import InlineQueryResultPhoto from .inline_query_result_venue import InlineQueryResultVenue from .inline_query_result_video import InlineQueryResultVideo from .inline_query_result_voice import InlineQueryResultVoice +from .inline_query_results_button import InlineQueryResultsButton from .input_contact_message_content import InputContactMessageContent from .input_file import BufferedInputFile, FSInputFile, InputFile, URLInputFile from .input_invoice_message_content import InputInvoiceMessageContent @@ -139,6 +141,7 @@ from .shipping_query import ShippingQuery from .sticker import Sticker from .sticker_set import StickerSet from .successful_payment import SuccessfulPayment +from .switch_inline_query_chosen_chat import SwitchInlineQueryChosenChat from .update import Update from .user import User from .user_profile_photos import UserProfilePhotos @@ -169,6 +172,7 @@ __all__ = ( "BotCommandScopeChatMember", "BotCommandScopeDefault", "BotDescription", + "BotName", "BotShortDescription", "BufferedInputFile", "CallbackGame", @@ -234,6 +238,7 @@ __all__ = ( "InlineQueryResultVenue", "InlineQueryResultVideo", "InlineQueryResultVoice", + "InlineQueryResultsButton", "InputContactMessageContent", "InputFile", "InputInvoiceMessageContent", @@ -294,6 +299,7 @@ __all__ = ( "Sticker", "StickerSet", "SuccessfulPayment", + "SwitchInlineQueryChosenChat", "TelegramObject", "UNSET_PARSE_MODE", "URLInputFile", @@ -318,11 +324,16 @@ __all__ = ( # Load typing forward refs for every TelegramObject for _entity_name in __all__: _entity = globals()[_entity_name] - if not hasattr(_entity, "update_forward_refs"): + if not hasattr(_entity, "model_rebuild"): continue - _entity.update_forward_refs( - **{k: v for k, v in globals().items() if k in __all__}, - **{"Optional": Optional}, + _entity.model_rebuild( + _types_namespace={ + "List": List, + "Optional": Optional, + "Union": Union, + "Literal": Literal, + **{k: v for k, v in globals().items() if k in __all__}, + } ) del _entity diff --git a/aiogram/types/base.py b/aiogram/types/base.py index 707e328c..641b16df 100644 --- a/aiogram/types/base.py +++ b/aiogram/types/base.py @@ -1,30 +1,32 @@ -import datetime from typing import Any from unittest.mock import sentinel -from pydantic import BaseModel, Extra +from pydantic import BaseModel, ConfigDict -from aiogram.utils.mixins import ContextInstanceMixin +from aiogram.client.context_controller import BotContextController -class TelegramObject(ContextInstanceMixin["TelegramObject"], BaseModel): - class Config: - use_enum_values = True - orm_mode = True - extra = Extra.allow - validate_assignment = True - allow_mutation = False - allow_population_by_field_name = True - json_encoders = {datetime.datetime: lambda dt: int(dt.timestamp())} +class TelegramObject(BotContextController, BaseModel): + model_config = ConfigDict( + use_enum_values=True, + extra="allow", + validate_assignment=True, + frozen=True, + populate_by_name=True, + arbitrary_types_allowed=True, + defer_build=True, + ) class MutableTelegramObject(TelegramObject): - class Config: - allow_mutation = True + model_config = ConfigDict( + frozen=False, + ) # special sentinel object which used in situation when None might be a useful value +UNSET: Any = sentinel.UNSET UNSET_PARSE_MODE: Any = sentinel.UNSET_PARSE_MODE -UNSET_DISABLE_WEB_PAGE_PREVIEW = sentinel.UNSET_DISABLE_WEB_PAGE_PREVIEW -UNSET_PROTECT_CONTENT = sentinel.UNSET_PROTECT_CONTENT -UNSET_TYPE = type(sentinel.DEFAULT) +UNSET_DISABLE_WEB_PAGE_PREVIEW: Any = sentinel.UNSET_DISABLE_WEB_PAGE_PREVIEW +UNSET_PROTECT_CONTENT: Any = sentinel.UNSET_PROTECT_CONTENT +UNSET_TYPE: Any = type(UNSET) diff --git a/aiogram/types/bot_command_scope_all_chat_administrators.py b/aiogram/types/bot_command_scope_all_chat_administrators.py index e9f6a969..ed3dd181 100644 --- a/aiogram/types/bot_command_scope_all_chat_administrators.py +++ b/aiogram/types/bot_command_scope_all_chat_administrators.py @@ -1,6 +1,6 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal from ..enums import BotCommandScopeType from .bot_command_scope import BotCommandScope @@ -13,5 +13,7 @@ class BotCommandScopeAllChatAdministrators(BotCommandScope): Source: https://core.telegram.org/bots/api#botcommandscopeallchatadministrators """ - type: str = Field(BotCommandScopeType.ALL_CHAT_ADMINISTRATORS, const=True) + type: Literal[ + BotCommandScopeType.ALL_CHAT_ADMINISTRATORS + ] = BotCommandScopeType.ALL_CHAT_ADMINISTRATORS """Scope type, must be *all_chat_administrators*""" diff --git a/aiogram/types/bot_command_scope_all_group_chats.py b/aiogram/types/bot_command_scope_all_group_chats.py index f9675ad6..3393266a 100644 --- a/aiogram/types/bot_command_scope_all_group_chats.py +++ b/aiogram/types/bot_command_scope_all_group_chats.py @@ -1,6 +1,6 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal from ..enums import BotCommandScopeType from .bot_command_scope import BotCommandScope @@ -13,5 +13,5 @@ class BotCommandScopeAllGroupChats(BotCommandScope): Source: https://core.telegram.org/bots/api#botcommandscopeallgroupchats """ - type: str = Field(BotCommandScopeType.ALL_GROUP_CHATS, const=True) + type: Literal[BotCommandScopeType.ALL_GROUP_CHATS] = BotCommandScopeType.ALL_GROUP_CHATS """Scope type, must be *all_group_chats*""" diff --git a/aiogram/types/bot_command_scope_all_private_chats.py b/aiogram/types/bot_command_scope_all_private_chats.py index f13e2866..c53303d1 100644 --- a/aiogram/types/bot_command_scope_all_private_chats.py +++ b/aiogram/types/bot_command_scope_all_private_chats.py @@ -1,6 +1,6 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal from ..enums import BotCommandScopeType from .bot_command_scope import BotCommandScope @@ -13,5 +13,5 @@ class BotCommandScopeAllPrivateChats(BotCommandScope): Source: https://core.telegram.org/bots/api#botcommandscopeallprivatechats """ - type: str = Field(BotCommandScopeType.ALL_PRIVATE_CHATS, const=True) + type: Literal[BotCommandScopeType.ALL_PRIVATE_CHATS] = BotCommandScopeType.ALL_PRIVATE_CHATS """Scope type, must be *all_private_chats*""" diff --git a/aiogram/types/bot_command_scope_chat.py b/aiogram/types/bot_command_scope_chat.py index d96bc6f4..f0ef7b58 100644 --- a/aiogram/types/bot_command_scope_chat.py +++ b/aiogram/types/bot_command_scope_chat.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import Union - -from pydantic import Field +from typing import Literal, Union from ..enums import BotCommandScopeType from .bot_command_scope import BotCommandScope @@ -15,7 +13,7 @@ class BotCommandScopeChat(BotCommandScope): Source: https://core.telegram.org/bots/api#botcommandscopechat """ - type: str = Field(BotCommandScopeType.CHAT, const=True) + type: Literal[BotCommandScopeType.CHAT] = BotCommandScopeType.CHAT """Scope type, must be *chat*""" chat_id: Union[int, str] """Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)""" diff --git a/aiogram/types/bot_command_scope_chat_administrators.py b/aiogram/types/bot_command_scope_chat_administrators.py index 824dc5a1..65513db2 100644 --- a/aiogram/types/bot_command_scope_chat_administrators.py +++ b/aiogram/types/bot_command_scope_chat_administrators.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import Union - -from pydantic import Field +from typing import Literal, Union from ..enums import BotCommandScopeType from .bot_command_scope import BotCommandScope @@ -15,7 +13,9 @@ class BotCommandScopeChatAdministrators(BotCommandScope): Source: https://core.telegram.org/bots/api#botcommandscopechatadministrators """ - type: str = Field(BotCommandScopeType.CHAT_ADMINISTRATORS, const=True) + type: Literal[ + BotCommandScopeType.CHAT_ADMINISTRATORS + ] = BotCommandScopeType.CHAT_ADMINISTRATORS """Scope type, must be *chat_administrators*""" chat_id: Union[int, str] """Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)""" diff --git a/aiogram/types/bot_command_scope_chat_member.py b/aiogram/types/bot_command_scope_chat_member.py index e9fb0dda..efb97870 100644 --- a/aiogram/types/bot_command_scope_chat_member.py +++ b/aiogram/types/bot_command_scope_chat_member.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import Union - -from pydantic import Field +from typing import Literal, Union from ..enums import BotCommandScopeType from .bot_command_scope import BotCommandScope @@ -15,7 +13,7 @@ class BotCommandScopeChatMember(BotCommandScope): Source: https://core.telegram.org/bots/api#botcommandscopechatmember """ - type: str = Field(BotCommandScopeType.CHAT_MEMBER, const=True) + type: Literal[BotCommandScopeType.CHAT_MEMBER] = BotCommandScopeType.CHAT_MEMBER """Scope type, must be *chat_member*""" chat_id: Union[int, str] """Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)""" diff --git a/aiogram/types/bot_command_scope_default.py b/aiogram/types/bot_command_scope_default.py index 79825631..449665c9 100644 --- a/aiogram/types/bot_command_scope_default.py +++ b/aiogram/types/bot_command_scope_default.py @@ -1,6 +1,6 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal from ..enums import BotCommandScopeType from .bot_command_scope import BotCommandScope @@ -13,5 +13,5 @@ class BotCommandScopeDefault(BotCommandScope): Source: https://core.telegram.org/bots/api#botcommandscopedefault """ - type: str = Field(BotCommandScopeType.DEFAULT, const=True) + type: Literal[BotCommandScopeType.DEFAULT] = BotCommandScopeType.DEFAULT """Scope type, must be *default*""" diff --git a/aiogram/types/bot_name.py b/aiogram/types/bot_name.py new file mode 100644 index 00000000..103f1fde --- /dev/null +++ b/aiogram/types/bot_name.py @@ -0,0 +1,12 @@ +from .base import TelegramObject + + +class BotName(TelegramObject): + """ + This object represents the bot's name. + + Source: https://core.telegram.org/bots/api#botname + """ + + name: str + """The bot's name""" diff --git a/aiogram/types/callback_query.py b/aiogram/types/callback_query.py index 5812bb13..59f9ea66 100644 --- a/aiogram/types/callback_query.py +++ b/aiogram/types/callback_query.py @@ -74,4 +74,4 @@ class CallbackQuery(TelegramObject): url=url, cache_time=cache_time, **kwargs, - ) + ).as_(self._bot) diff --git a/aiogram/types/chat.py b/aiogram/types/chat.py index 4bb6d688..d5d0dfcc 100644 --- a/aiogram/types/chat.py +++ b/aiogram/types/chat.py @@ -164,7 +164,7 @@ class Chat(TelegramObject): chat_id=self.id, sender_chat_id=sender_chat_id, **kwargs, - ) + ).as_(self._bot) def unban_sender_chat( self, @@ -193,7 +193,7 @@ class Chat(TelegramObject): chat_id=self.id, sender_chat_id=sender_chat_id, **kwargs, - ) + ).as_(self._bot) def get_administrators( self, @@ -219,7 +219,7 @@ class Chat(TelegramObject): return GetChatAdministrators( chat_id=self.id, **kwargs, - ) + ).as_(self._bot) def delete_message( self, @@ -266,7 +266,7 @@ class Chat(TelegramObject): chat_id=self.id, message_id=message_id, **kwargs, - ) + ).as_(self._bot) def revoke_invite_link( self, @@ -295,7 +295,7 @@ class Chat(TelegramObject): chat_id=self.id, invite_link=invite_link, **kwargs, - ) + ).as_(self._bot) def edit_invite_link( self, @@ -336,7 +336,7 @@ class Chat(TelegramObject): member_limit=member_limit, creates_join_request=creates_join_request, **kwargs, - ) + ).as_(self._bot) def create_invite_link( self, @@ -374,7 +374,7 @@ class Chat(TelegramObject): member_limit=member_limit, creates_join_request=creates_join_request, **kwargs, - ) + ).as_(self._bot) def export_invite_link( self, @@ -402,7 +402,7 @@ class Chat(TelegramObject): return ExportChatInviteLink( chat_id=self.id, **kwargs, - ) + ).as_(self._bot) def do( self, @@ -438,7 +438,7 @@ class Chat(TelegramObject): action=action, message_thread_id=message_thread_id, **kwargs, - ) + ).as_(self._bot) def delete_sticker_set( self, @@ -464,7 +464,7 @@ class Chat(TelegramObject): return DeleteChatStickerSet( chat_id=self.id, **kwargs, - ) + ).as_(self._bot) def set_sticker_set( self, @@ -493,7 +493,7 @@ class Chat(TelegramObject): chat_id=self.id, sticker_set_name=sticker_set_name, **kwargs, - ) + ).as_(self._bot) def get_member( self, @@ -522,7 +522,7 @@ class Chat(TelegramObject): chat_id=self.id, user_id=user_id, **kwargs, - ) + ).as_(self._bot) def get_member_count( self, @@ -548,7 +548,7 @@ class Chat(TelegramObject): return GetChatMemberCount( chat_id=self.id, **kwargs, - ) + ).as_(self._bot) def leave( self, @@ -574,7 +574,7 @@ class Chat(TelegramObject): return LeaveChat( chat_id=self.id, **kwargs, - ) + ).as_(self._bot) def unpin_all_messages( self, @@ -600,7 +600,7 @@ class Chat(TelegramObject): return UnpinAllChatMessages( chat_id=self.id, **kwargs, - ) + ).as_(self._bot) def unpin_message( self, @@ -629,7 +629,7 @@ class Chat(TelegramObject): chat_id=self.id, message_id=message_id, **kwargs, - ) + ).as_(self._bot) def pin_message( self, @@ -661,7 +661,7 @@ class Chat(TelegramObject): message_id=message_id, disable_notification=disable_notification, **kwargs, - ) + ).as_(self._bot) def set_administrator_custom_title( self, @@ -693,7 +693,7 @@ class Chat(TelegramObject): user_id=user_id, custom_title=custom_title, **kwargs, - ) + ).as_(self._bot) def set_permissions( self, @@ -725,7 +725,7 @@ class Chat(TelegramObject): permissions=permissions, use_independent_chat_permissions=use_independent_chat_permissions, **kwargs, - ) + ).as_(self._bot) def promote( self, @@ -790,7 +790,7 @@ class Chat(TelegramObject): can_pin_messages=can_pin_messages, can_manage_topics=can_manage_topics, **kwargs, - ) + ).as_(self._bot) def restrict( self, @@ -828,7 +828,7 @@ class Chat(TelegramObject): use_independent_chat_permissions=use_independent_chat_permissions, until_date=until_date, **kwargs, - ) + ).as_(self._bot) def unban( self, @@ -860,7 +860,7 @@ class Chat(TelegramObject): user_id=user_id, only_if_banned=only_if_banned, **kwargs, - ) + ).as_(self._bot) def ban( self, @@ -895,7 +895,7 @@ class Chat(TelegramObject): until_date=until_date, revoke_messages=revoke_messages, **kwargs, - ) + ).as_(self._bot) def set_description( self, @@ -924,7 +924,7 @@ class Chat(TelegramObject): chat_id=self.id, description=description, **kwargs, - ) + ).as_(self._bot) def set_title( self, @@ -953,7 +953,7 @@ class Chat(TelegramObject): chat_id=self.id, title=title, **kwargs, - ) + ).as_(self._bot) def delete_photo( self, @@ -979,7 +979,7 @@ class Chat(TelegramObject): return DeleteChatPhoto( chat_id=self.id, **kwargs, - ) + ).as_(self._bot) def set_photo( self, @@ -1008,4 +1008,4 @@ class Chat(TelegramObject): chat_id=self.id, photo=photo, **kwargs, - ) + ).as_(self._bot) diff --git a/aiogram/types/chat_join_request.py b/aiogram/types/chat_join_request.py index ca4f8bb7..94ef61ba 100644 --- a/aiogram/types/chat_join_request.py +++ b/aiogram/types/chat_join_request.py @@ -62,7 +62,7 @@ class ChatJoinRequest(TelegramObject): chat_id=self.chat.id, user_id=self.from_user.id, **kwargs, - ) + ).as_(self._bot) def decline( self, @@ -90,4 +90,4 @@ class ChatJoinRequest(TelegramObject): chat_id=self.chat.id, user_id=self.from_user.id, **kwargs, - ) + ).as_(self._bot) diff --git a/aiogram/types/chat_member.py b/aiogram/types/chat_member.py index 6bf5b79e..018bebda 100644 --- a/aiogram/types/chat_member.py +++ b/aiogram/types/chat_member.py @@ -1,13 +1,7 @@ from __future__ import annotations -import datetime -from typing import TYPE_CHECKING, Optional - from .base import TelegramObject -if TYPE_CHECKING: - from .user import User - class ChatMember(TelegramObject): """ @@ -22,60 +16,3 @@ class ChatMember(TelegramObject): Source: https://core.telegram.org/bots/api#chatmember """ - - status: str - """The member's status in the chat""" - user: Optional[User] = None - """*Optional*. Information about the user""" - is_anonymous: Optional[bool] = None - """*Optional*. :code:`True`, if the user's presence in the chat is hidden""" - custom_title: Optional[str] = None - """*Optional*. Custom title for this user""" - can_be_edited: Optional[bool] = None - """*Optional*. :code:`True`, if the bot is allowed to edit administrator privileges of that user""" - can_manage_chat: Optional[bool] = None - """*Optional*. :code:`True`, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege""" - can_delete_messages: Optional[bool] = None - """*Optional*. :code:`True`, if the administrator can delete messages of other users""" - can_manage_video_chats: Optional[bool] = None - """*Optional*. :code:`True`, if the administrator can manage video chats""" - can_restrict_members: Optional[bool] = None - """*Optional*. :code:`True`, if the administrator can restrict, ban or unban chat members""" - can_promote_members: Optional[bool] = None - """*Optional*. :code:`True`, if the administrator can add new administrators with a subset of their own privileges or demote administrators that they have promoted, directly or indirectly (promoted by administrators that were appointed by the user)""" - can_change_info: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to change the chat title, photo and other settings""" - can_invite_users: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to invite new users to the chat""" - can_post_messages: Optional[bool] = None - """*Optional*. :code:`True`, if the administrator can post in the channel; channels only""" - can_edit_messages: Optional[bool] = None - """*Optional*. :code:`True`, if the administrator can edit messages of other users and can pin messages; channels only""" - can_pin_messages: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to pin messages; groups and supergroups only""" - can_manage_topics: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to create, rename, close, and reopen forum topics; supergroups only""" - is_member: Optional[bool] = None - """*Optional*. :code:`True`, if the user is a member of the chat at the moment of the request""" - can_send_messages: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to send text messages, contacts, invoices, locations and venues""" - can_send_audios: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to send audios""" - can_send_documents: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to send documents""" - can_send_photos: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to send photos""" - can_send_videos: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to send videos""" - can_send_video_notes: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to send video notes""" - can_send_voice_notes: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to send voice notes""" - can_send_polls: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to send polls""" - can_send_other_messages: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to send animations, games, stickers and use inline bots""" - can_add_web_page_previews: Optional[bool] = None - """*Optional*. :code:`True`, if the user is allowed to add web page previews to their messages""" - until_date: Optional[datetime.datetime] = None - """*Optional*. Date when restrictions will be lifted for this user; unix time. If 0, then the user is restricted forever""" diff --git a/aiogram/types/chat_member_administrator.py b/aiogram/types/chat_member_administrator.py index 94fc76c3..ae98e79d 100644 --- a/aiogram/types/chat_member_administrator.py +++ b/aiogram/types/chat_member_administrator.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, Literal, Optional from ..enums import ChatMemberStatus from .chat_member import ChatMember @@ -18,7 +16,7 @@ class ChatMemberAdministrator(ChatMember): Source: https://core.telegram.org/bots/api#chatmemberadministrator """ - status: str = Field(ChatMemberStatus.ADMINISTRATOR, const=True) + status: Literal[ChatMemberStatus.ADMINISTRATOR] = ChatMemberStatus.ADMINISTRATOR """The member's status in the chat, always 'administrator'""" user: User """Information about the user""" diff --git a/aiogram/types/chat_member_banned.py b/aiogram/types/chat_member_banned.py index 85c07f51..33e85f45 100644 --- a/aiogram/types/chat_member_banned.py +++ b/aiogram/types/chat_member_banned.py @@ -1,9 +1,7 @@ from __future__ import annotations import datetime -from typing import TYPE_CHECKING - -from pydantic import Field +from typing import TYPE_CHECKING, Literal from ..enums import ChatMemberStatus from .chat_member import ChatMember @@ -19,7 +17,7 @@ class ChatMemberBanned(ChatMember): Source: https://core.telegram.org/bots/api#chatmemberbanned """ - status: str = Field(ChatMemberStatus.KICKED, const=True) + status: Literal[ChatMemberStatus.KICKED] = ChatMemberStatus.KICKED """The member's status in the chat, always 'kicked'""" user: User """Information about the user""" diff --git a/aiogram/types/chat_member_left.py b/aiogram/types/chat_member_left.py index 6d7968c1..af501917 100644 --- a/aiogram/types/chat_member_left.py +++ b/aiogram/types/chat_member_left.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING - -from pydantic import Field +from typing import TYPE_CHECKING, Literal from ..enums import ChatMemberStatus from .chat_member import ChatMember @@ -18,7 +16,7 @@ class ChatMemberLeft(ChatMember): Source: https://core.telegram.org/bots/api#chatmemberleft """ - status: str = Field(ChatMemberStatus.LEFT, const=True) + status: Literal[ChatMemberStatus.LEFT] = ChatMemberStatus.LEFT """The member's status in the chat, always 'left'""" user: User """Information about the user""" diff --git a/aiogram/types/chat_member_member.py b/aiogram/types/chat_member_member.py index 303a7d9d..e2c7418e 100644 --- a/aiogram/types/chat_member_member.py +++ b/aiogram/types/chat_member_member.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING - -from pydantic import Field +from typing import TYPE_CHECKING, Literal from ..enums import ChatMemberStatus from .chat_member import ChatMember @@ -18,7 +16,7 @@ class ChatMemberMember(ChatMember): Source: https://core.telegram.org/bots/api#chatmembermember """ - status: str = Field(ChatMemberStatus.MEMBER, const=True) + status: Literal[ChatMemberStatus.MEMBER] = ChatMemberStatus.MEMBER """The member's status in the chat, always 'member'""" user: User """Information about the user""" diff --git a/aiogram/types/chat_member_owner.py b/aiogram/types/chat_member_owner.py index e7c64fc1..66450550 100644 --- a/aiogram/types/chat_member_owner.py +++ b/aiogram/types/chat_member_owner.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, Literal, Optional from ..enums import ChatMemberStatus from .chat_member import ChatMember @@ -18,7 +16,7 @@ class ChatMemberOwner(ChatMember): Source: https://core.telegram.org/bots/api#chatmemberowner """ - status: str = Field(ChatMemberStatus.CREATOR, const=True) + status: Literal[ChatMemberStatus.CREATOR] = ChatMemberStatus.CREATOR """The member's status in the chat, always 'creator'""" user: User """Information about the user""" diff --git a/aiogram/types/chat_member_restricted.py b/aiogram/types/chat_member_restricted.py index b6f4f556..17db73fb 100644 --- a/aiogram/types/chat_member_restricted.py +++ b/aiogram/types/chat_member_restricted.py @@ -1,9 +1,7 @@ from __future__ import annotations import datetime -from typing import TYPE_CHECKING - -from pydantic import Field +from typing import TYPE_CHECKING, Literal from ..enums import ChatMemberStatus from .chat_member import ChatMember @@ -19,7 +17,7 @@ class ChatMemberRestricted(ChatMember): Source: https://core.telegram.org/bots/api#chatmemberrestricted """ - status: str = Field(ChatMemberStatus.RESTRICTED, const=True) + status: Literal[ChatMemberStatus.RESTRICTED] = ChatMemberStatus.RESTRICTED """The member's status in the chat, always 'restricted'""" user: User """Information about the user""" diff --git a/aiogram/types/chat_member_updated.py b/aiogram/types/chat_member_updated.py index e4e4a340..5931da6f 100644 --- a/aiogram/types/chat_member_updated.py +++ b/aiogram/types/chat_member_updated.py @@ -52,3 +52,5 @@ class ChatMemberUpdated(TelegramObject): """New information about the chat member""" invite_link: Optional[ChatInviteLink] = None """*Optional*. Chat invite link, which was used by the user to join the chat; for joining by invite link events only.""" + via_chat_folder_invite_link: Optional[bool] = None + """*Optional*. True, if the user joined the chat via a chat folder invite link""" diff --git a/aiogram/types/error_event.py b/aiogram/types/error_event.py index 1667d9e9..212bee56 100644 --- a/aiogram/types/error_event.py +++ b/aiogram/types/error_event.py @@ -2,18 +2,13 @@ from __future__ import annotations from typing import TYPE_CHECKING -from aiogram.types.base import MutableTelegramObject +from aiogram.types.base import TelegramObject if TYPE_CHECKING: from .update import Update -class _ErrorEvent(MutableTelegramObject): - class Config: - arbitrary_types_allowed = True - - -class ErrorEvent(_ErrorEvent): +class ErrorEvent(TelegramObject): """ Internal event, should be used to receive errors while processing Updates from Telegram diff --git a/aiogram/types/force_reply.py b/aiogram/types/force_reply.py index c27af31e..cd13b658 100644 --- a/aiogram/types/force_reply.py +++ b/aiogram/types/force_reply.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import Optional - -from pydantic import Field +from typing import Literal, Optional from .base import MutableTelegramObject @@ -21,7 +19,7 @@ class ForceReply(MutableTelegramObject): Source: https://core.telegram.org/bots/api#forcereply """ - force_reply: bool = Field(True, const=True) + force_reply: Literal[True] = True """Shows reply interface to the user, as if they manually selected the bot's message and tapped 'Reply'""" input_field_placeholder: Optional[str] = None """*Optional*. The placeholder to be shown in the input field when the reply is active; 1-64 characters""" diff --git a/aiogram/types/inline_keyboard_button.py b/aiogram/types/inline_keyboard_button.py index c4208b70..977fae8d 100644 --- a/aiogram/types/inline_keyboard_button.py +++ b/aiogram/types/inline_keyboard_button.py @@ -7,6 +7,7 @@ from .base import MutableTelegramObject if TYPE_CHECKING: from .callback_game import CallbackGame from .login_url import LoginUrl + from .switch_inline_query_chosen_chat import SwitchInlineQueryChosenChat from .web_app_info import WebAppInfo @@ -31,6 +32,8 @@ class InlineKeyboardButton(MutableTelegramObject): """*Optional*. 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. May be empty, in which case just the bot's username will be inserted.""" switch_inline_query_current_chat: Optional[str] = None """*Optional*. If set, pressing the button will insert the bot's username and the specified inline query in the current chat's input field. May be empty, in which case only the bot's username will be inserted.""" + switch_inline_query_chosen_chat: Optional[SwitchInlineQueryChosenChat] = None + """*Optional*. If set, pressing the button will prompt the user to select one of their chats of the specified type, open that chat and insert the bot's username and the specified inline query in the input field""" callback_game: Optional[CallbackGame] = None """*Optional*. Description of the game that will be launched when the user presses the button.""" pay: Optional[bool] = None diff --git a/aiogram/types/inline_query.py b/aiogram/types/inline_query.py index 1feb6f7f..e9fb644e 100644 --- a/aiogram/types/inline_query.py +++ b/aiogram/types/inline_query.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, List, Optional +from typing import TYPE_CHECKING, Any, List, Optional, Union from pydantic import Field @@ -8,7 +8,27 @@ from .base import TelegramObject if TYPE_CHECKING: from ..methods import AnswerInlineQuery - from .inline_query_result import InlineQueryResult + from .inline_query_result_article import InlineQueryResultArticle + from .inline_query_result_audio import InlineQueryResultAudio + from .inline_query_result_cached_audio import InlineQueryResultCachedAudio + from .inline_query_result_cached_document import InlineQueryResultCachedDocument + from .inline_query_result_cached_gif import InlineQueryResultCachedGif + from .inline_query_result_cached_mpeg4_gif import InlineQueryResultCachedMpeg4Gif + from .inline_query_result_cached_photo import InlineQueryResultCachedPhoto + from .inline_query_result_cached_sticker import InlineQueryResultCachedSticker + from .inline_query_result_cached_video import InlineQueryResultCachedVideo + from .inline_query_result_cached_voice import InlineQueryResultCachedVoice + from .inline_query_result_contact import InlineQueryResultContact + from .inline_query_result_document import InlineQueryResultDocument + from .inline_query_result_game import InlineQueryResultGame + from .inline_query_result_gif import InlineQueryResultGif + from .inline_query_result_location import InlineQueryResultLocation + from .inline_query_result_mpeg4_gif import InlineQueryResultMpeg4Gif + from .inline_query_result_photo import InlineQueryResultPhoto + from .inline_query_result_venue import InlineQueryResultVenue + from .inline_query_result_video import InlineQueryResultVideo + from .inline_query_result_voice import InlineQueryResultVoice + from .inline_query_results_button import InlineQueryResultsButton from .location import Location from .user import User @@ -35,12 +55,36 @@ class InlineQuery(TelegramObject): def answer( self, - results: List[InlineQueryResult], + results: List[ + Union[ + InlineQueryResultCachedAudio, + InlineQueryResultCachedDocument, + InlineQueryResultCachedGif, + InlineQueryResultCachedMpeg4Gif, + InlineQueryResultCachedPhoto, + InlineQueryResultCachedSticker, + InlineQueryResultCachedVideo, + InlineQueryResultCachedVoice, + InlineQueryResultArticle, + InlineQueryResultAudio, + InlineQueryResultContact, + InlineQueryResultGame, + InlineQueryResultDocument, + InlineQueryResultGif, + InlineQueryResultLocation, + InlineQueryResultMpeg4Gif, + InlineQueryResultPhoto, + InlineQueryResultVenue, + InlineQueryResultVideo, + InlineQueryResultVoice, + ] + ], cache_time: Optional[int] = None, is_personal: Optional[bool] = None, next_offset: Optional[str] = None, - switch_pm_text: Optional[str] = None, + button: Optional[InlineQueryResultsButton] = None, switch_pm_parameter: Optional[str] = None, + switch_pm_text: Optional[str] = None, **kwargs: Any, ) -> AnswerInlineQuery: """ @@ -57,10 +101,11 @@ class InlineQuery(TelegramObject): :param results: A JSON-serialized array of results for the inline query :param cache_time: The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300. - :param is_personal: Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query + :param is_personal: Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any 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. - :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 button: A JSON-serialized object describing a button to be shown above inline query results :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 :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed. + :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* :return: instance of method :class:`aiogram.methods.answer_inline_query.AnswerInlineQuery` """ # DO NOT EDIT MANUALLY!!! @@ -74,7 +119,8 @@ class InlineQuery(TelegramObject): cache_time=cache_time, is_personal=is_personal, next_offset=next_offset, - switch_pm_text=switch_pm_text, + button=button, switch_pm_parameter=switch_pm_parameter, + switch_pm_text=switch_pm_text, **kwargs, - ) + ).as_(self._bot) diff --git a/aiogram/types/inline_query_result_article.py b/aiogram/types/inline_query_result_article.py index dd65b595..42c11782 100644 --- a/aiogram/types/inline_query_result_article.py +++ b/aiogram/types/inline_query_result_article.py @@ -1,15 +1,17 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, Literal, Optional, Union from ..enums import InlineQueryResultType from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent class InlineQueryResultArticle(InlineQueryResult): @@ -19,13 +21,19 @@ class InlineQueryResultArticle(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultarticle """ - type: str = Field(InlineQueryResultType.ARTICLE, const=True) + type: Literal[InlineQueryResultType.ARTICLE] = InlineQueryResultType.ARTICLE """Type of the result, must be *article*""" id: str """Unique identifier for this result, 1-64 Bytes""" title: str """Title of the result""" - input_message_content: InputMessageContent + input_message_content: Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] """Content of the message to be sent""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" diff --git a/aiogram/types/inline_query_result_audio.py b/aiogram/types/inline_query_result_audio.py index 3b830fc8..c57b0b72 100644 --- a/aiogram/types/inline_query_result_audio.py +++ b/aiogram/types/inline_query_result_audio.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -22,7 +24,7 @@ class InlineQueryResultAudio(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultaudio """ - type: str = Field(InlineQueryResultType.AUDIO, const=True) + type: Literal[InlineQueryResultType.AUDIO] = InlineQueryResultType.AUDIO """Type of the result, must be *audio*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -42,5 +44,13 @@ class InlineQueryResultAudio(InlineQueryResult): """*Optional*. Audio duration in seconds""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the audio""" diff --git a/aiogram/types/inline_query_result_cached_audio.py b/aiogram/types/inline_query_result_cached_audio.py index 8358f723..6f0a73f1 100644 --- a/aiogram/types/inline_query_result_cached_audio.py +++ b/aiogram/types/inline_query_result_cached_audio.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -22,7 +24,7 @@ class InlineQueryResultCachedAudio(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultcachedaudio """ - type: str = Field(InlineQueryResultType.AUDIO, const=True) + type: Literal[InlineQueryResultType.AUDIO] = InlineQueryResultType.AUDIO """Type of the result, must be *audio*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -36,5 +38,13 @@ class InlineQueryResultCachedAudio(InlineQueryResult): """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the audio""" diff --git a/aiogram/types/inline_query_result_cached_document.py b/aiogram/types/inline_query_result_cached_document.py index 5513971f..ccb28196 100644 --- a/aiogram/types/inline_query_result_cached_document.py +++ b/aiogram/types/inline_query_result_cached_document.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -22,7 +24,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultcacheddocument """ - type: str = Field(InlineQueryResultType.DOCUMENT, const=True) + type: Literal[InlineQueryResultType.DOCUMENT] = InlineQueryResultType.DOCUMENT """Type of the result, must be *document*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -40,5 +42,13 @@ class InlineQueryResultCachedDocument(InlineQueryResult): """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the file""" diff --git a/aiogram/types/inline_query_result_cached_gif.py b/aiogram/types/inline_query_result_cached_gif.py index 7aa5c535..f8ef40a6 100644 --- a/aiogram/types/inline_query_result_cached_gif.py +++ b/aiogram/types/inline_query_result_cached_gif.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -21,7 +23,7 @@ class InlineQueryResultCachedGif(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultcachedgif """ - type: str = Field(InlineQueryResultType.GIF, const=True) + type: Literal[InlineQueryResultType.GIF] = InlineQueryResultType.GIF """Type of the result, must be *gif*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -37,5 +39,13 @@ class InlineQueryResultCachedGif(InlineQueryResult): """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the GIF animation""" diff --git a/aiogram/types/inline_query_result_cached_mpeg4_gif.py b/aiogram/types/inline_query_result_cached_mpeg4_gif.py index ab7a2a9b..09cc0db8 100644 --- a/aiogram/types/inline_query_result_cached_mpeg4_gif.py +++ b/aiogram/types/inline_query_result_cached_mpeg4_gif.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -21,7 +23,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultcachedmpeg4gif """ - type: str = Field(InlineQueryResultType.MPEG, const=True) + type: Literal[InlineQueryResultType.MPEG4_GIF] = InlineQueryResultType.MPEG4_GIF """Type of the result, must be *mpeg4_gif*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -37,5 +39,13 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult): """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the video animation""" diff --git a/aiogram/types/inline_query_result_cached_photo.py b/aiogram/types/inline_query_result_cached_photo.py index fc892826..b72ac656 100644 --- a/aiogram/types/inline_query_result_cached_photo.py +++ b/aiogram/types/inline_query_result_cached_photo.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -21,7 +23,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultcachedphoto """ - type: str = Field(InlineQueryResultType.PHOTO, const=True) + type: Literal[InlineQueryResultType.PHOTO] = InlineQueryResultType.PHOTO """Type of the result, must be *photo*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -39,5 +41,13 @@ class InlineQueryResultCachedPhoto(InlineQueryResult): """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the photo""" diff --git a/aiogram/types/inline_query_result_cached_sticker.py b/aiogram/types/inline_query_result_cached_sticker.py index 3d75c29c..beaab093 100644 --- a/aiogram/types/inline_query_result_cached_sticker.py +++ b/aiogram/types/inline_query_result_cached_sticker.py @@ -1,15 +1,17 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, Literal, Optional, Union from ..enums import InlineQueryResultType from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent class InlineQueryResultCachedSticker(InlineQueryResult): @@ -20,7 +22,7 @@ class InlineQueryResultCachedSticker(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultcachedsticker """ - type: str = Field(InlineQueryResultType.STICKER, const=True) + type: Literal[InlineQueryResultType.STICKER] = InlineQueryResultType.STICKER """Type of the result, must be *sticker*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -28,5 +30,13 @@ class InlineQueryResultCachedSticker(InlineQueryResult): """A valid file identifier of the sticker""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the sticker""" diff --git a/aiogram/types/inline_query_result_cached_video.py b/aiogram/types/inline_query_result_cached_video.py index acda3962..f522bc24 100644 --- a/aiogram/types/inline_query_result_cached_video.py +++ b/aiogram/types/inline_query_result_cached_video.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -21,7 +23,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultcachedvideo """ - type: str = Field(InlineQueryResultType.VIDEO, const=True) + type: Literal[InlineQueryResultType.VIDEO] = InlineQueryResultType.VIDEO """Type of the result, must be *video*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -39,5 +41,13 @@ class InlineQueryResultCachedVideo(InlineQueryResult): """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the video""" diff --git a/aiogram/types/inline_query_result_cached_voice.py b/aiogram/types/inline_query_result_cached_voice.py index 3f03b2fe..7c2b0a44 100644 --- a/aiogram/types/inline_query_result_cached_voice.py +++ b/aiogram/types/inline_query_result_cached_voice.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -22,7 +24,7 @@ class InlineQueryResultCachedVoice(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultcachedvoice """ - type: str = Field(InlineQueryResultType.VOICE, const=True) + type: Literal[InlineQueryResultType.VOICE] = InlineQueryResultType.VOICE """Type of the result, must be *voice*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -38,5 +40,13 @@ class InlineQueryResultCachedVoice(InlineQueryResult): """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the voice message""" diff --git a/aiogram/types/inline_query_result_contact.py b/aiogram/types/inline_query_result_contact.py index 0f88bb9f..aa2fc8c5 100644 --- a/aiogram/types/inline_query_result_contact.py +++ b/aiogram/types/inline_query_result_contact.py @@ -1,15 +1,17 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, Literal, Optional, Union from ..enums import InlineQueryResultType from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent class InlineQueryResultContact(InlineQueryResult): @@ -20,7 +22,7 @@ class InlineQueryResultContact(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultcontact """ - type: str = Field(InlineQueryResultType.CONTACT, const=True) + type: Literal[InlineQueryResultType.CONTACT] = InlineQueryResultType.CONTACT """Type of the result, must be *contact*""" id: str """Unique identifier for this result, 1-64 Bytes""" @@ -34,7 +36,15 @@ class InlineQueryResultContact(InlineQueryResult): """*Optional*. Additional data about the contact in the form of a `vCard `_, 0-2048 bytes""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the contact""" thumbnail_url: Optional[str] = None """*Optional*. Url of the thumbnail for the result""" diff --git a/aiogram/types/inline_query_result_document.py b/aiogram/types/inline_query_result_document.py index 7698e4c6..102aaf24 100644 --- a/aiogram/types/inline_query_result_document.py +++ b/aiogram/types/inline_query_result_document.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -22,7 +24,7 @@ class InlineQueryResultDocument(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultdocument """ - type: str = Field(InlineQueryResultType.DOCUMENT, const=True) + type: Literal[InlineQueryResultType.DOCUMENT] = InlineQueryResultType.DOCUMENT """Type of the result, must be *document*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -42,7 +44,15 @@ class InlineQueryResultDocument(InlineQueryResult): """*Optional*. Short description of the result""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. Inline keyboard attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the file""" thumbnail_url: Optional[str] = None """*Optional*. URL of the thumbnail (JPEG only) for the file""" diff --git a/aiogram/types/inline_query_result_game.py b/aiogram/types/inline_query_result_game.py index e4d92a61..b5ae90fc 100644 --- a/aiogram/types/inline_query_result_game.py +++ b/aiogram/types/inline_query_result_game.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, Literal, Optional from ..enums import InlineQueryResultType from .inline_query_result import InlineQueryResult @@ -19,7 +17,7 @@ class InlineQueryResultGame(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultgame """ - type: str = Field(InlineQueryResultType.GAME, const=True) + type: Literal[InlineQueryResultType.GAME] = InlineQueryResultType.GAME """Type of the result, must be *game*""" id: str """Unique identifier for this result, 1-64 bytes""" diff --git a/aiogram/types/inline_query_result_gif.py b/aiogram/types/inline_query_result_gif.py index b38cfa1a..e3b85fe2 100644 --- a/aiogram/types/inline_query_result_gif.py +++ b/aiogram/types/inline_query_result_gif.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -21,7 +23,7 @@ class InlineQueryResultGif(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultgif """ - type: str = Field(InlineQueryResultType.GIF, const=True) + type: Literal[InlineQueryResultType.GIF] = InlineQueryResultType.GIF """Type of the result, must be *gif*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -47,5 +49,13 @@ class InlineQueryResultGif(InlineQueryResult): """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the GIF animation""" diff --git a/aiogram/types/inline_query_result_location.py b/aiogram/types/inline_query_result_location.py index aa1f6d88..4948a67c 100644 --- a/aiogram/types/inline_query_result_location.py +++ b/aiogram/types/inline_query_result_location.py @@ -1,15 +1,17 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, Literal, Optional, Union from ..enums import InlineQueryResultType from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent class InlineQueryResultLocation(InlineQueryResult): @@ -20,7 +22,7 @@ class InlineQueryResultLocation(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultlocation """ - type: str = Field(InlineQueryResultType.LOCATION, const=True) + type: Literal[InlineQueryResultType.LOCATION] = InlineQueryResultType.LOCATION """Type of the result, must be *location*""" id: str """Unique identifier for this result, 1-64 Bytes""" @@ -40,7 +42,15 @@ class InlineQueryResultLocation(InlineQueryResult): """*Optional*. For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters. Must be between 1 and 100000 if specified.""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the location""" thumbnail_url: Optional[str] = None """*Optional*. Url of the thumbnail for the result""" diff --git a/aiogram/types/inline_query_result_mpeg4_gif.py b/aiogram/types/inline_query_result_mpeg4_gif.py index 44a61fee..9d475af3 100644 --- a/aiogram/types/inline_query_result_mpeg4_gif.py +++ b/aiogram/types/inline_query_result_mpeg4_gif.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -21,7 +23,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultmpeg4gif """ - type: str = Field(InlineQueryResultType.MPEG, const=True) + type: Literal[InlineQueryResultType.MPEG4_GIF] = InlineQueryResultType.MPEG4_GIF """Type of the result, must be *mpeg4_gif*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -47,5 +49,13 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the video animation""" diff --git a/aiogram/types/inline_query_result_photo.py b/aiogram/types/inline_query_result_photo.py index 6ed85276..35a9d996 100644 --- a/aiogram/types/inline_query_result_photo.py +++ b/aiogram/types/inline_query_result_photo.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -21,7 +23,7 @@ class InlineQueryResultPhoto(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultphoto """ - type: str = Field(InlineQueryResultType.PHOTO, const=True) + type: Literal[InlineQueryResultType.PHOTO] = InlineQueryResultType.PHOTO """Type of the result, must be *photo*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -45,5 +47,13 @@ class InlineQueryResultPhoto(InlineQueryResult): """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the photo""" diff --git a/aiogram/types/inline_query_result_venue.py b/aiogram/types/inline_query_result_venue.py index 0c92a008..65841255 100644 --- a/aiogram/types/inline_query_result_venue.py +++ b/aiogram/types/inline_query_result_venue.py @@ -1,15 +1,17 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, Literal, Optional, Union from ..enums import InlineQueryResultType from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent class InlineQueryResultVenue(InlineQueryResult): @@ -20,7 +22,7 @@ class InlineQueryResultVenue(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultvenue """ - type: str = Field(InlineQueryResultType.VENUE, const=True) + type: Literal[InlineQueryResultType.VENUE] = InlineQueryResultType.VENUE """Type of the result, must be *venue*""" id: str """Unique identifier for this result, 1-64 Bytes""" @@ -42,7 +44,15 @@ class InlineQueryResultVenue(InlineQueryResult): """*Optional*. Google Places type of the venue. (See `supported types `_.)""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the venue""" thumbnail_url: Optional[str] = None """*Optional*. Url of the thumbnail for the result""" diff --git a/aiogram/types/inline_query_result_video.py b/aiogram/types/inline_query_result_video.py index ba14d066..0968dda1 100644 --- a/aiogram/types/inline_query_result_video.py +++ b/aiogram/types/inline_query_result_video.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -23,7 +25,7 @@ class InlineQueryResultVideo(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultvideo """ - type: str = Field(InlineQueryResultType.VIDEO, const=True) + type: Literal[InlineQueryResultType.VIDEO] = InlineQueryResultType.VIDEO """Type of the result, must be *video*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -51,5 +53,13 @@ class InlineQueryResultVideo(InlineQueryResult): """*Optional*. Short description of the result""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the video. This field is **required** if InlineQueryResultVideo is used to send an HTML-page as a result (e.g., a YouTube video).""" diff --git a/aiogram/types/inline_query_result_voice.py b/aiogram/types/inline_query_result_voice.py index 7de1f6cf..995950ef 100644 --- a/aiogram/types/inline_query_result_voice.py +++ b/aiogram/types/inline_query_result_voice.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InlineQueryResultType from .base import UNSET_PARSE_MODE @@ -10,7 +8,11 @@ from .inline_query_result import InlineQueryResult if TYPE_CHECKING: from .inline_keyboard_markup import InlineKeyboardMarkup - from .input_message_content import InputMessageContent + from .input_contact_message_content import InputContactMessageContent + from .input_invoice_message_content import InputInvoiceMessageContent + from .input_location_message_content import InputLocationMessageContent + from .input_text_message_content import InputTextMessageContent + from .input_venue_message_content import InputVenueMessageContent from .message_entity import MessageEntity @@ -22,7 +24,7 @@ class InlineQueryResultVoice(InlineQueryResult): Source: https://core.telegram.org/bots/api#inlinequeryresultvoice """ - type: str = Field(InlineQueryResultType.VOICE, const=True) + type: Literal[InlineQueryResultType.VOICE] = InlineQueryResultType.VOICE """Type of the result, must be *voice*""" id: str """Unique identifier for this result, 1-64 bytes""" @@ -40,5 +42,13 @@ class InlineQueryResultVoice(InlineQueryResult): """*Optional*. Recording duration in seconds""" reply_markup: Optional[InlineKeyboardMarkup] = None """*Optional*. `Inline keyboard `_ attached to the message""" - input_message_content: Optional[InputMessageContent] = None + input_message_content: Optional[ + Union[ + InputTextMessageContent, + InputLocationMessageContent, + InputVenueMessageContent, + InputContactMessageContent, + InputInvoiceMessageContent, + ] + ] = None """*Optional*. Content of the message to be sent instead of the voice recording""" diff --git a/aiogram/types/inline_query_results_button.py b/aiogram/types/inline_query_results_button.py new file mode 100644 index 00000000..0a6db30c --- /dev/null +++ b/aiogram/types/inline_query_results_button.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Optional + +from .base import TelegramObject + +if TYPE_CHECKING: + from .web_app_info import WebAppInfo + + +class InlineQueryResultsButton(TelegramObject): + """ + This object represents a button to be shown above inline query results. You **must** use exactly one of the optional fields. + + Source: https://core.telegram.org/bots/api#inlinequeryresultsbutton + """ + + text: str + """Label text on the button""" + web_app: Optional[WebAppInfo] = None + """*Optional*. Description of the `Web App `_ that will be launched when the user presses the button. The Web App will be able to switch back to the inline mode using the method `switchInlineQuery `_ inside the Web App.""" + start_parameter: Optional[str] = None + """*Optional*. `Deep-linking `_ parameter for the /start message sent to the bot when a user presses the button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed.""" diff --git a/aiogram/types/input_file.py b/aiogram/types/input_file.py index c4090505..ed0a2433 100644 --- a/aiogram/types/input_file.py +++ b/aiogram/types/input_file.py @@ -4,10 +4,21 @@ import io import os from abc import ABC, abstractmethod from pathlib import Path -from typing import AsyncGenerator, AsyncIterator, Iterator, Optional, Union +from typing import ( + TYPE_CHECKING, + Any, + AsyncGenerator, + AsyncIterator, + Dict, + Optional, + Union, +) import aiofiles +if TYPE_CHECKING: + from aiogram.client.bot import Bot + DEFAULT_CHUNK_SIZE = 64 * 1024 # 64 kb @@ -29,10 +40,6 @@ class InputFile(ABC): self.filename = filename self.chunk_size = chunk_size - @classmethod - def __get_validators__(cls) -> Iterator[None]: - yield None - @abstractmethod async def read(self, chunk_size: int) -> AsyncGenerator[bytes, None]: # pragma: no cover yield b"" @@ -114,6 +121,8 @@ class URLInputFile(InputFile): def __init__( self, url: str, + bot: "Bot", + headers: Optional[Dict[str, Any]] = None, filename: Optional[str] = None, chunk_size: int = DEFAULT_CHUNK_SIZE, timeout: int = 30, @@ -122,20 +131,26 @@ class URLInputFile(InputFile): Represents object for streaming files from internet :param url: URL in internet + :param headers: HTTP Headers :param filename: Filename to be propagated to telegram. :param chunk_size: Uploading chunk size + :param timeout: Timeout for downloading + :param bot: Bot instance to use HTTP session from. + If not specified, will be used current bot from context. """ super().__init__(filename=filename, chunk_size=chunk_size) + if headers is None: + headers = {} self.url = url + self.headers = headers self.timeout = timeout + self.bot = bot async def read(self, chunk_size: int) -> AsyncGenerator[bytes, None]: - from aiogram.client.bot import Bot - - bot = Bot.get_current(no_error=False) - stream = bot.session.stream_content( + stream = self.bot.session.stream_content( url=self.url, + headers=self.headers, timeout=self.timeout, chunk_size=self.chunk_size, raise_for_status=True, diff --git a/aiogram/types/input_media_animation.py b/aiogram/types/input_media_animation.py index eabc4b5e..f0e1b860 100644 --- a/aiogram/types/input_media_animation.py +++ b/aiogram/types/input_media_animation.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InputMediaType from .base import UNSET_PARSE_MODE @@ -20,7 +18,7 @@ class InputMediaAnimation(InputMedia): Source: https://core.telegram.org/bots/api#inputmediaanimation """ - type: str = Field(InputMediaType.ANIMATION, const=True) + type: Literal[InputMediaType.ANIMATION] = InputMediaType.ANIMATION """Type of the result, must be *animation*""" media: Union[str, InputFile] """File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet, or pass 'attach://' to upload a new one using multipart/form-data under name. :ref:`More information on Sending Files » `""" diff --git a/aiogram/types/input_media_audio.py b/aiogram/types/input_media_audio.py index 8de62a6f..4bfa74c2 100644 --- a/aiogram/types/input_media_audio.py +++ b/aiogram/types/input_media_audio.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InputMediaType from .base import UNSET_PARSE_MODE @@ -20,7 +18,7 @@ class InputMediaAudio(InputMedia): Source: https://core.telegram.org/bots/api#inputmediaaudio """ - type: str = Field(InputMediaType.AUDIO, const=True) + type: Literal[InputMediaType.AUDIO] = InputMediaType.AUDIO """Type of the result, must be *audio*""" media: Union[str, InputFile] """File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet, or pass 'attach://' to upload a new one using multipart/form-data under name. :ref:`More information on Sending Files » `""" diff --git a/aiogram/types/input_media_document.py b/aiogram/types/input_media_document.py index 9ef4d52f..b749cdcb 100644 --- a/aiogram/types/input_media_document.py +++ b/aiogram/types/input_media_document.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InputMediaType from .base import UNSET_PARSE_MODE @@ -20,7 +18,7 @@ class InputMediaDocument(InputMedia): Source: https://core.telegram.org/bots/api#inputmediadocument """ - type: str = Field(InputMediaType.DOCUMENT, const=True) + type: Literal[InputMediaType.DOCUMENT] = InputMediaType.DOCUMENT """Type of the result, must be *document*""" media: Union[str, InputFile] """File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet, or pass 'attach://' to upload a new one using multipart/form-data under name. :ref:`More information on Sending Files » `""" diff --git a/aiogram/types/input_media_photo.py b/aiogram/types/input_media_photo.py index 0f9500e8..9128627b 100644 --- a/aiogram/types/input_media_photo.py +++ b/aiogram/types/input_media_photo.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InputMediaType from .base import UNSET_PARSE_MODE @@ -20,7 +18,7 @@ class InputMediaPhoto(InputMedia): Source: https://core.telegram.org/bots/api#inputmediaphoto """ - type: str = Field(InputMediaType.PHOTO, const=True) + type: Literal[InputMediaType.PHOTO] = InputMediaType.PHOTO """Type of the result, must be *photo*""" media: Union[str, InputFile] """File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet, or pass 'attach://' to upload a new one using multipart/form-data under name. :ref:`More information on Sending Files » `""" diff --git a/aiogram/types/input_media_video.py b/aiogram/types/input_media_video.py index 89d4df91..b7479607 100644 --- a/aiogram/types/input_media_video.py +++ b/aiogram/types/input_media_video.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union - -from pydantic import Field +from typing import TYPE_CHECKING, List, Literal, Optional, Union from ..enums import InputMediaType from .base import UNSET_PARSE_MODE @@ -20,7 +18,7 @@ class InputMediaVideo(InputMedia): Source: https://core.telegram.org/bots/api#inputmediavideo """ - type: str = Field(InputMediaType.VIDEO, const=True) + type: Literal[InputMediaType.VIDEO] = InputMediaType.VIDEO """Type of the result, must be *video*""" media: Union[str, InputFile] """File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet, or pass 'attach://' to upload a new one using multipart/form-data under name. :ref:`More information on Sending Files » `""" diff --git a/aiogram/types/input_sticker.py b/aiogram/types/input_sticker.py index 46bec15c..15765962 100644 --- a/aiogram/types/input_sticker.py +++ b/aiogram/types/input_sticker.py @@ -17,7 +17,7 @@ class InputSticker(TelegramObject): """ sticker: Union[InputFile, str] - """The added sticker. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. Animated and video stickers can't be uploaded via HTTP URL. :ref:`More information on Sending Files » `""" + """The added sticker. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, upload a new one using multipart/form-data, or pass 'attach://' to upload a new one using multipart/form-data under name. Animated and video stickers can't be uploaded via HTTP URL. :ref:`More information on Sending Files » `""" emoji_list: List[str] """List of 1-20 emoji associated with the sticker""" mask_position: Optional[MaskPosition] = None diff --git a/aiogram/types/keyboard_button_request_chat.py b/aiogram/types/keyboard_button_request_chat.py index f4ec059c..4b402c1b 100644 --- a/aiogram/types/keyboard_button_request_chat.py +++ b/aiogram/types/keyboard_button_request_chat.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class KeyboardButtonRequestChat(TelegramObject): """ - This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed. + This object defines the criteria used to request a suitable chat. The identifier of the selected chat will be shared with the bot when the corresponding button is pressed. `More about requesting chats » `_ Source: https://core.telegram.org/bots/api#keyboardbuttonrequestchat """ diff --git a/aiogram/types/keyboard_button_request_user.py b/aiogram/types/keyboard_button_request_user.py index 5fce962a..b6b33039 100644 --- a/aiogram/types/keyboard_button_request_user.py +++ b/aiogram/types/keyboard_button_request_user.py @@ -5,7 +5,7 @@ from aiogram.types import TelegramObject class KeyboardButtonRequestUser(TelegramObject): """ - This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed. + This object defines the criteria used to request a suitable user. The identifier of the selected user will be shared with the bot when the corresponding button is pressed. `More about requesting users » `_ Source: https://core.telegram.org/bots/api#keyboardbuttonrequestuser """ diff --git a/aiogram/types/menu_button_commands.py b/aiogram/types/menu_button_commands.py index 62a9061c..e37e48cd 100644 --- a/aiogram/types/menu_button_commands.py +++ b/aiogram/types/menu_button_commands.py @@ -1,6 +1,6 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal from ..enums import MenuButtonType from .menu_button import MenuButton @@ -13,5 +13,5 @@ class MenuButtonCommands(MenuButton): Source: https://core.telegram.org/bots/api#menubuttoncommands """ - type: str = Field(MenuButtonType.COMMANDS, const=True) + type: Literal[MenuButtonType.COMMANDS] = MenuButtonType.COMMANDS """Type of the button, must be *commands*""" diff --git a/aiogram/types/menu_button_default.py b/aiogram/types/menu_button_default.py index dc754ec0..7b68803e 100644 --- a/aiogram/types/menu_button_default.py +++ b/aiogram/types/menu_button_default.py @@ -1,6 +1,6 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal from ..enums import MenuButtonType from .menu_button import MenuButton @@ -13,5 +13,5 @@ class MenuButtonDefault(MenuButton): Source: https://core.telegram.org/bots/api#menubuttondefault """ - type: str = Field(MenuButtonType.DEFAULT, const=True) + type: Literal[MenuButtonType.DEFAULT] = MenuButtonType.DEFAULT """Type of the button, must be *default*""" diff --git a/aiogram/types/menu_button_web_app.py b/aiogram/types/menu_button_web_app.py index f77ed2ea..ab908afe 100644 --- a/aiogram/types/menu_button_web_app.py +++ b/aiogram/types/menu_button_web_app.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING - -from pydantic import Field +from typing import TYPE_CHECKING, Literal from ..enums import MenuButtonType from .menu_button import MenuButton @@ -18,7 +16,7 @@ class MenuButtonWebApp(MenuButton): Source: https://core.telegram.org/bots/api#menubuttonwebapp """ - type: str = Field(MenuButtonType.WEB_APP, const=True) + type: Literal[MenuButtonType.WEB_APP] = MenuButtonType.WEB_APP """Type of the button, must be *web_app*""" text: str """Text on the button""" diff --git a/aiogram/types/message.py b/aiogram/types/message.py index c74ccb97..6d022960 100644 --- a/aiogram/types/message.py +++ b/aiogram/types/message.py @@ -67,7 +67,7 @@ if TYPE_CHECKING: from .general_forum_topic_unhidden import GeneralForumTopicUnhidden from .inline_keyboard_markup import InlineKeyboardMarkup from .input_file import InputFile - from .input_media import InputMedia + from .input_media_animation import InputMediaAnimation from .input_media_audio import InputMediaAudio from .input_media_document import InputMediaDocument from .input_media_photo import InputMediaPhoto @@ -317,6 +317,8 @@ class Message(TelegramObject): return ContentType.MESSAGE_AUTO_DELETE_TIMER_CHANGED if self.forum_topic_created: return ContentType.FORUM_TOPIC_CREATED + if self.forum_topic_edited: + return ContentType.FORUM_TOPIC_EDITED if self.forum_topic_closed: return ContentType.FORUM_TOPIC_CLOSED if self.forum_topic_reopened: @@ -416,7 +418,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_animation( self, @@ -488,7 +490,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_audio( self, @@ -557,7 +559,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_audio( self, @@ -627,7 +629,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_contact( self, @@ -683,7 +685,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_contact( self, @@ -740,7 +742,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_document( self, @@ -802,7 +804,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_document( self, @@ -865,7 +867,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_game( self, @@ -910,7 +912,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_game( self, @@ -956,7 +958,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_invoice( self, @@ -1061,7 +1063,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_invoice( self, @@ -1167,7 +1169,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_location( self, @@ -1229,7 +1231,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_location( self, @@ -1292,7 +1294,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_media_group( self, @@ -1334,7 +1336,7 @@ class Message(TelegramObject): protect_content=protect_content, allow_sending_without_reply=allow_sending_without_reply, **kwargs, - ) + ).as_(self._bot) def answer_media_group( self, @@ -1377,7 +1379,7 @@ class Message(TelegramObject): reply_to_message_id=reply_to_message_id, allow_sending_without_reply=allow_sending_without_reply, **kwargs, - ) + ).as_(self._bot) def reply( self, @@ -1433,7 +1435,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer( self, @@ -1490,7 +1492,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_photo( self, @@ -1549,7 +1551,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_photo( self, @@ -1609,7 +1611,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_poll( self, @@ -1689,7 +1691,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_poll( self, @@ -1770,7 +1772,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_dice( self, @@ -1817,7 +1819,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_dice( self, @@ -1865,7 +1867,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_sticker( self, @@ -1915,7 +1917,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_sticker( self, @@ -1966,7 +1968,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_venue( self, @@ -2034,7 +2036,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_venue( self, @@ -2103,7 +2105,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_video( self, @@ -2177,7 +2179,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_video( self, @@ -2252,7 +2254,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_video_note( self, @@ -2308,7 +2310,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_video_note( self, @@ -2365,7 +2367,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def reply_voice( self, @@ -2424,7 +2426,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def answer_voice( self, @@ -2484,7 +2486,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def send_copy( # noqa: C901 self: Message, @@ -2682,7 +2684,7 @@ class Message(TelegramObject): allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def edit_text( self, @@ -2728,7 +2730,7 @@ class Message(TelegramObject): disable_web_page_preview=disable_web_page_preview, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def forward( self, @@ -2768,11 +2770,17 @@ class Message(TelegramObject): disable_notification=disable_notification, protect_content=protect_content, **kwargs, - ) + ).as_(self._bot) def edit_media( self, - media: InputMedia, + media: Union[ + InputMediaAnimation, + InputMediaDocument, + InputMediaAudio, + InputMediaPhoto, + InputMediaVideo, + ], inline_message_id: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, **kwargs: Any, @@ -2805,7 +2813,7 @@ class Message(TelegramObject): inline_message_id=inline_message_id, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def edit_reply_markup( self, @@ -2839,7 +2847,7 @@ class Message(TelegramObject): inline_message_id=inline_message_id, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def delete_reply_markup(self) -> EditMessageReplyMarkup: return self.edit_reply_markup(reply_markup=None) @@ -2891,7 +2899,7 @@ class Message(TelegramObject): proximity_alert_radius=proximity_alert_radius, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def stop_live_location( self, @@ -2925,7 +2933,7 @@ class Message(TelegramObject): inline_message_id=inline_message_id, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def edit_caption( self, @@ -2968,7 +2976,7 @@ class Message(TelegramObject): caption_entities=caption_entities, reply_markup=reply_markup, **kwargs, - ) + ).as_(self._bot) def delete( self, @@ -3014,7 +3022,7 @@ class Message(TelegramObject): chat_id=self.chat.id, message_id=self.message_id, **kwargs, - ) + ).as_(self._bot) def pin( self, @@ -3045,7 +3053,7 @@ class Message(TelegramObject): message_id=self.message_id, disable_notification=disable_notification, **kwargs, - ) + ).as_(self._bot) def unpin( self, @@ -3073,7 +3081,7 @@ class Message(TelegramObject): chat_id=self.chat.id, message_id=self.message_id, **kwargs, - ) + ).as_(self._bot) def get_url(self, force_private: bool = False) -> Optional[str]: """ diff --git a/aiogram/types/passport_element_error_data_field.py b/aiogram/types/passport_element_error_data_field.py index f5b0b67b..76a6d93a 100644 --- a/aiogram/types/passport_element_error_data_field.py +++ b/aiogram/types/passport_element_error_data_field.py @@ -1,7 +1,8 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal +from ..enums import PassportElementErrorType from .passport_element_error import PassportElementError @@ -12,7 +13,7 @@ class PassportElementErrorDataField(PassportElementError): Source: https://core.telegram.org/bots/api#passportelementerrordatafield """ - source: str = Field("data", const=True) + source: Literal[PassportElementErrorType.DATA] = PassportElementErrorType.DATA """Error source, must be *data*""" type: str """The section of the user's Telegram Passport which has the error, one of 'personal_details', 'passport', 'driver_license', 'identity_card', 'internal_passport', 'address'""" diff --git a/aiogram/types/passport_element_error_file.py b/aiogram/types/passport_element_error_file.py index 217deaaa..74512eea 100644 --- a/aiogram/types/passport_element_error_file.py +++ b/aiogram/types/passport_element_error_file.py @@ -1,7 +1,8 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal +from ..enums import PassportElementErrorType from .passport_element_error import PassportElementError @@ -12,7 +13,7 @@ class PassportElementErrorFile(PassportElementError): Source: https://core.telegram.org/bots/api#passportelementerrorfile """ - source: str = Field("file", const=True) + source: Literal[PassportElementErrorType.FILE] = PassportElementErrorType.FILE """Error source, must be *file*""" type: str """The section of the user's Telegram Passport which has the issue, one of 'utility_bill', 'bank_statement', 'rental_agreement', 'passport_registration', 'temporary_registration'""" diff --git a/aiogram/types/passport_element_error_files.py b/aiogram/types/passport_element_error_files.py index 6f42d693..020f7a99 100644 --- a/aiogram/types/passport_element_error_files.py +++ b/aiogram/types/passport_element_error_files.py @@ -1,9 +1,8 @@ from __future__ import annotations -from typing import List - -from pydantic import Field +from typing import List, Literal +from ..enums import PassportElementErrorType from .passport_element_error import PassportElementError @@ -14,7 +13,7 @@ class PassportElementErrorFiles(PassportElementError): Source: https://core.telegram.org/bots/api#passportelementerrorfiles """ - source: str = Field("files", const=True) + source: Literal[PassportElementErrorType.FILES] = PassportElementErrorType.FILES """Error source, must be *files*""" type: str """The section of the user's Telegram Passport which has the issue, one of 'utility_bill', 'bank_statement', 'rental_agreement', 'passport_registration', 'temporary_registration'""" diff --git a/aiogram/types/passport_element_error_front_side.py b/aiogram/types/passport_element_error_front_side.py index 98e60acd..f3b4dd2f 100644 --- a/aiogram/types/passport_element_error_front_side.py +++ b/aiogram/types/passport_element_error_front_side.py @@ -1,7 +1,8 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal +from ..enums import PassportElementErrorType from .passport_element_error import PassportElementError @@ -12,7 +13,7 @@ class PassportElementErrorFrontSide(PassportElementError): Source: https://core.telegram.org/bots/api#passportelementerrorfrontside """ - source: str = Field("front_side", const=True) + source: Literal[PassportElementErrorType.FRONT_SIDE] = PassportElementErrorType.FRONT_SIDE """Error source, must be *front_side*""" type: str """The section of the user's Telegram Passport which has the issue, one of 'passport', 'driver_license', 'identity_card', 'internal_passport'""" diff --git a/aiogram/types/passport_element_error_reverse_side.py b/aiogram/types/passport_element_error_reverse_side.py index 0c6073ba..18929df6 100644 --- a/aiogram/types/passport_element_error_reverse_side.py +++ b/aiogram/types/passport_element_error_reverse_side.py @@ -1,7 +1,8 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal +from ..enums import PassportElementErrorType from .passport_element_error import PassportElementError @@ -12,7 +13,7 @@ class PassportElementErrorReverseSide(PassportElementError): Source: https://core.telegram.org/bots/api#passportelementerrorreverseside """ - source: str = Field("reverse_side", const=True) + source: Literal[PassportElementErrorType.REVERSE_SIDE] = PassportElementErrorType.REVERSE_SIDE """Error source, must be *reverse_side*""" type: str """The section of the user's Telegram Passport which has the issue, one of 'driver_license', 'identity_card'""" diff --git a/aiogram/types/passport_element_error_selfie.py b/aiogram/types/passport_element_error_selfie.py index 4a3b2fe1..003bfec6 100644 --- a/aiogram/types/passport_element_error_selfie.py +++ b/aiogram/types/passport_element_error_selfie.py @@ -1,7 +1,8 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal +from ..enums import PassportElementErrorType from .passport_element_error import PassportElementError @@ -12,7 +13,7 @@ class PassportElementErrorSelfie(PassportElementError): Source: https://core.telegram.org/bots/api#passportelementerrorselfie """ - source: str = Field("selfie", const=True) + source: Literal[PassportElementErrorType.SELFIE] = PassportElementErrorType.SELFIE """Error source, must be *selfie*""" type: str """The section of the user's Telegram Passport which has the issue, one of 'passport', 'driver_license', 'identity_card', 'internal_passport'""" diff --git a/aiogram/types/passport_element_error_translation_file.py b/aiogram/types/passport_element_error_translation_file.py index d4106453..aac4268e 100644 --- a/aiogram/types/passport_element_error_translation_file.py +++ b/aiogram/types/passport_element_error_translation_file.py @@ -1,7 +1,8 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal +from ..enums import PassportElementErrorType from .passport_element_error import PassportElementError @@ -12,7 +13,9 @@ class PassportElementErrorTranslationFile(PassportElementError): Source: https://core.telegram.org/bots/api#passportelementerrortranslationfile """ - source: str = Field("translation_file", const=True) + source: Literal[ + PassportElementErrorType.TRANSLATION_FILE + ] = PassportElementErrorType.TRANSLATION_FILE """Error source, must be *translation_file*""" type: str """Type of element of the user's Telegram Passport which has the issue, one of 'passport', 'driver_license', 'identity_card', 'internal_passport', 'utility_bill', 'bank_statement', 'rental_agreement', 'passport_registration', 'temporary_registration'""" diff --git a/aiogram/types/passport_element_error_translation_files.py b/aiogram/types/passport_element_error_translation_files.py index df0db64f..427c6468 100644 --- a/aiogram/types/passport_element_error_translation_files.py +++ b/aiogram/types/passport_element_error_translation_files.py @@ -1,9 +1,8 @@ from __future__ import annotations -from typing import List - -from pydantic import Field +from typing import List, Literal +from ..enums import PassportElementErrorType from .passport_element_error import PassportElementError @@ -14,7 +13,9 @@ class PassportElementErrorTranslationFiles(PassportElementError): Source: https://core.telegram.org/bots/api#passportelementerrortranslationfiles """ - source: str = Field("translation_files", const=True) + source: Literal[ + PassportElementErrorType.TRANSLATION_FILES + ] = PassportElementErrorType.TRANSLATION_FILES """Error source, must be *translation_files*""" type: str """Type of element of the user's Telegram Passport which has the issue, one of 'passport', 'driver_license', 'identity_card', 'internal_passport', 'utility_bill', 'bank_statement', 'rental_agreement', 'passport_registration', 'temporary_registration'""" diff --git a/aiogram/types/passport_element_error_unspecified.py b/aiogram/types/passport_element_error_unspecified.py index 39d0c417..5e8d88e7 100644 --- a/aiogram/types/passport_element_error_unspecified.py +++ b/aiogram/types/passport_element_error_unspecified.py @@ -1,7 +1,8 @@ from __future__ import annotations -from pydantic import Field +from typing import Literal +from ..enums import PassportElementErrorType from .passport_element_error import PassportElementError @@ -12,7 +13,7 @@ class PassportElementErrorUnspecified(PassportElementError): Source: https://core.telegram.org/bots/api#passportelementerrorunspecified """ - source: str = Field("unspecified", const=True) + source: Literal[PassportElementErrorType.UNSPECIFIED] = PassportElementErrorType.UNSPECIFIED """Error source, must be *unspecified*""" type: str """Type of element of the user's Telegram Passport which has the issue""" diff --git a/aiogram/types/reply_keyboard_remove.py b/aiogram/types/reply_keyboard_remove.py index 1e2c2da9..0260ab6c 100644 --- a/aiogram/types/reply_keyboard_remove.py +++ b/aiogram/types/reply_keyboard_remove.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import Optional - -from pydantic import Field +from typing import Literal, Optional from .base import MutableTelegramObject @@ -14,7 +12,7 @@ class ReplyKeyboardRemove(MutableTelegramObject): Source: https://core.telegram.org/bots/api#replykeyboardremove """ - remove_keyboard: bool = Field(True, const=True) + remove_keyboard: Literal[True] = True """Requests clients to remove the custom keyboard (user will not be able to summon this keyboard; if you want to hide the keyboard from sight but keep it accessible, use *one_time_keyboard* in :class:`aiogram.types.reply_keyboard_markup.ReplyKeyboardMarkup`)""" selective: Optional[bool] = None """*Optional*. Use this parameter if you want to remove the keyboard for specific users only. Targets: 1) users that are @mentioned in the *text* of the :class:`aiogram.types.message.Message` object; 2) if the bot's message is a reply (has *reply_to_message_id*), sender of the original message.""" diff --git a/aiogram/types/sticker.py b/aiogram/types/sticker.py index 1bac276f..cb453b32 100644 --- a/aiogram/types/sticker.py +++ b/aiogram/types/sticker.py @@ -76,7 +76,7 @@ class Sticker(TelegramObject): sticker=self.file_id, position=position, **kwargs, - ) + ).as_(self._bot) def delete_from_set( self, @@ -102,4 +102,4 @@ class Sticker(TelegramObject): return DeleteStickerFromSet( sticker=self.file_id, **kwargs, - ) + ).as_(self._bot) diff --git a/aiogram/types/switch_inline_query_chosen_chat.py b/aiogram/types/switch_inline_query_chosen_chat.py new file mode 100644 index 00000000..f0a2e84f --- /dev/null +++ b/aiogram/types/switch_inline_query_chosen_chat.py @@ -0,0 +1,22 @@ +from typing import Optional + +from .base import TelegramObject + + +class SwitchInlineQueryChosenChat(TelegramObject): + """ + This object represents an inline button that switches the current user to inline mode in a chosen chat, with an optional default inline query. + + Source: https://core.telegram.org/bots/api#switchinlinequerychosenchat + """ + + query: Optional[str] = None + """*Optional*. The default inline query to be inserted in the input field. If left empty, only the bot's username will be inserted""" + allow_user_chats: Optional[bool] = None + """*Optional*. True, if private chats with users can be chosen""" + allow_bot_chats: Optional[bool] = None + """*Optional*. True, if private chats with bots can be chosen""" + allow_group_chats: Optional[bool] = None + """*Optional*. True, if group and supergroup chats can be chosen""" + allow_channel_chats: Optional[bool] = None + """*Optional*. True, if channel chats can be chosen""" diff --git a/aiogram/types/user.py b/aiogram/types/user.py index 3b71af19..de1941fb 100644 --- a/aiogram/types/user.py +++ b/aiogram/types/user.py @@ -90,4 +90,4 @@ class User(TelegramObject): offset=offset, limit=limit, **kwargs, - ) + ).as_(self._bot) diff --git a/aiogram/types/write_access_allowed.py b/aiogram/types/write_access_allowed.py index 859280db..32924410 100644 --- a/aiogram/types/write_access_allowed.py +++ b/aiogram/types/write_access_allowed.py @@ -1,9 +1,14 @@ +from typing import Optional + from aiogram.types import TelegramObject class WriteAccessAllowed(TelegramObject): """ - This object represents a service message about a user allowing a bot added to the attachment menu to write messages. Currently holds no information. + This object represents a service message about a user allowing a bot to write messages after adding the bot to the attachment menu or launching a Web App from a link. Source: https://core.telegram.org/bots/api#writeaccessallowed """ + + web_app_name: Optional[str] = None + """*Optional*. Name of the Web App which was launched from a link""" diff --git a/aiogram/utils/chat_action.py b/aiogram/utils/chat_action.py index b6bda916..d4778443 100644 --- a/aiogram/utils/chat_action.py +++ b/aiogram/utils/chat_action.py @@ -31,22 +31,19 @@ class ChatActionSender: def __init__( self, *, + bot: Bot, chat_id: Union[str, int], action: str = "typing", interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, - bot: Optional[Bot] = None, ) -> None: """ + :param bot: instance of the bot :param chat_id: target chat id :param action: chat action type :param interval: interval between iterations :param initial_sleep: sleep before first iteration - :param bot: instance of the bot, can be omitted from the context """ - if bot is None: - bot = Bot.get_current(False) - self.chat_id = chat_id self.action = action self.interval = interval @@ -132,7 +129,7 @@ class ChatActionSender: def typing( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": @@ -149,7 +146,7 @@ class ChatActionSender: def upload_photo( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": @@ -166,7 +163,7 @@ class ChatActionSender: def record_video( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": @@ -183,7 +180,7 @@ class ChatActionSender: def upload_video( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": @@ -200,7 +197,7 @@ class ChatActionSender: def record_voice( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": @@ -217,7 +214,7 @@ class ChatActionSender: def upload_voice( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": @@ -234,7 +231,7 @@ class ChatActionSender: def upload_document( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": @@ -251,7 +248,7 @@ class ChatActionSender: def choose_sticker( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": @@ -268,7 +265,7 @@ class ChatActionSender: def find_location( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": @@ -285,7 +282,7 @@ class ChatActionSender: def record_video_note( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": @@ -302,7 +299,7 @@ class ChatActionSender: def upload_video_note( cls, chat_id: Union[int, str], - bot: Optional[Bot] = None, + bot: Bot, interval: float = DEFAULT_INTERVAL, initial_sleep: float = DEFAULT_INITIAL_SLEEP, ) -> "ChatActionSender": diff --git a/aiogram/utils/deep_linking.py b/aiogram/utils/deep_linking.py index ec3f9bff..3d27633f 100644 --- a/aiogram/utils/deep_linking.py +++ b/aiogram/utils/deep_linking.py @@ -15,8 +15,9 @@ Basic link example: .. code-block:: python - from aiogram.utils.deep_linking import get_start_link - link = await get_start_link('foo') + from aiogram.utils.deep_linking import create_start_link + + link = await create_start_link(bot, 'foo') # result: 'https://t.me/MyBot?start=foo' @@ -24,20 +25,21 @@ Encoded link example: .. code-block:: python - from aiogram.utils.deep_linking import get_start_link + from aiogram.utils.deep_linking import create_start_link - link = await get_start_link('foo', encode=True) + link = await create_start_link(bot, 'foo', encode=True) # result: 'https://t.me/MyBot?start=Zm9v' Decode it back example: .. code-block:: python from aiogram.utils.deep_linking import decode_payload + from aiogram.filters import CommandStart, CommandObject from aiogram.types import Message - @dp.message_handler(commands=["start"]) - async def handler(message: Message): - args = message.get_args() + @router.message(CommandStart(deep_link=True)) + async def handler(message: Message, command: CommandObject): + args = command.args payload = decode_payload(args) await message.answer(f"Your payload: {payload}") diff --git a/aiogram/utils/formatting.py b/aiogram/utils/formatting.py new file mode 100644 index 00000000..132e04f2 --- /dev/null +++ b/aiogram/utils/formatting.py @@ -0,0 +1,606 @@ +import textwrap +from typing import ( + Any, + ClassVar, + Dict, + Generator, + Iterable, + Iterator, + List, + Optional, + Tuple, + Type, +) + +from typing_extensions import Self + +from aiogram.enums import MessageEntityType +from aiogram.types import MessageEntity, User +from aiogram.utils.text_decorations import ( + add_surrogates, + html_decoration, + markdown_decoration, + remove_surrogates, +) + +NodeType = Any + + +def sizeof(value: str) -> int: + return len(value.encode("utf-16-le")) // 2 + + +class Text(Iterable[NodeType]): + """ + Simple text element + """ + + type: ClassVar[Optional[str]] = None + + __slots__ = ("_body", "_params") + + def __init__( + self, + *body: NodeType, + **params: Any, + ) -> None: + self._body: Tuple[NodeType, ...] = body + self._params: Dict[str, Any] = params + + @classmethod + def from_entities(cls, text: str, entities: List[MessageEntity]) -> "Text": + return cls( + *_unparse_entities( + text=add_surrogates(text), + entities=sorted(entities, key=lambda item: item.offset) if entities else [], + ) + ) + + def render( + self, + *, + _offset: int = 0, + _sort: bool = True, + _collect_entities: bool = True, + ) -> Tuple[str, List[MessageEntity]]: + """ + Render elements tree as text with entities list + + :return: + """ + + text = "" + entities = [] + offset = _offset + + for node in self._body: + if not isinstance(node, Text): + node = str(node) + text += node + offset += sizeof(node) + else: + node_text, node_entities = node.render( + _offset=offset, + _sort=False, + _collect_entities=_collect_entities, + ) + text += node_text + offset += sizeof(node_text) + if _collect_entities: + entities.extend(node_entities) + + if _collect_entities and self.type: + entities.append(self._render_entity(offset=_offset, length=offset - _offset)) + + if _collect_entities and _sort: + entities.sort(key=lambda entity: entity.offset) + + return text, entities + + def _render_entity(self, *, offset: int, length: int) -> MessageEntity: + return MessageEntity(type=self.type, offset=offset, length=length, **self._params) + + def as_kwargs( + self, + *, + text_key: str = "text", + entities_key: str = "entities", + replace_parse_mode: bool = True, + parse_mode_key: str = "parse_mode", + ) -> Dict[str, Any]: + """ + Render elements tree as keyword arguments for usage in the API call, for example: + + .. code-block:: python + + entities = Text(...) + await message.answer(**entities.as_kwargs()) + + :param text_key: + :param entities_key: + :param replace_parse_mode: + :param parse_mode_key: + :return: + """ + text_value, entities_value = self.render() + result: Dict[str, Any] = { + text_key: text_value, + entities_key: entities_value, + } + if replace_parse_mode: + result[parse_mode_key] = None + return result + + def as_html(self) -> str: + """ + Render elements tree as HTML markup + """ + text, entities = self.render() + return html_decoration.unparse(text, entities) + + def as_markdown(self) -> str: + """ + Render elements tree as MarkdownV2 markup + """ + text, entities = self.render() + return markdown_decoration.unparse(text, entities) + + def replace(self: Self, *args: Any, **kwargs: Any) -> Self: + return type(self)(*args, **{**self._params, **kwargs}) + + def as_pretty_string(self, indent: bool = False) -> str: + sep = ",\n" if indent else ", " + body = sep.join( + item.as_pretty_string(indent=indent) if isinstance(item, Text) else repr(item) + for item in self._body + ) + params = sep.join(f"{k}={v!r}" for k, v in self._params.items() if v is not None) + + args = [] + if body: + args.append(body) + if params: + args.append(params) + + args_str = sep.join(args) + if indent: + args_str = textwrap.indent("\n" + args_str + "\n", " ") + return f"{type(self).__name__}({args_str})" + + def __add__(self, other: NodeType) -> "Text": + if isinstance(other, Text) and other.type == self.type and self._params == other._params: + return type(self)(*self, *other, **self._params) + if type(self) == Text and isinstance(other, str): + return type(self)(*self, other, **self._params) + return Text(self, other) + + def __iter__(self) -> Iterator[NodeType]: + yield from self._body + + def __len__(self) -> int: + text, _ = self.render(_collect_entities=False) + return sizeof(text) + + def __getitem__(self, item: slice) -> "Text": + if not isinstance(item, slice): + raise TypeError("Can only be sliced") + if (item.start is None or item.start == 0) and item.stop is None: + return self.replace(*self._body) + start = 0 if item.start is None else item.start + stop = len(self) if item.stop is None else item.stop + if start == stop: + return self.replace() + + nodes = [] + position = 0 + + for node in self._body: + node_size = len(node) + current_position = position + position += node_size + if position < start: + continue + if current_position > stop: + break + a = max((0, start - current_position)) + b = min((node_size, stop - current_position)) + new_node = node[a:b] + if not new_node: + continue + nodes.append(new_node) + + return self.replace(*nodes) + + +class HashTag(Text): + """ + Hashtag element. + + .. warning:: + + The value should always start with '#' symbol + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.HASHTAG` + """ + + type = MessageEntityType.HASHTAG + + def __init__(self, *body: NodeType, **params: Any) -> None: + if len(body) != 1: + raise ValueError("Hashtag can contain only one element") + if not isinstance(body[0], str): + raise ValueError("Hashtag can contain only string") + if not body[0].startswith("#"): + body = ("#" + body[0],) + super().__init__(*body, **params) + + +class CashTag(Text): + """ + Cashtag element. + + .. warning:: + + The value should always start with '$' symbol + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.CASHTAG` + """ + + type = MessageEntityType.CASHTAG + + def __init__(self, *body: NodeType, **params: Any) -> None: + if len(body) != 1: + raise ValueError("Cashtag can contain only one element") + if not isinstance(body[0], str): + raise ValueError("Cashtag can contain only string") + if not body[0].startswith("$"): + body = ("$" + body[0],) + super().__init__(*body, **params) + + +class BotCommand(Text): + """ + Bot command element. + + .. warning:: + + The value should always start with '/' symbol + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.BOT_COMMAND` + """ + + type = MessageEntityType.BOT_COMMAND + + +class Url(Text): + """ + Url element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.URL` + """ + + type = MessageEntityType.URL + + +class Email(Text): + """ + Email element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.EMAIL` + """ + + type = MessageEntityType.EMAIL + + +class PhoneNumber(Text): + """ + Phone number element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.PHONE_NUMBER` + """ + + type = MessageEntityType.PHONE_NUMBER + + +class Bold(Text): + """ + Bold element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.BOLD` + """ + + type = MessageEntityType.BOLD + + +class Italic(Text): + """ + Italic element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.ITALIC` + """ + + type = MessageEntityType.ITALIC + + +class Underline(Text): + """ + Underline element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.UNDERLINE` + """ + + type = MessageEntityType.UNDERLINE + + +class Strikethrough(Text): + """ + Strikethrough element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.STRIKETHROUGH` + """ + + type = MessageEntityType.STRIKETHROUGH + + +class Spoiler(Text): + """ + Spoiler element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.SPOILER` + """ + + type = MessageEntityType.SPOILER + + +class Code(Text): + """ + Code element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.CODE` + """ + + type = MessageEntityType.CODE + + +class Pre(Text): + """ + Pre element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.PRE` + """ + + type = MessageEntityType.PRE + + def __init__(self, *body: NodeType, language: Optional[str] = None, **params: Any) -> None: + super().__init__(*body, language=language, **params) + + +class TextLink(Text): + """ + Text link element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.TEXT_LINK` + """ + + type = MessageEntityType.TEXT_LINK + + def __init__(self, *body: NodeType, url: str, **params: Any) -> None: + super().__init__(*body, url=url, **params) + + +class TextMention(Text): + """ + Text mention element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.TEXT_MENTION` + """ + + type = MessageEntityType.TEXT_MENTION + + def __init__(self, *body: NodeType, user: User, **params: Any) -> None: + super().__init__(*body, user=user, **params) + + +class CustomEmoji(Text): + """ + Custom emoji element. + + Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` + with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.CUSTOM_EMOJI` + """ + + type = MessageEntityType.CUSTOM_EMOJI + + def __init__(self, *body: NodeType, custom_emoji_id: str, **params: Any) -> None: + super().__init__(*body, custom_emoji_id=custom_emoji_id, **params) + + +NODE_TYPES: Dict[Optional[str], Type[Text]] = { + Text.type: Text, + HashTag.type: HashTag, + CashTag.type: CashTag, + BotCommand.type: BotCommand, + Url.type: Url, + Email.type: Email, + PhoneNumber.type: PhoneNumber, + Bold.type: Bold, + Italic.type: Italic, + Underline.type: Underline, + Strikethrough.type: Strikethrough, + Spoiler.type: Spoiler, + Code.type: Code, + Pre.type: Pre, + TextLink.type: TextLink, + TextMention.type: TextMention, +} + + +def _apply_entity(entity: MessageEntity, *nodes: NodeType) -> NodeType: + """ + Apply single entity to text + + :param entity: + :param text: + :return: + """ + node_type = NODE_TYPES.get(entity.type, Text) + return node_type( + *nodes, **entity.model_dump(exclude={"type", "offset", "length"}, warnings=False) + ) + + +def _unparse_entities( + text: bytes, + entities: List[MessageEntity], + offset: Optional[int] = None, + length: Optional[int] = None, +) -> Generator[NodeType, None, None]: + if offset is None: + offset = 0 + length = length or len(text) + + for index, entity in enumerate(entities): + if entity.offset * 2 < offset: + continue + if entity.offset * 2 > offset: + yield remove_surrogates(text[offset : entity.offset * 2]) + start = entity.offset * 2 + offset = entity.offset * 2 + entity.length * 2 + + sub_entities = list(filter(lambda e: e.offset * 2 < (offset or 0), entities[index + 1 :])) + yield _apply_entity( + entity, + *_unparse_entities(text, sub_entities, offset=start, length=offset), + ) + + if offset < length: + yield remove_surrogates(text[offset:length]) + + +def as_line(*items: NodeType, end: str = "\n", sep: str = "") -> Text: + """ + Wrap multiple nodes into line with :code:`\\\\n` at the end of line. + + :param items: Text or Any + :param end: ending of the line, by default is :code:`\\\\n` + :param sep: separator between items, by default is empty string + :return: Text + """ + if sep: + nodes = [] + for item in items[:-1]: + nodes.extend([item, sep]) + nodes.append(items[-1]) + nodes.append(end) + else: + nodes = [*items, end] + return Text(*nodes) + + +def as_list(*items: NodeType, sep: str = "\n") -> Text: + """ + Wrap each element to separated lines + + :param items: + :param sep: + :return: + """ + nodes = [] + for item in items[:-1]: + nodes.extend([item, sep]) + nodes.append(items[-1]) + return Text(*nodes) + + +def as_marked_list(*items: NodeType, marker: str = "- ") -> Text: + """ + Wrap elements as marked list + + :param items: + :param marker: line marker, by default is :code:`- ` + :return: Text + """ + return as_list(*(Text(marker, item) for item in items)) + + +def as_numbered_list(*items: NodeType, start: int = 1, fmt: str = "{}. ") -> Text: + """ + Wrap elements as numbered list + + :param items: + :param start: initial number, by default 1 + :param fmt: number format, by default :code:`{}. ` + :return: Text + """ + return as_list(*(Text(fmt.format(index), item) for index, item in enumerate(items, start))) + + +def as_section(title: NodeType, *body: NodeType) -> Text: + """ + Wrap elements as simple section, section has title and body + + :param title: + :param body: + :return: Text + """ + return Text(title, "\n", *body) + + +def as_marked_section( + title: NodeType, + *body: NodeType, + marker: str = "- ", +) -> Text: + """ + Wrap elements as section with marked list + + :param title: + :param body: + :param marker: + :return: + """ + return as_section(title, as_marked_list(*body, marker=marker)) + + +def as_numbered_section( + title: NodeType, + *body: NodeType, + start: int = 1, + fmt: str = "{}. ", +) -> Text: + """ + Wrap elements as section with numbered list + + :param title: + :param body: + :param start: + :param fmt: + :return: + """ + return as_section(title, as_numbered_list(*body, start=start, fmt=fmt)) + + +def as_key_value(key: NodeType, value: NodeType) -> Text: + """ + Wrap elements pair as key-value line. (:code:`{key}: {value}`) + + :param key: + :param value: + :return: Text + """ + return Text(Bold(key, ":"), " ", value) diff --git a/aiogram/utils/i18n/middleware.py b/aiogram/utils/i18n/middleware.py index e720db1a..68be22bc 100644 --- a/aiogram/utils/i18n/middleware.py +++ b/aiogram/utils/i18n/middleware.py @@ -1,10 +1,10 @@ from abc import ABC, abstractmethod -from typing import Any, Awaitable, Callable, Dict, Optional, Set, cast +from typing import Any, Awaitable, Callable, Dict, Optional, Set try: from babel import Locale, UnknownLocaleError except ImportError: # pragma: no cover - Locale = None + Locale = None # type: ignore class UnknownLocaleError(Exception): # type: ignore pass @@ -127,7 +127,7 @@ class SimpleI18nMiddleware(I18nMiddleware): if locale.language not in self.i18n.available_locales: return self.i18n.default_locale - return cast(str, locale.language) + return locale.language class ConstI18nMiddleware(I18nMiddleware): diff --git a/aiogram/utils/link.py b/aiogram/utils/link.py index e4bc28f2..051247fa 100644 --- a/aiogram/utils/link.py +++ b/aiogram/utils/link.py @@ -26,3 +26,49 @@ def create_tg_link(link: str, **kwargs: Any) -> str: def create_telegram_link(*path: str, **kwargs: Any) -> str: return _format_url("https://t.me", *path, **kwargs) + + +def create_channel_bot_link( + username: str, + parameter: Optional[str] = None, + change_info: bool = False, + post_messages: bool = False, + edit_messages: bool = False, + delete_messages: bool = False, + restrict_members: bool = False, + invite_users: bool = False, + pin_messages: bool = False, + promote_members: bool = False, + manage_video_chats: bool = False, + anonymous: bool = False, + manage_chat: bool = False, +) -> str: + params = {} + if parameter is not None: + params["startgroup"] = parameter + permissions = [] + if change_info: + permissions.append("change_info") + if post_messages: + permissions.append("post_messages") + if edit_messages: + permissions.append("edit_messages") + if delete_messages: + permissions.append("delete_messages") + if restrict_members: + permissions.append("restrict_members") + if invite_users: + permissions.append("invite_users") + if pin_messages: + permissions.append("pin_messages") + if promote_members: + permissions.append("promote_members") + if manage_video_chats: + permissions.append("manage_video_chats") + if anonymous: + permissions.append("anonymous") + if manage_chat: + permissions.append("manage_chat") + if permissions: + params["admin"] = "+".join(permissions) + return create_telegram_link(username, **params) diff --git a/aiogram/utils/text_decorations.py b/aiogram/utils/text_decorations.py index 70f96388..97430a32 100644 --- a/aiogram/utils/text_decorations.py +++ b/aiogram/utils/text_decorations.py @@ -233,7 +233,7 @@ class MarkdownDecoration(TextDecoration): return f"~{value}~" def spoiler(self, value: str) -> str: - return f"|{value}|" + return f"||{value}||" def quote(self, value: str) -> str: return re.sub(pattern=self.MARKDOWN_QUOTE_PATTERN, repl=r"\\\1", string=value) diff --git a/aiogram/webhook/aiohttp_server.py b/aiogram/webhook/aiohttp_server.py index 4406f1ff..f623484f 100644 --- a/aiogram/webhook/aiohttp_server.py +++ b/aiogram/webhook/aiohttp_server.py @@ -28,8 +28,8 @@ def setup_application(app: Application, dispatcher: Dispatcher, /, **kwargs: Any workflow_data = { "app": app, "dispatcher": dispatcher, - **kwargs, **dispatcher.workflow_data, + **kwargs, } async def on_startup(*a: Any, **kw: Any) -> None: # pragma: no cover @@ -131,6 +131,10 @@ class BaseRequestHandler(ABC): """ pass + @abstractmethod + def verify_secret(self, telegram_secret_token: str, bot: Bot) -> bool: + pass + async def _background_feed_update(self, bot: Bot, update: Dict[str, Any]) -> None: result = await self.dispatcher.feed_raw_update(bot=bot, update=update, **self.data) if isinstance(result, TelegramMethod): @@ -158,7 +162,7 @@ class BaseRequestHandler(ABC): payload.set_content_disposition("form-data", name="method") files: Dict[str, InputFile] = {} - for key, value in result.dict().items(): + for key, value in result.model_dump(warnings=False).items(): value = bot.session.prepare_value(value, bot=bot, files=files) if not value: continue @@ -185,6 +189,8 @@ class BaseRequestHandler(ABC): async def handle(self, request: web.Request) -> web.Response: bot = await self.resolve_bot(request) + if not self.verify_secret(request.headers.get("X-Telegram-Bot-Api-Secret-Token", ""), bot): + return web.Response(body="Unauthorized", status=401) if self.handle_in_background: return await self._handle_request_background(bot=bot, request=request) return await self._handle_request(bot=bot, request=request) @@ -198,7 +204,12 @@ class SimpleRequestHandler(BaseRequestHandler): """ def __init__( - self, dispatcher: Dispatcher, bot: Bot, handle_in_background: bool = True, **data: Any + self, + dispatcher: Dispatcher, + bot: Bot, + handle_in_background: bool = True, + secret_token: Optional[str] = None, + **data: Any, ) -> None: """ :param dispatcher: instance of :class:`aiogram.dispatcher.dispatcher.Dispatcher` @@ -208,6 +219,12 @@ class SimpleRequestHandler(BaseRequestHandler): """ super().__init__(dispatcher=dispatcher, handle_in_background=handle_in_background, **data) self.bot = bot + self.secret_token = secret_token + + def verify_secret(self, telegram_secret_token: str, bot: Bot) -> bool: + if self.secret_token: + return secrets.compare_digest(telegram_secret_token, self.secret_token) + return True async def close(self) -> None: """ @@ -244,6 +261,9 @@ class TokenBasedRequestHandler(BaseRequestHandler): self.bot_settings = bot_settings self.bots: Dict[str, Bot] = {} + def verify_secret(self, telegram_secret_token: str, bot: Bot) -> bool: + return True + async def close(self) -> None: for bot in self.bots.values(): await bot.session.close() diff --git a/docs/api/enums/encrypted_passport_element.rst b/docs/api/enums/encrypted_passport_element.rst new file mode 100644 index 00000000..9d79b162 --- /dev/null +++ b/docs/api/enums/encrypted_passport_element.rst @@ -0,0 +1,9 @@ +######################## +EncryptedPassportElement +######################## + + +.. automodule:: aiogram.enums.encrypted_passport_element + :members: + :member-order: bysource + :undoc-members: True diff --git a/docs/api/enums/index.rst b/docs/api/enums/index.rst index 84a4b837..e496f5b4 100644 --- a/docs/api/enums/index.rst +++ b/docs/api/enums/index.rst @@ -14,12 +14,14 @@ Here is list of all available enums: chat_type content_type dice_emoji + encrypted_passport_element inline_query_result_type input_media_type mask_position_point menu_button_type message_entity_type parse_mode + passport_element_error_type poll_type sticker_format sticker_type diff --git a/docs/api/enums/passport_element_error_type.rst b/docs/api/enums/passport_element_error_type.rst new file mode 100644 index 00000000..c79d9b11 --- /dev/null +++ b/docs/api/enums/passport_element_error_type.rst @@ -0,0 +1,9 @@ +######################## +PassportElementErrorType +######################## + + +.. automodule:: aiogram.enums.passport_element_error_type + :members: + :member-order: bysource + :undoc-members: True diff --git a/docs/api/methods/add_sticker_to_set.rst b/docs/api/methods/add_sticker_to_set.rst index 8c86d09a..8168a20e 100644 --- a/docs/api/methods/add_sticker_to_set.rst +++ b/docs/api/methods/add_sticker_to_set.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/answer_callback_query.rst b/docs/api/methods/answer_callback_query.rst index aadbc1fa..42c016ec 100644 --- a/docs/api/methods/answer_callback_query.rst +++ b/docs/api/methods/answer_callback_query.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/answer_inline_query.rst b/docs/api/methods/answer_inline_query.rst index 79b46888..3d4b7948 100644 --- a/docs/api/methods/answer_inline_query.rst +++ b/docs/api/methods/answer_inline_query.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/answer_pre_checkout_query.rst b/docs/api/methods/answer_pre_checkout_query.rst index 82157af2..e0ae9694 100644 --- a/docs/api/methods/answer_pre_checkout_query.rst +++ b/docs/api/methods/answer_pre_checkout_query.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/answer_shipping_query.rst b/docs/api/methods/answer_shipping_query.rst index b9ddc36c..d1854376 100644 --- a/docs/api/methods/answer_shipping_query.rst +++ b/docs/api/methods/answer_shipping_query.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/answer_web_app_query.rst b/docs/api/methods/answer_web_app_query.rst index 884366ee..3a38dab0 100644 --- a/docs/api/methods/answer_web_app_query.rst +++ b/docs/api/methods/answer_web_app_query.rst @@ -8,6 +8,7 @@ Returns: :obj:`SentWebAppMessage` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/approve_chat_join_request.rst b/docs/api/methods/approve_chat_join_request.rst index 0f54f2a8..d87335dc 100644 --- a/docs/api/methods/approve_chat_join_request.rst +++ b/docs/api/methods/approve_chat_join_request.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/ban_chat_member.rst b/docs/api/methods/ban_chat_member.rst index a28db5df..1197408e 100644 --- a/docs/api/methods/ban_chat_member.rst +++ b/docs/api/methods/ban_chat_member.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/ban_chat_sender_chat.rst b/docs/api/methods/ban_chat_sender_chat.rst index 68b2fba5..8e237cab 100644 --- a/docs/api/methods/ban_chat_sender_chat.rst +++ b/docs/api/methods/ban_chat_sender_chat.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/close.rst b/docs/api/methods/close.rst index 6c315eb4..a3f509cf 100644 --- a/docs/api/methods/close.rst +++ b/docs/api/methods/close.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/close_forum_topic.rst b/docs/api/methods/close_forum_topic.rst index 127813d0..416fae77 100644 --- a/docs/api/methods/close_forum_topic.rst +++ b/docs/api/methods/close_forum_topic.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/close_general_forum_topic.rst b/docs/api/methods/close_general_forum_topic.rst index 1f2bfe2c..b316c264 100644 --- a/docs/api/methods/close_general_forum_topic.rst +++ b/docs/api/methods/close_general_forum_topic.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/copy_message.rst b/docs/api/methods/copy_message.rst index 92edcb1a..ae1e5dd1 100644 --- a/docs/api/methods/copy_message.rst +++ b/docs/api/methods/copy_message.rst @@ -8,6 +8,7 @@ Returns: :obj:`MessageId` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/create_chat_invite_link.rst b/docs/api/methods/create_chat_invite_link.rst index 1543a40f..67b2e5c8 100644 --- a/docs/api/methods/create_chat_invite_link.rst +++ b/docs/api/methods/create_chat_invite_link.rst @@ -8,6 +8,7 @@ Returns: :obj:`ChatInviteLink` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/create_forum_topic.rst b/docs/api/methods/create_forum_topic.rst index 0c46afeb..4663049c 100644 --- a/docs/api/methods/create_forum_topic.rst +++ b/docs/api/methods/create_forum_topic.rst @@ -8,6 +8,7 @@ Returns: :obj:`ForumTopic` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/create_invoice_link.rst b/docs/api/methods/create_invoice_link.rst index 5d25aae9..ace5b729 100644 --- a/docs/api/methods/create_invoice_link.rst +++ b/docs/api/methods/create_invoice_link.rst @@ -8,6 +8,7 @@ Returns: :obj:`str` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/create_new_sticker_set.rst b/docs/api/methods/create_new_sticker_set.rst index a118200b..e59e1b14 100644 --- a/docs/api/methods/create_new_sticker_set.rst +++ b/docs/api/methods/create_new_sticker_set.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/decline_chat_join_request.rst b/docs/api/methods/decline_chat_join_request.rst index b0ba4a24..5cee1a7e 100644 --- a/docs/api/methods/decline_chat_join_request.rst +++ b/docs/api/methods/decline_chat_join_request.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/delete_chat_photo.rst b/docs/api/methods/delete_chat_photo.rst index c218a1c0..4757aa75 100644 --- a/docs/api/methods/delete_chat_photo.rst +++ b/docs/api/methods/delete_chat_photo.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/delete_chat_sticker_set.rst b/docs/api/methods/delete_chat_sticker_set.rst index f8472556..6af3c840 100644 --- a/docs/api/methods/delete_chat_sticker_set.rst +++ b/docs/api/methods/delete_chat_sticker_set.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/delete_forum_topic.rst b/docs/api/methods/delete_forum_topic.rst index f17a204c..3966c7d8 100644 --- a/docs/api/methods/delete_forum_topic.rst +++ b/docs/api/methods/delete_forum_topic.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/delete_message.rst b/docs/api/methods/delete_message.rst index 4e6ee2ef..dade9117 100644 --- a/docs/api/methods/delete_message.rst +++ b/docs/api/methods/delete_message.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/delete_my_commands.rst b/docs/api/methods/delete_my_commands.rst index 58cfce2b..cc11d818 100644 --- a/docs/api/methods/delete_my_commands.rst +++ b/docs/api/methods/delete_my_commands.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/delete_sticker_from_set.rst b/docs/api/methods/delete_sticker_from_set.rst index f00d3a9d..7821ef0e 100644 --- a/docs/api/methods/delete_sticker_from_set.rst +++ b/docs/api/methods/delete_sticker_from_set.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/delete_sticker_set.rst b/docs/api/methods/delete_sticker_set.rst index dc9be624..cc2dbdd2 100644 --- a/docs/api/methods/delete_sticker_set.rst +++ b/docs/api/methods/delete_sticker_set.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/delete_webhook.rst b/docs/api/methods/delete_webhook.rst index b903296a..1c3ad04d 100644 --- a/docs/api/methods/delete_webhook.rst +++ b/docs/api/methods/delete_webhook.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/edit_chat_invite_link.rst b/docs/api/methods/edit_chat_invite_link.rst index a1543b3e..709d26b8 100644 --- a/docs/api/methods/edit_chat_invite_link.rst +++ b/docs/api/methods/edit_chat_invite_link.rst @@ -8,6 +8,7 @@ Returns: :obj:`ChatInviteLink` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/edit_forum_topic.rst b/docs/api/methods/edit_forum_topic.rst index daa6ff0e..a190d534 100644 --- a/docs/api/methods/edit_forum_topic.rst +++ b/docs/api/methods/edit_forum_topic.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/edit_general_forum_topic.rst b/docs/api/methods/edit_general_forum_topic.rst index b038c9d3..a06021d5 100644 --- a/docs/api/methods/edit_general_forum_topic.rst +++ b/docs/api/methods/edit_general_forum_topic.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/edit_message_caption.rst b/docs/api/methods/edit_message_caption.rst index cb90bba3..a37c17a5 100644 --- a/docs/api/methods/edit_message_caption.rst +++ b/docs/api/methods/edit_message_caption.rst @@ -8,6 +8,7 @@ Returns: :obj:`Union[Message, bool]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/edit_message_live_location.rst b/docs/api/methods/edit_message_live_location.rst index edeb5353..f2f0b3df 100644 --- a/docs/api/methods/edit_message_live_location.rst +++ b/docs/api/methods/edit_message_live_location.rst @@ -8,6 +8,7 @@ Returns: :obj:`Union[Message, bool]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/edit_message_media.rst b/docs/api/methods/edit_message_media.rst index faa4c6c2..aae7d89b 100644 --- a/docs/api/methods/edit_message_media.rst +++ b/docs/api/methods/edit_message_media.rst @@ -8,6 +8,7 @@ Returns: :obj:`Union[Message, bool]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/edit_message_reply_markup.rst b/docs/api/methods/edit_message_reply_markup.rst index d8db9a2b..6f814c2e 100644 --- a/docs/api/methods/edit_message_reply_markup.rst +++ b/docs/api/methods/edit_message_reply_markup.rst @@ -8,6 +8,7 @@ Returns: :obj:`Union[Message, bool]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/edit_message_text.rst b/docs/api/methods/edit_message_text.rst index 0098e9a1..b707de73 100644 --- a/docs/api/methods/edit_message_text.rst +++ b/docs/api/methods/edit_message_text.rst @@ -8,6 +8,7 @@ Returns: :obj:`Union[Message, bool]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/export_chat_invite_link.rst b/docs/api/methods/export_chat_invite_link.rst index c9bd9945..c8aa1b6b 100644 --- a/docs/api/methods/export_chat_invite_link.rst +++ b/docs/api/methods/export_chat_invite_link.rst @@ -8,6 +8,7 @@ Returns: :obj:`str` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/forward_message.rst b/docs/api/methods/forward_message.rst index 38465cf5..516442ad 100644 --- a/docs/api/methods/forward_message.rst +++ b/docs/api/methods/forward_message.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_chat.rst b/docs/api/methods/get_chat.rst index dbc1143c..c0c95236 100644 --- a/docs/api/methods/get_chat.rst +++ b/docs/api/methods/get_chat.rst @@ -8,6 +8,7 @@ Returns: :obj:`Chat` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_chat_administrators.rst b/docs/api/methods/get_chat_administrators.rst index f56966d2..9a1784b5 100644 --- a/docs/api/methods/get_chat_administrators.rst +++ b/docs/api/methods/get_chat_administrators.rst @@ -8,6 +8,7 @@ Returns: :obj:`List[Union[ChatMemberOwner, ChatMemberAdministrator, ChatMemberMe :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_chat_member.rst b/docs/api/methods/get_chat_member.rst index 6155fb24..60742bf6 100644 --- a/docs/api/methods/get_chat_member.rst +++ b/docs/api/methods/get_chat_member.rst @@ -8,6 +8,7 @@ Returns: :obj:`Union[ChatMemberOwner, ChatMemberAdministrator, ChatMemberMember, :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_chat_member_count.rst b/docs/api/methods/get_chat_member_count.rst index ec4497b6..73177a1a 100644 --- a/docs/api/methods/get_chat_member_count.rst +++ b/docs/api/methods/get_chat_member_count.rst @@ -8,6 +8,7 @@ Returns: :obj:`int` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_chat_menu_button.rst b/docs/api/methods/get_chat_menu_button.rst index 5a3f5a6f..e70fddb0 100644 --- a/docs/api/methods/get_chat_menu_button.rst +++ b/docs/api/methods/get_chat_menu_button.rst @@ -8,6 +8,7 @@ Returns: :obj:`Union[MenuButtonDefault, MenuButtonWebApp, MenuButtonCommands]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_custom_emoji_stickers.rst b/docs/api/methods/get_custom_emoji_stickers.rst index 9c7455fd..c7b4dbc5 100644 --- a/docs/api/methods/get_custom_emoji_stickers.rst +++ b/docs/api/methods/get_custom_emoji_stickers.rst @@ -8,6 +8,7 @@ Returns: :obj:`List[Sticker]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_file.rst b/docs/api/methods/get_file.rst index eb9f3b7d..5eda2ebf 100644 --- a/docs/api/methods/get_file.rst +++ b/docs/api/methods/get_file.rst @@ -8,6 +8,7 @@ Returns: :obj:`File` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_forum_topic_icon_stickers.rst b/docs/api/methods/get_forum_topic_icon_stickers.rst index ef3887e4..5e6680a7 100644 --- a/docs/api/methods/get_forum_topic_icon_stickers.rst +++ b/docs/api/methods/get_forum_topic_icon_stickers.rst @@ -8,6 +8,7 @@ Returns: :obj:`List[Sticker]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_game_high_scores.rst b/docs/api/methods/get_game_high_scores.rst index d57d781d..67b40ef3 100644 --- a/docs/api/methods/get_game_high_scores.rst +++ b/docs/api/methods/get_game_high_scores.rst @@ -8,6 +8,7 @@ Returns: :obj:`List[GameHighScore]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_me.rst b/docs/api/methods/get_me.rst index cf883046..96117b9e 100644 --- a/docs/api/methods/get_me.rst +++ b/docs/api/methods/get_me.rst @@ -8,6 +8,7 @@ Returns: :obj:`User` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_my_commands.rst b/docs/api/methods/get_my_commands.rst index a67f1d88..9ca3a907 100644 --- a/docs/api/methods/get_my_commands.rst +++ b/docs/api/methods/get_my_commands.rst @@ -8,6 +8,7 @@ Returns: :obj:`List[BotCommand]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_my_default_administrator_rights.rst b/docs/api/methods/get_my_default_administrator_rights.rst index 5d28e41f..360f482a 100644 --- a/docs/api/methods/get_my_default_administrator_rights.rst +++ b/docs/api/methods/get_my_default_administrator_rights.rst @@ -8,6 +8,7 @@ Returns: :obj:`ChatAdministratorRights` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_my_description.rst b/docs/api/methods/get_my_description.rst index c68bda0d..d8846821 100644 --- a/docs/api/methods/get_my_description.rst +++ b/docs/api/methods/get_my_description.rst @@ -8,6 +8,7 @@ Returns: :obj:`BotDescription` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_my_name.rst b/docs/api/methods/get_my_name.rst new file mode 100644 index 00000000..5bf9c10d --- /dev/null +++ b/docs/api/methods/get_my_name.rst @@ -0,0 +1,38 @@ +######### +getMyName +######### + +Returns: :obj:`BotName` + +.. automodule:: aiogram.methods.get_my_name + :members: + :member-order: bysource + :undoc-members: True + :exclude-members: model_config,model_fields + + +Usage +===== + +As bot method +------------- + +.. code-block:: + + result: BotName = await bot.get_my_name(...) + + +Method as object +---------------- + +Imports: + +- :code:`from aiogram.methods.get_my_name import GetMyName` +- alias: :code:`from aiogram.methods import GetMyName` + +With specific bot +~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + result: BotName = await bot(GetMyName(...)) diff --git a/docs/api/methods/get_my_short_description.rst b/docs/api/methods/get_my_short_description.rst index 967d3318..3acac53a 100644 --- a/docs/api/methods/get_my_short_description.rst +++ b/docs/api/methods/get_my_short_description.rst @@ -8,6 +8,7 @@ Returns: :obj:`BotShortDescription` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_sticker_set.rst b/docs/api/methods/get_sticker_set.rst index 2b131b21..e30f9110 100644 --- a/docs/api/methods/get_sticker_set.rst +++ b/docs/api/methods/get_sticker_set.rst @@ -8,6 +8,7 @@ Returns: :obj:`StickerSet` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_updates.rst b/docs/api/methods/get_updates.rst index 7d14ee1e..f774aef1 100644 --- a/docs/api/methods/get_updates.rst +++ b/docs/api/methods/get_updates.rst @@ -8,6 +8,7 @@ Returns: :obj:`List[Update]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_user_profile_photos.rst b/docs/api/methods/get_user_profile_photos.rst index f0c36a61..7b165bae 100644 --- a/docs/api/methods/get_user_profile_photos.rst +++ b/docs/api/methods/get_user_profile_photos.rst @@ -8,6 +8,7 @@ Returns: :obj:`UserProfilePhotos` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/get_webhook_info.rst b/docs/api/methods/get_webhook_info.rst index d038a261..a2e2dc08 100644 --- a/docs/api/methods/get_webhook_info.rst +++ b/docs/api/methods/get_webhook_info.rst @@ -8,6 +8,7 @@ Returns: :obj:`WebhookInfo` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/hide_general_forum_topic.rst b/docs/api/methods/hide_general_forum_topic.rst index df36474e..619e5233 100644 --- a/docs/api/methods/hide_general_forum_topic.rst +++ b/docs/api/methods/hide_general_forum_topic.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/index.rst b/docs/api/methods/index.rst index 17626855..4a7f4b01 100644 --- a/docs/api/methods/index.rst +++ b/docs/api/methods/index.rst @@ -42,6 +42,7 @@ Available methods get_my_commands get_my_default_administrator_rights get_my_description + get_my_name get_my_short_description get_user_profile_photos hide_general_forum_topic @@ -78,6 +79,7 @@ Available methods set_my_commands set_my_default_administrator_rights set_my_description + set_my_name set_my_short_description unban_chat_member unban_chat_sender_chat diff --git a/docs/api/methods/leave_chat.rst b/docs/api/methods/leave_chat.rst index 8c84e324..fd829a1a 100644 --- a/docs/api/methods/leave_chat.rst +++ b/docs/api/methods/leave_chat.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/log_out.rst b/docs/api/methods/log_out.rst index 683cf19a..d1545da8 100644 --- a/docs/api/methods/log_out.rst +++ b/docs/api/methods/log_out.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/pin_chat_message.rst b/docs/api/methods/pin_chat_message.rst index 11de4e53..6c6756bd 100644 --- a/docs/api/methods/pin_chat_message.rst +++ b/docs/api/methods/pin_chat_message.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/promote_chat_member.rst b/docs/api/methods/promote_chat_member.rst index aada3f05..19bcd5be 100644 --- a/docs/api/methods/promote_chat_member.rst +++ b/docs/api/methods/promote_chat_member.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/reopen_forum_topic.rst b/docs/api/methods/reopen_forum_topic.rst index c76b7adc..9838d934 100644 --- a/docs/api/methods/reopen_forum_topic.rst +++ b/docs/api/methods/reopen_forum_topic.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/reopen_general_forum_topic.rst b/docs/api/methods/reopen_general_forum_topic.rst index ec217d9c..5d89f7cc 100644 --- a/docs/api/methods/reopen_general_forum_topic.rst +++ b/docs/api/methods/reopen_general_forum_topic.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/restrict_chat_member.rst b/docs/api/methods/restrict_chat_member.rst index b063b8b1..da10bbd9 100644 --- a/docs/api/methods/restrict_chat_member.rst +++ b/docs/api/methods/restrict_chat_member.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/revoke_chat_invite_link.rst b/docs/api/methods/revoke_chat_invite_link.rst index f8293be2..5d88c4ce 100644 --- a/docs/api/methods/revoke_chat_invite_link.rst +++ b/docs/api/methods/revoke_chat_invite_link.rst @@ -8,6 +8,7 @@ Returns: :obj:`ChatInviteLink` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_animation.rst b/docs/api/methods/send_animation.rst index 220bf5ba..cc4e727a 100644 --- a/docs/api/methods/send_animation.rst +++ b/docs/api/methods/send_animation.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_audio.rst b/docs/api/methods/send_audio.rst index 877478ba..0c332cbd 100644 --- a/docs/api/methods/send_audio.rst +++ b/docs/api/methods/send_audio.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_chat_action.rst b/docs/api/methods/send_chat_action.rst index c1ad9e61..efff1e27 100644 --- a/docs/api/methods/send_chat_action.rst +++ b/docs/api/methods/send_chat_action.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_contact.rst b/docs/api/methods/send_contact.rst index 05af5b1e..d7f13cba 100644 --- a/docs/api/methods/send_contact.rst +++ b/docs/api/methods/send_contact.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_dice.rst b/docs/api/methods/send_dice.rst index 5e1548f7..4a106c04 100644 --- a/docs/api/methods/send_dice.rst +++ b/docs/api/methods/send_dice.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_document.rst b/docs/api/methods/send_document.rst index 60d9d0b0..b0121109 100644 --- a/docs/api/methods/send_document.rst +++ b/docs/api/methods/send_document.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_game.rst b/docs/api/methods/send_game.rst index d145c430..18d299cf 100644 --- a/docs/api/methods/send_game.rst +++ b/docs/api/methods/send_game.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_invoice.rst b/docs/api/methods/send_invoice.rst index 1e5ce258..bd5070fd 100644 --- a/docs/api/methods/send_invoice.rst +++ b/docs/api/methods/send_invoice.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_location.rst b/docs/api/methods/send_location.rst index 3c52df75..c8dc9f56 100644 --- a/docs/api/methods/send_location.rst +++ b/docs/api/methods/send_location.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_media_group.rst b/docs/api/methods/send_media_group.rst index fe0f8e03..9d9de9e9 100644 --- a/docs/api/methods/send_media_group.rst +++ b/docs/api/methods/send_media_group.rst @@ -8,6 +8,7 @@ Returns: :obj:`List[Message]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_message.rst b/docs/api/methods/send_message.rst index 9edb4bf3..594ef99c 100644 --- a/docs/api/methods/send_message.rst +++ b/docs/api/methods/send_message.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_photo.rst b/docs/api/methods/send_photo.rst index 85fb0921..b622f6cc 100644 --- a/docs/api/methods/send_photo.rst +++ b/docs/api/methods/send_photo.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_poll.rst b/docs/api/methods/send_poll.rst index 14e10d19..36100c36 100644 --- a/docs/api/methods/send_poll.rst +++ b/docs/api/methods/send_poll.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_sticker.rst b/docs/api/methods/send_sticker.rst index 395fb12b..4c67047a 100644 --- a/docs/api/methods/send_sticker.rst +++ b/docs/api/methods/send_sticker.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_venue.rst b/docs/api/methods/send_venue.rst index 4985cbc1..79cfc8ca 100644 --- a/docs/api/methods/send_venue.rst +++ b/docs/api/methods/send_venue.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_video.rst b/docs/api/methods/send_video.rst index a8e6e1b4..c8446369 100644 --- a/docs/api/methods/send_video.rst +++ b/docs/api/methods/send_video.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_video_note.rst b/docs/api/methods/send_video_note.rst index aa27c198..089f9e66 100644 --- a/docs/api/methods/send_video_note.rst +++ b/docs/api/methods/send_video_note.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/send_voice.rst b/docs/api/methods/send_voice.rst index 3742cdb3..3f19e9e9 100644 --- a/docs/api/methods/send_voice.rst +++ b/docs/api/methods/send_voice.rst @@ -8,6 +8,7 @@ Returns: :obj:`Message` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_chat_administrator_custom_title.rst b/docs/api/methods/set_chat_administrator_custom_title.rst index 60d8df84..560185f1 100644 --- a/docs/api/methods/set_chat_administrator_custom_title.rst +++ b/docs/api/methods/set_chat_administrator_custom_title.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_chat_description.rst b/docs/api/methods/set_chat_description.rst index 85cd7d48..7cd242b7 100644 --- a/docs/api/methods/set_chat_description.rst +++ b/docs/api/methods/set_chat_description.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_chat_menu_button.rst b/docs/api/methods/set_chat_menu_button.rst index 671313fe..2262dca7 100644 --- a/docs/api/methods/set_chat_menu_button.rst +++ b/docs/api/methods/set_chat_menu_button.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_chat_permissions.rst b/docs/api/methods/set_chat_permissions.rst index 7867065c..0636fede 100644 --- a/docs/api/methods/set_chat_permissions.rst +++ b/docs/api/methods/set_chat_permissions.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_chat_photo.rst b/docs/api/methods/set_chat_photo.rst index ee7434f9..6a5edccd 100644 --- a/docs/api/methods/set_chat_photo.rst +++ b/docs/api/methods/set_chat_photo.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_chat_sticker_set.rst b/docs/api/methods/set_chat_sticker_set.rst index eccd0da3..f42c7b2e 100644 --- a/docs/api/methods/set_chat_sticker_set.rst +++ b/docs/api/methods/set_chat_sticker_set.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_chat_title.rst b/docs/api/methods/set_chat_title.rst index ffac0b6e..657283a4 100644 --- a/docs/api/methods/set_chat_title.rst +++ b/docs/api/methods/set_chat_title.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_custom_emoji_sticker_set_thumbnail.rst b/docs/api/methods/set_custom_emoji_sticker_set_thumbnail.rst index 093e30c9..16cce30f 100644 --- a/docs/api/methods/set_custom_emoji_sticker_set_thumbnail.rst +++ b/docs/api/methods/set_custom_emoji_sticker_set_thumbnail.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_game_score.rst b/docs/api/methods/set_game_score.rst index ef484655..6a227095 100644 --- a/docs/api/methods/set_game_score.rst +++ b/docs/api/methods/set_game_score.rst @@ -8,6 +8,7 @@ Returns: :obj:`Union[Message, bool]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_my_commands.rst b/docs/api/methods/set_my_commands.rst index 191f30e1..b8491102 100644 --- a/docs/api/methods/set_my_commands.rst +++ b/docs/api/methods/set_my_commands.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_my_default_administrator_rights.rst b/docs/api/methods/set_my_default_administrator_rights.rst index 1caabdfd..db381aea 100644 --- a/docs/api/methods/set_my_default_administrator_rights.rst +++ b/docs/api/methods/set_my_default_administrator_rights.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_my_description.rst b/docs/api/methods/set_my_description.rst index 126199ee..a3032799 100644 --- a/docs/api/methods/set_my_description.rst +++ b/docs/api/methods/set_my_description.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_my_name.rst b/docs/api/methods/set_my_name.rst new file mode 100644 index 00000000..2a536ff4 --- /dev/null +++ b/docs/api/methods/set_my_name.rst @@ -0,0 +1,45 @@ +######### +setMyName +######### + +Returns: :obj:`bool` + +.. automodule:: aiogram.methods.set_my_name + :members: + :member-order: bysource + :undoc-members: True + :exclude-members: model_config,model_fields + + +Usage +===== + +As bot method +------------- + +.. code-block:: + + result: bool = await bot.set_my_name(...) + + +Method as object +---------------- + +Imports: + +- :code:`from aiogram.methods.set_my_name import SetMyName` +- alias: :code:`from aiogram.methods import SetMyName` + +With specific bot +~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + result: bool = await bot(SetMyName(...)) + +As reply into Webhook in handler +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + return SetMyName(...) diff --git a/docs/api/methods/set_my_short_description.rst b/docs/api/methods/set_my_short_description.rst index f7f250d7..e2bf6f7a 100644 --- a/docs/api/methods/set_my_short_description.rst +++ b/docs/api/methods/set_my_short_description.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_passport_data_errors.rst b/docs/api/methods/set_passport_data_errors.rst index ac49f78c..b05fe1b2 100644 --- a/docs/api/methods/set_passport_data_errors.rst +++ b/docs/api/methods/set_passport_data_errors.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_sticker_emoji_list.rst b/docs/api/methods/set_sticker_emoji_list.rst index c8602f0f..5856fbc5 100644 --- a/docs/api/methods/set_sticker_emoji_list.rst +++ b/docs/api/methods/set_sticker_emoji_list.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_sticker_keywords.rst b/docs/api/methods/set_sticker_keywords.rst index d15c11ac..5e263d39 100644 --- a/docs/api/methods/set_sticker_keywords.rst +++ b/docs/api/methods/set_sticker_keywords.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_sticker_mask_position.rst b/docs/api/methods/set_sticker_mask_position.rst index 48041877..dc0d0eb9 100644 --- a/docs/api/methods/set_sticker_mask_position.rst +++ b/docs/api/methods/set_sticker_mask_position.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_sticker_position_in_set.rst b/docs/api/methods/set_sticker_position_in_set.rst index 04a8a9cf..82915f41 100644 --- a/docs/api/methods/set_sticker_position_in_set.rst +++ b/docs/api/methods/set_sticker_position_in_set.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_sticker_set_thumbnail.rst b/docs/api/methods/set_sticker_set_thumbnail.rst index 218c1012..3a72fab0 100644 --- a/docs/api/methods/set_sticker_set_thumbnail.rst +++ b/docs/api/methods/set_sticker_set_thumbnail.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_sticker_set_title.rst b/docs/api/methods/set_sticker_set_title.rst index f6924dd4..74d487b2 100644 --- a/docs/api/methods/set_sticker_set_title.rst +++ b/docs/api/methods/set_sticker_set_title.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/set_webhook.rst b/docs/api/methods/set_webhook.rst index 8e7d78d5..52def7c0 100644 --- a/docs/api/methods/set_webhook.rst +++ b/docs/api/methods/set_webhook.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/stop_message_live_location.rst b/docs/api/methods/stop_message_live_location.rst index 74f105d1..568d41cc 100644 --- a/docs/api/methods/stop_message_live_location.rst +++ b/docs/api/methods/stop_message_live_location.rst @@ -8,6 +8,7 @@ Returns: :obj:`Union[Message, bool]` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/stop_poll.rst b/docs/api/methods/stop_poll.rst index c51afc90..83c14574 100644 --- a/docs/api/methods/stop_poll.rst +++ b/docs/api/methods/stop_poll.rst @@ -8,6 +8,7 @@ Returns: :obj:`Poll` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/unban_chat_member.rst b/docs/api/methods/unban_chat_member.rst index 0b588b70..4b76a602 100644 --- a/docs/api/methods/unban_chat_member.rst +++ b/docs/api/methods/unban_chat_member.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/unban_chat_sender_chat.rst b/docs/api/methods/unban_chat_sender_chat.rst index 1fdfd5a3..88b00b90 100644 --- a/docs/api/methods/unban_chat_sender_chat.rst +++ b/docs/api/methods/unban_chat_sender_chat.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/unhide_general_forum_topic.rst b/docs/api/methods/unhide_general_forum_topic.rst index e2601df8..6e6be61b 100644 --- a/docs/api/methods/unhide_general_forum_topic.rst +++ b/docs/api/methods/unhide_general_forum_topic.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/unpin_all_chat_messages.rst b/docs/api/methods/unpin_all_chat_messages.rst index 854091e5..571be7f0 100644 --- a/docs/api/methods/unpin_all_chat_messages.rst +++ b/docs/api/methods/unpin_all_chat_messages.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/unpin_all_forum_topic_messages.rst b/docs/api/methods/unpin_all_forum_topic_messages.rst index 7ae521f4..60b03070 100644 --- a/docs/api/methods/unpin_all_forum_topic_messages.rst +++ b/docs/api/methods/unpin_all_forum_topic_messages.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/unpin_chat_message.rst b/docs/api/methods/unpin_chat_message.rst index 9a03c08b..003c83b8 100644 --- a/docs/api/methods/unpin_chat_message.rst +++ b/docs/api/methods/unpin_chat_message.rst @@ -8,6 +8,7 @@ Returns: :obj:`bool` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/methods/upload_sticker_file.rst b/docs/api/methods/upload_sticker_file.rst index c542515d..88cc8859 100644 --- a/docs/api/methods/upload_sticker_file.rst +++ b/docs/api/methods/upload_sticker_file.rst @@ -8,6 +8,7 @@ Returns: :obj:`File` :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields Usage diff --git a/docs/api/types/animation.rst b/docs/api/types/animation.rst index 1d111c20..ee4f4875 100644 --- a/docs/api/types/animation.rst +++ b/docs/api/types/animation.rst @@ -7,3 +7,4 @@ Animation :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/audio.rst b/docs/api/types/audio.rst index e29b246c..a4f5a42a 100644 --- a/docs/api/types/audio.rst +++ b/docs/api/types/audio.rst @@ -7,3 +7,4 @@ Audio :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_command.rst b/docs/api/types/bot_command.rst index 4b8c60ab..5b3307c8 100644 --- a/docs/api/types/bot_command.rst +++ b/docs/api/types/bot_command.rst @@ -7,3 +7,4 @@ BotCommand :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_command_scope.rst b/docs/api/types/bot_command_scope.rst index fa89f3ab..82c404c6 100644 --- a/docs/api/types/bot_command_scope.rst +++ b/docs/api/types/bot_command_scope.rst @@ -7,3 +7,4 @@ BotCommandScope :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_command_scope_all_chat_administrators.rst b/docs/api/types/bot_command_scope_all_chat_administrators.rst index cfde1f73..46110136 100644 --- a/docs/api/types/bot_command_scope_all_chat_administrators.rst +++ b/docs/api/types/bot_command_scope_all_chat_administrators.rst @@ -7,3 +7,4 @@ BotCommandScopeAllChatAdministrators :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_command_scope_all_group_chats.rst b/docs/api/types/bot_command_scope_all_group_chats.rst index 2fe3ec7a..e191c5db 100644 --- a/docs/api/types/bot_command_scope_all_group_chats.rst +++ b/docs/api/types/bot_command_scope_all_group_chats.rst @@ -7,3 +7,4 @@ BotCommandScopeAllGroupChats :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_command_scope_all_private_chats.rst b/docs/api/types/bot_command_scope_all_private_chats.rst index 4c018322..41cf2ff2 100644 --- a/docs/api/types/bot_command_scope_all_private_chats.rst +++ b/docs/api/types/bot_command_scope_all_private_chats.rst @@ -7,3 +7,4 @@ BotCommandScopeAllPrivateChats :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_command_scope_chat.rst b/docs/api/types/bot_command_scope_chat.rst index ee7900fc..4f098f9e 100644 --- a/docs/api/types/bot_command_scope_chat.rst +++ b/docs/api/types/bot_command_scope_chat.rst @@ -7,3 +7,4 @@ BotCommandScopeChat :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_command_scope_chat_administrators.rst b/docs/api/types/bot_command_scope_chat_administrators.rst index 76e72c45..b3cd9aa7 100644 --- a/docs/api/types/bot_command_scope_chat_administrators.rst +++ b/docs/api/types/bot_command_scope_chat_administrators.rst @@ -7,3 +7,4 @@ BotCommandScopeChatAdministrators :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_command_scope_chat_member.rst b/docs/api/types/bot_command_scope_chat_member.rst index 60a76fa1..4e953111 100644 --- a/docs/api/types/bot_command_scope_chat_member.rst +++ b/docs/api/types/bot_command_scope_chat_member.rst @@ -7,3 +7,4 @@ BotCommandScopeChatMember :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_command_scope_default.rst b/docs/api/types/bot_command_scope_default.rst index fe97331b..9a45c243 100644 --- a/docs/api/types/bot_command_scope_default.rst +++ b/docs/api/types/bot_command_scope_default.rst @@ -7,3 +7,4 @@ BotCommandScopeDefault :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_description.rst b/docs/api/types/bot_description.rst index f3ea6d7a..16409cf3 100644 --- a/docs/api/types/bot_description.rst +++ b/docs/api/types/bot_description.rst @@ -7,3 +7,4 @@ BotDescription :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_name.rst b/docs/api/types/bot_name.rst new file mode 100644 index 00000000..2eb8fbf4 --- /dev/null +++ b/docs/api/types/bot_name.rst @@ -0,0 +1,10 @@ +####### +BotName +####### + + +.. automodule:: aiogram.types.bot_name + :members: + :member-order: bysource + :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/bot_short_description.rst b/docs/api/types/bot_short_description.rst index e9812e64..61dbbaea 100644 --- a/docs/api/types/bot_short_description.rst +++ b/docs/api/types/bot_short_description.rst @@ -7,3 +7,4 @@ BotShortDescription :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/callback_game.rst b/docs/api/types/callback_game.rst index 789519f3..8e5f32f1 100644 --- a/docs/api/types/callback_game.rst +++ b/docs/api/types/callback_game.rst @@ -7,3 +7,4 @@ CallbackGame :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/callback_query.rst b/docs/api/types/callback_query.rst index 22ddc99b..dee49c20 100644 --- a/docs/api/types/callback_query.rst +++ b/docs/api/types/callback_query.rst @@ -7,3 +7,4 @@ CallbackQuery :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat.rst b/docs/api/types/chat.rst index 5b506b1b..e473f6be 100644 --- a/docs/api/types/chat.rst +++ b/docs/api/types/chat.rst @@ -7,3 +7,4 @@ Chat :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_administrator_rights.rst b/docs/api/types/chat_administrator_rights.rst index ef86eede..c728cc83 100644 --- a/docs/api/types/chat_administrator_rights.rst +++ b/docs/api/types/chat_administrator_rights.rst @@ -7,3 +7,4 @@ ChatAdministratorRights :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_invite_link.rst b/docs/api/types/chat_invite_link.rst index d64e28ae..3ee3f9ea 100644 --- a/docs/api/types/chat_invite_link.rst +++ b/docs/api/types/chat_invite_link.rst @@ -7,3 +7,4 @@ ChatInviteLink :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_join_request.rst b/docs/api/types/chat_join_request.rst index 236a472a..3ff695a8 100644 --- a/docs/api/types/chat_join_request.rst +++ b/docs/api/types/chat_join_request.rst @@ -7,3 +7,4 @@ ChatJoinRequest :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_location.rst b/docs/api/types/chat_location.rst index 5d528095..74dff084 100644 --- a/docs/api/types/chat_location.rst +++ b/docs/api/types/chat_location.rst @@ -7,3 +7,4 @@ ChatLocation :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_member.rst b/docs/api/types/chat_member.rst index bd357f7c..7cf71744 100644 --- a/docs/api/types/chat_member.rst +++ b/docs/api/types/chat_member.rst @@ -7,3 +7,4 @@ ChatMember :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_member_administrator.rst b/docs/api/types/chat_member_administrator.rst index 55302054..f8c98c7b 100644 --- a/docs/api/types/chat_member_administrator.rst +++ b/docs/api/types/chat_member_administrator.rst @@ -7,3 +7,4 @@ ChatMemberAdministrator :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_member_banned.rst b/docs/api/types/chat_member_banned.rst index 31570bec..95085cfc 100644 --- a/docs/api/types/chat_member_banned.rst +++ b/docs/api/types/chat_member_banned.rst @@ -7,3 +7,4 @@ ChatMemberBanned :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_member_left.rst b/docs/api/types/chat_member_left.rst index 52a4dd9d..6f6d7e0d 100644 --- a/docs/api/types/chat_member_left.rst +++ b/docs/api/types/chat_member_left.rst @@ -7,3 +7,4 @@ ChatMemberLeft :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_member_member.rst b/docs/api/types/chat_member_member.rst index 8f884af9..ec014bd2 100644 --- a/docs/api/types/chat_member_member.rst +++ b/docs/api/types/chat_member_member.rst @@ -7,3 +7,4 @@ ChatMemberMember :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_member_owner.rst b/docs/api/types/chat_member_owner.rst index 09eee65c..3319823b 100644 --- a/docs/api/types/chat_member_owner.rst +++ b/docs/api/types/chat_member_owner.rst @@ -7,3 +7,4 @@ ChatMemberOwner :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_member_restricted.rst b/docs/api/types/chat_member_restricted.rst index dcc3db58..65fdffa5 100644 --- a/docs/api/types/chat_member_restricted.rst +++ b/docs/api/types/chat_member_restricted.rst @@ -7,3 +7,4 @@ ChatMemberRestricted :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_member_updated.rst b/docs/api/types/chat_member_updated.rst index e02ddd8b..f1ae6dd8 100644 --- a/docs/api/types/chat_member_updated.rst +++ b/docs/api/types/chat_member_updated.rst @@ -7,3 +7,4 @@ ChatMemberUpdated :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_permissions.rst b/docs/api/types/chat_permissions.rst index 6eedb23b..934eb1c5 100644 --- a/docs/api/types/chat_permissions.rst +++ b/docs/api/types/chat_permissions.rst @@ -7,3 +7,4 @@ ChatPermissions :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_photo.rst b/docs/api/types/chat_photo.rst index 7821d5ba..e1284cc1 100644 --- a/docs/api/types/chat_photo.rst +++ b/docs/api/types/chat_photo.rst @@ -7,3 +7,4 @@ ChatPhoto :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chat_shared.rst b/docs/api/types/chat_shared.rst index fe6c4c4a..c180f114 100644 --- a/docs/api/types/chat_shared.rst +++ b/docs/api/types/chat_shared.rst @@ -7,3 +7,4 @@ ChatShared :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/chosen_inline_result.rst b/docs/api/types/chosen_inline_result.rst index 3f86a983..0519b88a 100644 --- a/docs/api/types/chosen_inline_result.rst +++ b/docs/api/types/chosen_inline_result.rst @@ -7,3 +7,4 @@ ChosenInlineResult :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/contact.rst b/docs/api/types/contact.rst index f99e1d27..152a6efc 100644 --- a/docs/api/types/contact.rst +++ b/docs/api/types/contact.rst @@ -7,3 +7,4 @@ Contact :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/dice.rst b/docs/api/types/dice.rst index 41ddf6c4..ba6309f4 100644 --- a/docs/api/types/dice.rst +++ b/docs/api/types/dice.rst @@ -7,3 +7,4 @@ Dice :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/document.rst b/docs/api/types/document.rst index 48799778..1d9a34d7 100644 --- a/docs/api/types/document.rst +++ b/docs/api/types/document.rst @@ -7,3 +7,4 @@ Document :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/encrypted_credentials.rst b/docs/api/types/encrypted_credentials.rst index 41425c95..7bce1366 100644 --- a/docs/api/types/encrypted_credentials.rst +++ b/docs/api/types/encrypted_credentials.rst @@ -7,3 +7,4 @@ EncryptedCredentials :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/encrypted_passport_element.rst b/docs/api/types/encrypted_passport_element.rst index 0acf7a8e..b5634dc5 100644 --- a/docs/api/types/encrypted_passport_element.rst +++ b/docs/api/types/encrypted_passport_element.rst @@ -7,3 +7,4 @@ EncryptedPassportElement :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/error_event.rst b/docs/api/types/error_event.rst index 77fae204..562ea15b 100644 --- a/docs/api/types/error_event.rst +++ b/docs/api/types/error_event.rst @@ -7,3 +7,4 @@ ErrorEvent :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/file.rst b/docs/api/types/file.rst index 5a9d920e..ab525e80 100644 --- a/docs/api/types/file.rst +++ b/docs/api/types/file.rst @@ -7,3 +7,4 @@ File :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/force_reply.rst b/docs/api/types/force_reply.rst index 326cd91f..a5f5d93c 100644 --- a/docs/api/types/force_reply.rst +++ b/docs/api/types/force_reply.rst @@ -7,3 +7,4 @@ ForceReply :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/forum_topic.rst b/docs/api/types/forum_topic.rst index fa5e99a6..ee38ae7b 100644 --- a/docs/api/types/forum_topic.rst +++ b/docs/api/types/forum_topic.rst @@ -7,3 +7,4 @@ ForumTopic :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/forum_topic_closed.rst b/docs/api/types/forum_topic_closed.rst index 200b19a5..97e8afde 100644 --- a/docs/api/types/forum_topic_closed.rst +++ b/docs/api/types/forum_topic_closed.rst @@ -7,3 +7,4 @@ ForumTopicClosed :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/forum_topic_created.rst b/docs/api/types/forum_topic_created.rst index 5eeb2382..63fc4a8f 100644 --- a/docs/api/types/forum_topic_created.rst +++ b/docs/api/types/forum_topic_created.rst @@ -7,3 +7,4 @@ ForumTopicCreated :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/forum_topic_edited.rst b/docs/api/types/forum_topic_edited.rst index 6909332f..d3d41960 100644 --- a/docs/api/types/forum_topic_edited.rst +++ b/docs/api/types/forum_topic_edited.rst @@ -7,3 +7,4 @@ ForumTopicEdited :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/forum_topic_reopened.rst b/docs/api/types/forum_topic_reopened.rst index 8803cf1f..a14b3877 100644 --- a/docs/api/types/forum_topic_reopened.rst +++ b/docs/api/types/forum_topic_reopened.rst @@ -7,3 +7,4 @@ ForumTopicReopened :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/game.rst b/docs/api/types/game.rst index 62a7f390..8ee3f03d 100644 --- a/docs/api/types/game.rst +++ b/docs/api/types/game.rst @@ -7,3 +7,4 @@ Game :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/game_high_score.rst b/docs/api/types/game_high_score.rst index 6f8d8194..64a2a751 100644 --- a/docs/api/types/game_high_score.rst +++ b/docs/api/types/game_high_score.rst @@ -7,3 +7,4 @@ GameHighScore :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/general_forum_topic_hidden.rst b/docs/api/types/general_forum_topic_hidden.rst index f83b143a..032d190a 100644 --- a/docs/api/types/general_forum_topic_hidden.rst +++ b/docs/api/types/general_forum_topic_hidden.rst @@ -7,3 +7,4 @@ GeneralForumTopicHidden :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/general_forum_topic_unhidden.rst b/docs/api/types/general_forum_topic_unhidden.rst index 9dee46cb..55764d2c 100644 --- a/docs/api/types/general_forum_topic_unhidden.rst +++ b/docs/api/types/general_forum_topic_unhidden.rst @@ -7,3 +7,4 @@ GeneralForumTopicUnhidden :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/index.rst b/docs/api/types/index.rst index 304eae6b..930e9354 100644 --- a/docs/api/types/index.rst +++ b/docs/api/types/index.rst @@ -34,6 +34,7 @@ Inline mode inline_query_result_venue inline_query_result_video inline_query_result_voice + inline_query_results_button input_contact_message_content input_invoice_message_content input_location_message_content @@ -60,6 +61,7 @@ Available types bot_command_scope_chat_member bot_command_scope_default bot_description + bot_name bot_short_description callback_query chat @@ -121,6 +123,7 @@ Available types reply_keyboard_markup reply_keyboard_remove response_parameters + switch_inline_query_chosen_chat user user_profile_photos user_shared diff --git a/docs/api/types/inline_keyboard_button.rst b/docs/api/types/inline_keyboard_button.rst index 1075ad01..43ca6325 100644 --- a/docs/api/types/inline_keyboard_button.rst +++ b/docs/api/types/inline_keyboard_button.rst @@ -7,3 +7,4 @@ InlineKeyboardButton :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_keyboard_markup.rst b/docs/api/types/inline_keyboard_markup.rst index b7c5108f..ff47ff06 100644 --- a/docs/api/types/inline_keyboard_markup.rst +++ b/docs/api/types/inline_keyboard_markup.rst @@ -7,3 +7,4 @@ InlineKeyboardMarkup :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query.rst b/docs/api/types/inline_query.rst index 7577b29c..437f0880 100644 --- a/docs/api/types/inline_query.rst +++ b/docs/api/types/inline_query.rst @@ -7,3 +7,4 @@ InlineQuery :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result.rst b/docs/api/types/inline_query_result.rst index ba3e265f..0caa7246 100644 --- a/docs/api/types/inline_query_result.rst +++ b/docs/api/types/inline_query_result.rst @@ -7,3 +7,4 @@ InlineQueryResult :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_article.rst b/docs/api/types/inline_query_result_article.rst index 8ffb1db9..59c1c085 100644 --- a/docs/api/types/inline_query_result_article.rst +++ b/docs/api/types/inline_query_result_article.rst @@ -7,3 +7,4 @@ InlineQueryResultArticle :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_audio.rst b/docs/api/types/inline_query_result_audio.rst index 50858460..58d5b640 100644 --- a/docs/api/types/inline_query_result_audio.rst +++ b/docs/api/types/inline_query_result_audio.rst @@ -7,3 +7,4 @@ InlineQueryResultAudio :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_cached_audio.rst b/docs/api/types/inline_query_result_cached_audio.rst index bcce043d..9c9e83dd 100644 --- a/docs/api/types/inline_query_result_cached_audio.rst +++ b/docs/api/types/inline_query_result_cached_audio.rst @@ -7,3 +7,4 @@ InlineQueryResultCachedAudio :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_cached_document.rst b/docs/api/types/inline_query_result_cached_document.rst index 0813734d..d6081dc9 100644 --- a/docs/api/types/inline_query_result_cached_document.rst +++ b/docs/api/types/inline_query_result_cached_document.rst @@ -7,3 +7,4 @@ InlineQueryResultCachedDocument :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_cached_gif.rst b/docs/api/types/inline_query_result_cached_gif.rst index d1103a55..e38a0305 100644 --- a/docs/api/types/inline_query_result_cached_gif.rst +++ b/docs/api/types/inline_query_result_cached_gif.rst @@ -7,3 +7,4 @@ InlineQueryResultCachedGif :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_cached_mpeg4_gif.rst b/docs/api/types/inline_query_result_cached_mpeg4_gif.rst index 022ce1ca..f073b73e 100644 --- a/docs/api/types/inline_query_result_cached_mpeg4_gif.rst +++ b/docs/api/types/inline_query_result_cached_mpeg4_gif.rst @@ -7,3 +7,4 @@ InlineQueryResultCachedMpeg4Gif :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_cached_photo.rst b/docs/api/types/inline_query_result_cached_photo.rst index 3fcd27bc..c75f6d34 100644 --- a/docs/api/types/inline_query_result_cached_photo.rst +++ b/docs/api/types/inline_query_result_cached_photo.rst @@ -7,3 +7,4 @@ InlineQueryResultCachedPhoto :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_cached_sticker.rst b/docs/api/types/inline_query_result_cached_sticker.rst index 30a5d5b3..d0e965a8 100644 --- a/docs/api/types/inline_query_result_cached_sticker.rst +++ b/docs/api/types/inline_query_result_cached_sticker.rst @@ -7,3 +7,4 @@ InlineQueryResultCachedSticker :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_cached_video.rst b/docs/api/types/inline_query_result_cached_video.rst index 0c5acbe9..a7a7b130 100644 --- a/docs/api/types/inline_query_result_cached_video.rst +++ b/docs/api/types/inline_query_result_cached_video.rst @@ -7,3 +7,4 @@ InlineQueryResultCachedVideo :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_cached_voice.rst b/docs/api/types/inline_query_result_cached_voice.rst index 5b4f0d8e..95dbe44a 100644 --- a/docs/api/types/inline_query_result_cached_voice.rst +++ b/docs/api/types/inline_query_result_cached_voice.rst @@ -7,3 +7,4 @@ InlineQueryResultCachedVoice :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_contact.rst b/docs/api/types/inline_query_result_contact.rst index 123b4d61..ca3f74bc 100644 --- a/docs/api/types/inline_query_result_contact.rst +++ b/docs/api/types/inline_query_result_contact.rst @@ -7,3 +7,4 @@ InlineQueryResultContact :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_document.rst b/docs/api/types/inline_query_result_document.rst index 6352c6c3..d5e03940 100644 --- a/docs/api/types/inline_query_result_document.rst +++ b/docs/api/types/inline_query_result_document.rst @@ -7,3 +7,4 @@ InlineQueryResultDocument :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_game.rst b/docs/api/types/inline_query_result_game.rst index 562c1974..4f57d322 100644 --- a/docs/api/types/inline_query_result_game.rst +++ b/docs/api/types/inline_query_result_game.rst @@ -7,3 +7,4 @@ InlineQueryResultGame :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_gif.rst b/docs/api/types/inline_query_result_gif.rst index 552252de..54628ab6 100644 --- a/docs/api/types/inline_query_result_gif.rst +++ b/docs/api/types/inline_query_result_gif.rst @@ -7,3 +7,4 @@ InlineQueryResultGif :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_location.rst b/docs/api/types/inline_query_result_location.rst index fcde9fb2..7f637827 100644 --- a/docs/api/types/inline_query_result_location.rst +++ b/docs/api/types/inline_query_result_location.rst @@ -7,3 +7,4 @@ InlineQueryResultLocation :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_mpeg4_gif.rst b/docs/api/types/inline_query_result_mpeg4_gif.rst index ccdfb06f..80144e82 100644 --- a/docs/api/types/inline_query_result_mpeg4_gif.rst +++ b/docs/api/types/inline_query_result_mpeg4_gif.rst @@ -7,3 +7,4 @@ InlineQueryResultMpeg4Gif :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_photo.rst b/docs/api/types/inline_query_result_photo.rst index 4af41c8e..e36c6b01 100644 --- a/docs/api/types/inline_query_result_photo.rst +++ b/docs/api/types/inline_query_result_photo.rst @@ -7,3 +7,4 @@ InlineQueryResultPhoto :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_venue.rst b/docs/api/types/inline_query_result_venue.rst index b3c40c01..ea0b5331 100644 --- a/docs/api/types/inline_query_result_venue.rst +++ b/docs/api/types/inline_query_result_venue.rst @@ -7,3 +7,4 @@ InlineQueryResultVenue :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_video.rst b/docs/api/types/inline_query_result_video.rst index e27f6be3..b767f746 100644 --- a/docs/api/types/inline_query_result_video.rst +++ b/docs/api/types/inline_query_result_video.rst @@ -7,3 +7,4 @@ InlineQueryResultVideo :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_result_voice.rst b/docs/api/types/inline_query_result_voice.rst index 4496c4fe..fc648e0a 100644 --- a/docs/api/types/inline_query_result_voice.rst +++ b/docs/api/types/inline_query_result_voice.rst @@ -7,3 +7,4 @@ InlineQueryResultVoice :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/inline_query_results_button.rst b/docs/api/types/inline_query_results_button.rst new file mode 100644 index 00000000..75903af3 --- /dev/null +++ b/docs/api/types/inline_query_results_button.rst @@ -0,0 +1,10 @@ +######################## +InlineQueryResultsButton +######################## + + +.. automodule:: aiogram.types.inline_query_results_button + :members: + :member-order: bysource + :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_contact_message_content.rst b/docs/api/types/input_contact_message_content.rst index a3100b83..ea3ae3f0 100644 --- a/docs/api/types/input_contact_message_content.rst +++ b/docs/api/types/input_contact_message_content.rst @@ -7,3 +7,4 @@ InputContactMessageContent :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_file.rst b/docs/api/types/input_file.rst index 4197e6cd..1cb8fa16 100644 --- a/docs/api/types/input_file.rst +++ b/docs/api/types/input_file.rst @@ -7,3 +7,4 @@ InputFile :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_invoice_message_content.rst b/docs/api/types/input_invoice_message_content.rst index f5d7a0ab..f08e8fff 100644 --- a/docs/api/types/input_invoice_message_content.rst +++ b/docs/api/types/input_invoice_message_content.rst @@ -7,3 +7,4 @@ InputInvoiceMessageContent :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_location_message_content.rst b/docs/api/types/input_location_message_content.rst index 6ca59b0b..8c79a76c 100644 --- a/docs/api/types/input_location_message_content.rst +++ b/docs/api/types/input_location_message_content.rst @@ -7,3 +7,4 @@ InputLocationMessageContent :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_media.rst b/docs/api/types/input_media.rst index 9b3f386b..f2bbb471 100644 --- a/docs/api/types/input_media.rst +++ b/docs/api/types/input_media.rst @@ -7,3 +7,4 @@ InputMedia :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_media_animation.rst b/docs/api/types/input_media_animation.rst index 9c00494b..eb6b2754 100644 --- a/docs/api/types/input_media_animation.rst +++ b/docs/api/types/input_media_animation.rst @@ -7,3 +7,4 @@ InputMediaAnimation :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_media_audio.rst b/docs/api/types/input_media_audio.rst index c12d307c..f44b52c7 100644 --- a/docs/api/types/input_media_audio.rst +++ b/docs/api/types/input_media_audio.rst @@ -7,3 +7,4 @@ InputMediaAudio :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_media_document.rst b/docs/api/types/input_media_document.rst index 645b78e7..4dc1eca0 100644 --- a/docs/api/types/input_media_document.rst +++ b/docs/api/types/input_media_document.rst @@ -7,3 +7,4 @@ InputMediaDocument :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_media_photo.rst b/docs/api/types/input_media_photo.rst index 32656e29..d78d91ef 100644 --- a/docs/api/types/input_media_photo.rst +++ b/docs/api/types/input_media_photo.rst @@ -7,3 +7,4 @@ InputMediaPhoto :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_media_video.rst b/docs/api/types/input_media_video.rst index 57099c51..c6b84be0 100644 --- a/docs/api/types/input_media_video.rst +++ b/docs/api/types/input_media_video.rst @@ -7,3 +7,4 @@ InputMediaVideo :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_message_content.rst b/docs/api/types/input_message_content.rst index 84040fb7..c79c4c6c 100644 --- a/docs/api/types/input_message_content.rst +++ b/docs/api/types/input_message_content.rst @@ -7,3 +7,4 @@ InputMessageContent :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_sticker.rst b/docs/api/types/input_sticker.rst index 176a0e15..e235697d 100644 --- a/docs/api/types/input_sticker.rst +++ b/docs/api/types/input_sticker.rst @@ -7,3 +7,4 @@ InputSticker :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_text_message_content.rst b/docs/api/types/input_text_message_content.rst index 1eb83e54..b019fb5d 100644 --- a/docs/api/types/input_text_message_content.rst +++ b/docs/api/types/input_text_message_content.rst @@ -7,3 +7,4 @@ InputTextMessageContent :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/input_venue_message_content.rst b/docs/api/types/input_venue_message_content.rst index 479a99a0..6288d78a 100644 --- a/docs/api/types/input_venue_message_content.rst +++ b/docs/api/types/input_venue_message_content.rst @@ -7,3 +7,4 @@ InputVenueMessageContent :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/invoice.rst b/docs/api/types/invoice.rst index 24ecc961..e5582e52 100644 --- a/docs/api/types/invoice.rst +++ b/docs/api/types/invoice.rst @@ -7,3 +7,4 @@ Invoice :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/keyboard_button.rst b/docs/api/types/keyboard_button.rst index 9faca06d..b67d22fa 100644 --- a/docs/api/types/keyboard_button.rst +++ b/docs/api/types/keyboard_button.rst @@ -7,3 +7,4 @@ KeyboardButton :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/keyboard_button_poll_type.rst b/docs/api/types/keyboard_button_poll_type.rst index 9a4974a5..c15f6e1f 100644 --- a/docs/api/types/keyboard_button_poll_type.rst +++ b/docs/api/types/keyboard_button_poll_type.rst @@ -7,3 +7,4 @@ KeyboardButtonPollType :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/keyboard_button_request_chat.rst b/docs/api/types/keyboard_button_request_chat.rst index b47f1a8b..083bbd55 100644 --- a/docs/api/types/keyboard_button_request_chat.rst +++ b/docs/api/types/keyboard_button_request_chat.rst @@ -7,3 +7,4 @@ KeyboardButtonRequestChat :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/keyboard_button_request_user.rst b/docs/api/types/keyboard_button_request_user.rst index f216668a..fe5be538 100644 --- a/docs/api/types/keyboard_button_request_user.rst +++ b/docs/api/types/keyboard_button_request_user.rst @@ -7,3 +7,4 @@ KeyboardButtonRequestUser :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/labeled_price.rst b/docs/api/types/labeled_price.rst index a76b28f3..da5ccabb 100644 --- a/docs/api/types/labeled_price.rst +++ b/docs/api/types/labeled_price.rst @@ -7,3 +7,4 @@ LabeledPrice :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/location.rst b/docs/api/types/location.rst index 2957683a..e6fa6bf0 100644 --- a/docs/api/types/location.rst +++ b/docs/api/types/location.rst @@ -7,3 +7,4 @@ Location :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/login_url.rst b/docs/api/types/login_url.rst index f72b28b6..3caae33d 100644 --- a/docs/api/types/login_url.rst +++ b/docs/api/types/login_url.rst @@ -7,3 +7,4 @@ LoginUrl :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/mask_position.rst b/docs/api/types/mask_position.rst index 74c28494..d53f7598 100644 --- a/docs/api/types/mask_position.rst +++ b/docs/api/types/mask_position.rst @@ -7,3 +7,4 @@ MaskPosition :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/menu_button.rst b/docs/api/types/menu_button.rst index 44eeb4c3..a1ab0d8b 100644 --- a/docs/api/types/menu_button.rst +++ b/docs/api/types/menu_button.rst @@ -7,3 +7,4 @@ MenuButton :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/menu_button_commands.rst b/docs/api/types/menu_button_commands.rst index 66614b04..f5662136 100644 --- a/docs/api/types/menu_button_commands.rst +++ b/docs/api/types/menu_button_commands.rst @@ -7,3 +7,4 @@ MenuButtonCommands :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/menu_button_default.rst b/docs/api/types/menu_button_default.rst index f114387c..6594f436 100644 --- a/docs/api/types/menu_button_default.rst +++ b/docs/api/types/menu_button_default.rst @@ -7,3 +7,4 @@ MenuButtonDefault :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/menu_button_web_app.rst b/docs/api/types/menu_button_web_app.rst index bf5c0806..f65948fd 100644 --- a/docs/api/types/menu_button_web_app.rst +++ b/docs/api/types/menu_button_web_app.rst @@ -7,3 +7,4 @@ MenuButtonWebApp :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/message.rst b/docs/api/types/message.rst index 5e1be4f7..90ce74ca 100644 --- a/docs/api/types/message.rst +++ b/docs/api/types/message.rst @@ -7,3 +7,4 @@ Message :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/message_auto_delete_timer_changed.rst b/docs/api/types/message_auto_delete_timer_changed.rst index 102caacc..80d3f7db 100644 --- a/docs/api/types/message_auto_delete_timer_changed.rst +++ b/docs/api/types/message_auto_delete_timer_changed.rst @@ -7,3 +7,4 @@ MessageAutoDeleteTimerChanged :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/message_entity.rst b/docs/api/types/message_entity.rst index 38ee737d..15d9e15c 100644 --- a/docs/api/types/message_entity.rst +++ b/docs/api/types/message_entity.rst @@ -7,3 +7,4 @@ MessageEntity :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/message_id.rst b/docs/api/types/message_id.rst index 2ed2adc6..55f15959 100644 --- a/docs/api/types/message_id.rst +++ b/docs/api/types/message_id.rst @@ -7,3 +7,4 @@ MessageId :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/order_info.rst b/docs/api/types/order_info.rst index 6180f709..5529a607 100644 --- a/docs/api/types/order_info.rst +++ b/docs/api/types/order_info.rst @@ -7,3 +7,4 @@ OrderInfo :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_data.rst b/docs/api/types/passport_data.rst index 9a3de684..eea326bb 100644 --- a/docs/api/types/passport_data.rst +++ b/docs/api/types/passport_data.rst @@ -7,3 +7,4 @@ PassportData :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_element_error.rst b/docs/api/types/passport_element_error.rst index 8fc30e86..24e16dd0 100644 --- a/docs/api/types/passport_element_error.rst +++ b/docs/api/types/passport_element_error.rst @@ -7,3 +7,4 @@ PassportElementError :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_element_error_data_field.rst b/docs/api/types/passport_element_error_data_field.rst index b9382471..08e75bc1 100644 --- a/docs/api/types/passport_element_error_data_field.rst +++ b/docs/api/types/passport_element_error_data_field.rst @@ -7,3 +7,4 @@ PassportElementErrorDataField :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_element_error_file.rst b/docs/api/types/passport_element_error_file.rst index 877def6a..7d209266 100644 --- a/docs/api/types/passport_element_error_file.rst +++ b/docs/api/types/passport_element_error_file.rst @@ -7,3 +7,4 @@ PassportElementErrorFile :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_element_error_files.rst b/docs/api/types/passport_element_error_files.rst index 922b4ffb..9d9f5585 100644 --- a/docs/api/types/passport_element_error_files.rst +++ b/docs/api/types/passport_element_error_files.rst @@ -7,3 +7,4 @@ PassportElementErrorFiles :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_element_error_front_side.rst b/docs/api/types/passport_element_error_front_side.rst index 3f7dfe81..c72e9b87 100644 --- a/docs/api/types/passport_element_error_front_side.rst +++ b/docs/api/types/passport_element_error_front_side.rst @@ -7,3 +7,4 @@ PassportElementErrorFrontSide :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_element_error_reverse_side.rst b/docs/api/types/passport_element_error_reverse_side.rst index dd61c9a1..a9147a70 100644 --- a/docs/api/types/passport_element_error_reverse_side.rst +++ b/docs/api/types/passport_element_error_reverse_side.rst @@ -7,3 +7,4 @@ PassportElementErrorReverseSide :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_element_error_selfie.rst b/docs/api/types/passport_element_error_selfie.rst index d3463191..ed452899 100644 --- a/docs/api/types/passport_element_error_selfie.rst +++ b/docs/api/types/passport_element_error_selfie.rst @@ -7,3 +7,4 @@ PassportElementErrorSelfie :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_element_error_translation_file.rst b/docs/api/types/passport_element_error_translation_file.rst index 3a0e16aa..68e3417b 100644 --- a/docs/api/types/passport_element_error_translation_file.rst +++ b/docs/api/types/passport_element_error_translation_file.rst @@ -7,3 +7,4 @@ PassportElementErrorTranslationFile :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_element_error_translation_files.rst b/docs/api/types/passport_element_error_translation_files.rst index 9ac03422..5102b071 100644 --- a/docs/api/types/passport_element_error_translation_files.rst +++ b/docs/api/types/passport_element_error_translation_files.rst @@ -7,3 +7,4 @@ PassportElementErrorTranslationFiles :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_element_error_unspecified.rst b/docs/api/types/passport_element_error_unspecified.rst index ec90bed9..6510d51e 100644 --- a/docs/api/types/passport_element_error_unspecified.rst +++ b/docs/api/types/passport_element_error_unspecified.rst @@ -7,3 +7,4 @@ PassportElementErrorUnspecified :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/passport_file.rst b/docs/api/types/passport_file.rst index 4c737fff..1a2dcd56 100644 --- a/docs/api/types/passport_file.rst +++ b/docs/api/types/passport_file.rst @@ -7,3 +7,4 @@ PassportFile :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/photo_size.rst b/docs/api/types/photo_size.rst index 1086588c..3605b912 100644 --- a/docs/api/types/photo_size.rst +++ b/docs/api/types/photo_size.rst @@ -7,3 +7,4 @@ PhotoSize :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/poll.rst b/docs/api/types/poll.rst index fd11bc88..294b323b 100644 --- a/docs/api/types/poll.rst +++ b/docs/api/types/poll.rst @@ -7,3 +7,4 @@ Poll :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/poll_answer.rst b/docs/api/types/poll_answer.rst index fe92fb6a..680cc75e 100644 --- a/docs/api/types/poll_answer.rst +++ b/docs/api/types/poll_answer.rst @@ -7,3 +7,4 @@ PollAnswer :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/poll_option.rst b/docs/api/types/poll_option.rst index 72ebfbd2..b85634e0 100644 --- a/docs/api/types/poll_option.rst +++ b/docs/api/types/poll_option.rst @@ -7,3 +7,4 @@ PollOption :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/pre_checkout_query.rst b/docs/api/types/pre_checkout_query.rst index 418c11b9..8f330051 100644 --- a/docs/api/types/pre_checkout_query.rst +++ b/docs/api/types/pre_checkout_query.rst @@ -7,3 +7,4 @@ PreCheckoutQuery :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/proximity_alert_triggered.rst b/docs/api/types/proximity_alert_triggered.rst index 98ac7d2f..16a47c11 100644 --- a/docs/api/types/proximity_alert_triggered.rst +++ b/docs/api/types/proximity_alert_triggered.rst @@ -7,3 +7,4 @@ ProximityAlertTriggered :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/reply_keyboard_markup.rst b/docs/api/types/reply_keyboard_markup.rst index a5c5ae85..01c040ee 100644 --- a/docs/api/types/reply_keyboard_markup.rst +++ b/docs/api/types/reply_keyboard_markup.rst @@ -7,3 +7,4 @@ ReplyKeyboardMarkup :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/reply_keyboard_remove.rst b/docs/api/types/reply_keyboard_remove.rst index 799ad3a9..b54b06f7 100644 --- a/docs/api/types/reply_keyboard_remove.rst +++ b/docs/api/types/reply_keyboard_remove.rst @@ -7,3 +7,4 @@ ReplyKeyboardRemove :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/response_parameters.rst b/docs/api/types/response_parameters.rst index 5b7056b8..31ae0c34 100644 --- a/docs/api/types/response_parameters.rst +++ b/docs/api/types/response_parameters.rst @@ -7,3 +7,4 @@ ResponseParameters :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/sent_web_app_message.rst b/docs/api/types/sent_web_app_message.rst index 1a7d2084..a8563b8d 100644 --- a/docs/api/types/sent_web_app_message.rst +++ b/docs/api/types/sent_web_app_message.rst @@ -7,3 +7,4 @@ SentWebAppMessage :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/shipping_address.rst b/docs/api/types/shipping_address.rst index 0421c58e..6eb704f8 100644 --- a/docs/api/types/shipping_address.rst +++ b/docs/api/types/shipping_address.rst @@ -7,3 +7,4 @@ ShippingAddress :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/shipping_option.rst b/docs/api/types/shipping_option.rst index 28e13897..e5f57874 100644 --- a/docs/api/types/shipping_option.rst +++ b/docs/api/types/shipping_option.rst @@ -7,3 +7,4 @@ ShippingOption :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/shipping_query.rst b/docs/api/types/shipping_query.rst index c4ccdf70..761a2f52 100644 --- a/docs/api/types/shipping_query.rst +++ b/docs/api/types/shipping_query.rst @@ -7,3 +7,4 @@ ShippingQuery :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/sticker.rst b/docs/api/types/sticker.rst index f15dd9ef..3f69a389 100644 --- a/docs/api/types/sticker.rst +++ b/docs/api/types/sticker.rst @@ -7,3 +7,4 @@ Sticker :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/sticker_set.rst b/docs/api/types/sticker_set.rst index a25e064f..9f50ef1d 100644 --- a/docs/api/types/sticker_set.rst +++ b/docs/api/types/sticker_set.rst @@ -7,3 +7,4 @@ StickerSet :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/successful_payment.rst b/docs/api/types/successful_payment.rst index f21f860b..ed882b60 100644 --- a/docs/api/types/successful_payment.rst +++ b/docs/api/types/successful_payment.rst @@ -7,3 +7,4 @@ SuccessfulPayment :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/switch_inline_query_chosen_chat.rst b/docs/api/types/switch_inline_query_chosen_chat.rst new file mode 100644 index 00000000..0934367d --- /dev/null +++ b/docs/api/types/switch_inline_query_chosen_chat.rst @@ -0,0 +1,10 @@ +########################### +SwitchInlineQueryChosenChat +########################### + + +.. automodule:: aiogram.types.switch_inline_query_chosen_chat + :members: + :member-order: bysource + :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/update.rst b/docs/api/types/update.rst index 5419da6e..b789cb3d 100644 --- a/docs/api/types/update.rst +++ b/docs/api/types/update.rst @@ -7,3 +7,4 @@ Update :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/user.rst b/docs/api/types/user.rst index b13f8808..92a0bf32 100644 --- a/docs/api/types/user.rst +++ b/docs/api/types/user.rst @@ -7,3 +7,4 @@ User :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/user_profile_photos.rst b/docs/api/types/user_profile_photos.rst index b6cce934..29bf9a88 100644 --- a/docs/api/types/user_profile_photos.rst +++ b/docs/api/types/user_profile_photos.rst @@ -7,3 +7,4 @@ UserProfilePhotos :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/user_shared.rst b/docs/api/types/user_shared.rst index 55713049..6a485188 100644 --- a/docs/api/types/user_shared.rst +++ b/docs/api/types/user_shared.rst @@ -7,3 +7,4 @@ UserShared :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/venue.rst b/docs/api/types/venue.rst index 75a71fff..1827dd18 100644 --- a/docs/api/types/venue.rst +++ b/docs/api/types/venue.rst @@ -7,3 +7,4 @@ Venue :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/video.rst b/docs/api/types/video.rst index 0478b3f7..a2a2c032 100644 --- a/docs/api/types/video.rst +++ b/docs/api/types/video.rst @@ -7,3 +7,4 @@ Video :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/video_chat_ended.rst b/docs/api/types/video_chat_ended.rst index aed8b7a9..6edfb158 100644 --- a/docs/api/types/video_chat_ended.rst +++ b/docs/api/types/video_chat_ended.rst @@ -7,3 +7,4 @@ VideoChatEnded :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/video_chat_participants_invited.rst b/docs/api/types/video_chat_participants_invited.rst index 9ca905bd..8812311f 100644 --- a/docs/api/types/video_chat_participants_invited.rst +++ b/docs/api/types/video_chat_participants_invited.rst @@ -7,3 +7,4 @@ VideoChatParticipantsInvited :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/video_chat_scheduled.rst b/docs/api/types/video_chat_scheduled.rst index 0d5f8c45..e612af51 100644 --- a/docs/api/types/video_chat_scheduled.rst +++ b/docs/api/types/video_chat_scheduled.rst @@ -7,3 +7,4 @@ VideoChatScheduled :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/video_chat_started.rst b/docs/api/types/video_chat_started.rst index 5d59a22e..a58fb47e 100644 --- a/docs/api/types/video_chat_started.rst +++ b/docs/api/types/video_chat_started.rst @@ -7,3 +7,4 @@ VideoChatStarted :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/video_note.rst b/docs/api/types/video_note.rst index b9d308e5..ad0912a6 100644 --- a/docs/api/types/video_note.rst +++ b/docs/api/types/video_note.rst @@ -7,3 +7,4 @@ VideoNote :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/voice.rst b/docs/api/types/voice.rst index 7d58722d..c963205a 100644 --- a/docs/api/types/voice.rst +++ b/docs/api/types/voice.rst @@ -7,3 +7,4 @@ Voice :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/web_app_data.rst b/docs/api/types/web_app_data.rst index 1a94573f..e4369a88 100644 --- a/docs/api/types/web_app_data.rst +++ b/docs/api/types/web_app_data.rst @@ -7,3 +7,4 @@ WebAppData :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/web_app_info.rst b/docs/api/types/web_app_info.rst index b21f0aea..6ebfad64 100644 --- a/docs/api/types/web_app_info.rst +++ b/docs/api/types/web_app_info.rst @@ -7,3 +7,4 @@ WebAppInfo :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/webhook_info.rst b/docs/api/types/webhook_info.rst index 259a01bc..7194b726 100644 --- a/docs/api/types/webhook_info.rst +++ b/docs/api/types/webhook_info.rst @@ -7,3 +7,4 @@ WebhookInfo :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/types/write_access_allowed.rst b/docs/api/types/write_access_allowed.rst index d2afa3bc..62fa76d6 100644 --- a/docs/api/types/write_access_allowed.rst +++ b/docs/api/types/write_access_allowed.rst @@ -7,3 +7,4 @@ WriteAccessAllowed :members: :member-order: bysource :undoc-members: True + :exclude-members: model_config,model_fields diff --git a/docs/api/upload_file.rst b/docs/api/upload_file.rst index 9399f1dd..715474f7 100644 --- a/docs/api/upload_file.rst +++ b/docs/api/upload_file.rst @@ -10,7 +10,7 @@ there are three ways to send files (photos, stickers, audio, media, etc.): If the file is already stored somewhere on the Telegram servers or file is available by the URL, you don't need to reupload it. -But if you need to upload a new file just use subclasses of `InputFile `__. +But if you need to upload a new file just use subclasses of `InputFile `__. Here are the three different available builtin types of input file: diff --git a/docs/contributing.rst b/docs/contributing.rst index 3feda269..a0a80181 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -209,5 +209,4 @@ it is my personal initiative (`@JRootJunior `_) and I am engaged in the development of the project in my free time. So, if you want to financially support the project, or, for example, give me a pizza or a beer, -you can do it on `OpenCollective `_ -or `Patreon `_. +you can do it on `OpenCollective `_. diff --git a/docs/dispatcher/filters/callback_data.rst b/docs/dispatcher/filters/callback_data.rst index cbf51a79..61d7a40a 100644 --- a/docs/dispatcher/filters/callback_data.rst +++ b/docs/dispatcher/filters/callback_data.rst @@ -8,6 +8,7 @@ Callback Data Factory & Filter :members: :member-order: bysource :undoc-members: False + :exclude-members: model_config,model_fields Usage ===== diff --git a/docs/dispatcher/filters/index.rst b/docs/dispatcher/filters/index.rst index 856b8677..9ac14213 100644 --- a/docs/dispatcher/filters/index.rst +++ b/docs/dispatcher/filters/index.rst @@ -16,7 +16,6 @@ Here is list of builtin filters: :maxdepth: 1 command - text chat_member_updated magic_filters magic_data @@ -69,7 +68,7 @@ If you specify multiple filters in a row, it will be checked with an "and" condi .. code-block:: python - @.message(Text(startswith="show"), Text(endswith="example")) + @.message(F.text.startswith("show"), F.text.endswith("example")) Also, if you want to use two alternative ways to run the same handler ("or" condition) @@ -77,7 +76,7 @@ you can register the handler twice or more times as you like .. code-block:: python - @.message(Text(text="hi")) + @.message(F.text == "hi") @.message(CommandStart()) @@ -96,7 +95,7 @@ An alternative way is to combine using special functions (:func:`and_f`, :func:` .. code-block:: python - and_f(Text(startswith="show"), Text(endswith="example")) - or_f(Text(text="hi"), CommandStart()) + and_f(F.text.startswith("show"), F.text.endswith("example")) + or_f(F.text(text="hi"), CommandStart()) invert_f(IsAdmin()) and_f(, or_f(, )) diff --git a/docs/dispatcher/filters/text.rst b/docs/dispatcher/filters/text.rst deleted file mode 100644 index 622f41d8..00000000 --- a/docs/dispatcher/filters/text.rst +++ /dev/null @@ -1,35 +0,0 @@ -==== -Text -==== - -.. autoclass:: aiogram.filters.text.Text - :members: - :member-order: bysource - :undoc-members: False - -Can be imported: - -- :code:`from aiogram.filters.text import Text` -- :code:`from aiogram.filters import Text` - -Usage -===== - -#. Text equals with the specified value: :code:`Text(text="text") # value == 'text'` -#. Text starts with the specified value: :code:`Text(startswith="text") # value.startswith('text')` -#. Text ends with the specified value: :code:`Text(endswith="text") # value.endswith('text')` -#. Text contains the specified value: :code:`Text(contains="text") # value in 'text'` -#. Any of previous listed filters can be list, set or tuple of strings that's mean any of listed value should be equals/startswith/endswith/contains: :code:`Text(text=["text", "spam"])` -#. Ignore case can be combined with any previous listed filter: :code:`Text(text="Text", ignore_case=True) # value.lower() == 'text'.lower()` - -Allowed handlers -================ - -Allowed update types for this filter: - -- :code:`message` -- :code:`edited_message` -- :code:`channel_post` -- :code:`edited_channel_post` -- :code:`inline_query` -- :code:`callback_query` diff --git a/docs/locale/en/LC_MESSAGES/api/bot.po b/docs/locale/en/LC_MESSAGES/api/bot.po index 0a7dbcc9..96a78215 100644 --- a/docs/locale/en/LC_MESSAGES/api/bot.po +++ b/docs/locale/en/LC_MESSAGES/api/bot.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-01-07 23:01+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/bot.rst:3 msgid "Bot" @@ -77,11 +77,23 @@ msgid "" "methods at runtime." msgstr "" +#: aiogram.client.bot.Bot.__init__:8 of +msgid "" +"Default disable_web_page_preview mode. If specified it will be propagated" +" into the API methods at runtime." +msgstr "" + +#: aiogram.client.bot.Bot.__init__:10 of +msgid "" +"Default protect_content mode. If specified it will be propagated into the" +" API methods at runtime." +msgstr "" + #: aiogram.client.bot.Bot.__init__ of msgid "Raises" msgstr "" -#: aiogram.client.bot.Bot.__init__:8 of +#: aiogram.client.bot.Bot.__init__:12 of msgid "When token has invalid format this exception will be raised" msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/methods/answer_inline_query.po b/docs/locale/en/LC_MESSAGES/api/methods/answer_inline_query.po index 22834a67..329640c8 100644 --- a/docs/locale/en/LC_MESSAGES/api/methods/answer_inline_query.po +++ b/docs/locale/en/LC_MESSAGES/api/methods/answer_inline_query.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-23 00:47+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/methods/answer_inline_query.rst:3 msgid "answerInlineQuery" @@ -61,7 +61,7 @@ msgstr "" msgid "" "Pass :code:`True` if results may be cached on the server side only for " "the user that sent the query. By default, results may be returned to any " -"user who sends the same query" +"user who sends the same query." msgstr "" #: ../../docstring @@ -74,11 +74,10 @@ msgid "" msgstr "" #: ../../docstring -#: aiogram.methods.answer_inline_query.AnswerInlineQuery.switch_pm_text:1 of +#: aiogram.methods.answer_inline_query.AnswerInlineQuery.button:1 of msgid "" -"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*" +"A JSON-serialized object describing a button to be shown above inline " +"query results" msgstr "" #: ../../docstring @@ -91,6 +90,20 @@ msgid "" ":code:`0-9`, :code:`_` and :code:`-` are allowed." msgstr "" +#: ../../docstring +#: aiogram.methods.answer_inline_query.AnswerInlineQuery.switch_pm_parameter:3 +#: aiogram.methods.answer_inline_query.AnswerInlineQuery.switch_pm_text:3 of +msgid "https://core.telegram.org/bots/api-changelog#april-21-2023" +msgstr "" + +#: ../../docstring +#: aiogram.methods.answer_inline_query.AnswerInlineQuery.switch_pm_text:1 of +msgid "" +"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*" +msgstr "" + #: ../../api/methods/answer_inline_query.rst:14 msgid "Usage" msgstr "" @@ -140,3 +153,12 @@ msgstr "" #~ ":code:`0-9`, :code:`_` and :code:`-` are " #~ "allowed." #~ msgstr "" + +#~ msgid "" +#~ "Pass :code:`True` if results may be " +#~ "cached on the server side only for" +#~ " the user that sent the query. " +#~ "By default, results may be returned " +#~ "to any user who sends the same " +#~ "query" +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/methods/get_my_name.po b/docs/locale/en/LC_MESSAGES/api/methods/get_my_name.po new file mode 100644 index 00000000..0437b444 --- /dev/null +++ b/docs/locale/en/LC_MESSAGES/api/methods/get_my_name.po @@ -0,0 +1,68 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../api/methods/get_my_name.rst:3 +msgid "getMyName" +msgstr "" + +#: ../../api/methods/get_my_name.rst:5 +msgid "Returns: :obj:`BotName`" +msgstr "" + +#: aiogram.methods.get_my_name.GetMyName:1 of +msgid "" +"Use this method to get the current bot name for the given user language. " +"Returns :class:`aiogram.types.bot_name.BotName` on success." +msgstr "" + +#: aiogram.methods.get_my_name.GetMyName:3 of +msgid "Source: https://core.telegram.org/bots/api#getmyname" +msgstr "" + +#: ../../docstring aiogram.methods.get_my_name.GetMyName.language_code:1 of +msgid "A two-letter ISO 639-1 language code or an empty string" +msgstr "" + +#: ../../api/methods/get_my_name.rst:14 +msgid "Usage" +msgstr "" + +#: ../../api/methods/get_my_name.rst:17 +msgid "As bot method" +msgstr "" + +#: ../../api/methods/get_my_name.rst:25 +msgid "Method as object" +msgstr "" + +#: ../../api/methods/get_my_name.rst:27 +msgid "Imports:" +msgstr "" + +#: ../../api/methods/get_my_name.rst:29 +msgid ":code:`from aiogram.methods.get_my_name import GetMyName`" +msgstr "" + +#: ../../api/methods/get_my_name.rst:30 +msgid "alias: :code:`from aiogram.methods import GetMyName`" +msgstr "" + +#: ../../api/methods/get_my_name.rst:33 +msgid "With specific bot" +msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/methods/get_updates.po b/docs/locale/en/LC_MESSAGES/api/methods/get_updates.po index e64a0df6..39a54f54 100644 --- a/docs/locale/en/LC_MESSAGES/api/methods/get_updates.po +++ b/docs/locale/en/LC_MESSAGES/api/methods/get_updates.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 22:51+0300\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/methods/get_updates.rst:3 msgid "getUpdates" @@ -59,7 +59,7 @@ msgid "" ":class:`aiogram.methods.get_updates.GetUpdates` is called with an " "*offset* higher than its *update_id*. The negative offset can be " "specified to retrieve updates starting from *-offset* update from the end" -" of the updates queue. All previous updates will forgotten." +" of the updates queue. All previous updates will be forgotten." msgstr "" #: ../../docstring aiogram.methods.get_updates.GetUpdates.limit:1 of @@ -113,3 +113,21 @@ msgstr "" #: ../../api/methods/get_updates.rst:33 msgid "With specific bot" msgstr "" + +#~ msgid "" +#~ "Identifier of the first update to " +#~ "be returned. Must be greater by " +#~ "one than the highest among the " +#~ "identifiers of previously received updates." +#~ " By default, updates starting with " +#~ "the earliest unconfirmed update are " +#~ "returned. An update is considered " +#~ "confirmed as soon as " +#~ ":class:`aiogram.methods.get_updates.GetUpdates` is called" +#~ " with an *offset* higher than its " +#~ "*update_id*. The negative offset can be" +#~ " specified to retrieve updates starting " +#~ "from *-offset* update from the end " +#~ "of the updates queue. All previous " +#~ "updates will forgotten." +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/methods/set_my_name.po b/docs/locale/en/LC_MESSAGES/api/methods/set_my_name.po new file mode 100644 index 00000000..b5befc8d --- /dev/null +++ b/docs/locale/en/LC_MESSAGES/api/methods/set_my_name.po @@ -0,0 +1,78 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../api/methods/set_my_name.rst:3 +msgid "setMyName" +msgstr "" + +#: ../../api/methods/set_my_name.rst:5 +msgid "Returns: :obj:`bool`" +msgstr "" + +#: aiogram.methods.set_my_name.SetMyName:1 of +msgid "Use this method to change the bot's name. Returns :code:`True` on success." +msgstr "" + +#: aiogram.methods.set_my_name.SetMyName:3 of +msgid "Source: https://core.telegram.org/bots/api#setmyname" +msgstr "" + +#: ../../docstring aiogram.methods.set_my_name.SetMyName.name:1 of +msgid "" +"New bot name; 0-64 characters. Pass an empty string to remove the " +"dedicated name for the given language." +msgstr "" + +#: ../../docstring aiogram.methods.set_my_name.SetMyName.language_code:1 of +msgid "" +"A two-letter ISO 639-1 language code. If empty, the name will be shown to" +" all users for whose language there is no dedicated name." +msgstr "" + +#: ../../api/methods/set_my_name.rst:14 +msgid "Usage" +msgstr "" + +#: ../../api/methods/set_my_name.rst:17 +msgid "As bot method" +msgstr "" + +#: ../../api/methods/set_my_name.rst:25 +msgid "Method as object" +msgstr "" + +#: ../../api/methods/set_my_name.rst:27 +msgid "Imports:" +msgstr "" + +#: ../../api/methods/set_my_name.rst:29 +msgid ":code:`from aiogram.methods.set_my_name import SetMyName`" +msgstr "" + +#: ../../api/methods/set_my_name.rst:30 +msgid "alias: :code:`from aiogram.methods import SetMyName`" +msgstr "" + +#: ../../api/methods/set_my_name.rst:33 +msgid "With specific bot" +msgstr "" + +#: ../../api/methods/set_my_name.rst:40 +msgid "As reply into Webhook in handler" +msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/session/base.po b/docs/locale/en/LC_MESSAGES/api/session/base.po index 3587676e..413eafd2 100644 --- a/docs/locale/en/LC_MESSAGES/api/session/base.po +++ b/docs/locale/en/LC_MESSAGES/api/session/base.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 22:51+0300\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/session/base.rst:3 msgid "Base" @@ -29,10 +29,6 @@ msgstr "" msgid "Check response status" msgstr "" -#: aiogram.client.session.base.BaseSession.clean_json:1 of -msgid "Clean data before send" -msgstr "" - #: aiogram.client.session.base.BaseSession.close:1 of msgid "Close client session" msgstr "" @@ -72,3 +68,6 @@ msgstr "" #: aiogram.client.session.base.BaseSession.stream_content:1 of msgid "Stream reader" msgstr "" + +#~ msgid "Clean data before send" +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/bot_name.po b/docs/locale/en/LC_MESSAGES/api/types/bot_name.po new file mode 100644 index 00000000..64e89253 --- /dev/null +++ b/docs/locale/en/LC_MESSAGES/api/types/bot_name.po @@ -0,0 +1,34 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../api/types/bot_name.rst:3 +msgid "BotName" +msgstr "" + +#: aiogram.types.bot_name.BotName:1 of +msgid "This object represents the bot's name." +msgstr "" + +#: aiogram.types.bot_name.BotName:3 of +msgid "Source: https://core.telegram.org/bots/api#botname" +msgstr "" + +#: ../../docstring aiogram.types.bot_name.BotName.name:1 of +msgid "The bot's name" +msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/chat_member_updated.po b/docs/locale/en/LC_MESSAGES/api/types/chat_member_updated.po index a362821e..756e5b94 100644 --- a/docs/locale/en/LC_MESSAGES/api/types/chat_member_updated.po +++ b/docs/locale/en/LC_MESSAGES/api/types/chat_member_updated.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 22:51+0300\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/chat_member_updated.rst:3 msgid "ChatMemberUpdated" @@ -60,3 +60,11 @@ msgid "" "*Optional*. Chat invite link, which was used by the user to join the " "chat; for joining by invite link events only." msgstr "" + +#: ../../docstring +#: aiogram.types.chat_member_updated.ChatMemberUpdated.via_chat_folder_invite_link:1 +#: of +msgid "" +"*Optional*. True, if the user joined the chat via a chat folder invite " +"link" +msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/index.po b/docs/locale/en/LC_MESSAGES/api/types/index.po index 8ee34c1a..dd347157 100644 --- a/docs/locale/en/LC_MESSAGES/api/types/index.po +++ b/docs/locale/en/LC_MESSAGES/api/types/index.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-30 22:28+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/index.rst:3 msgid "Types" @@ -29,33 +29,32 @@ msgstr "" msgid "Inline mode" msgstr "" -#: ../../api/types/index.rst:46 +#: ../../api/types/index.rst:47 msgid "Available types" msgstr "" -#: ../../api/types/index.rst:134 +#: ../../api/types/index.rst:143 msgid "Telegram Passport" msgstr "" -#: ../../api/types/index.rst:155 +#: ../../api/types/index.rst:164 msgid "Getting updates" msgstr "" -#: ../../api/types/index.rst:164 +#: ../../api/types/index.rst:173 msgid "Stickers" msgstr "" -#: ../../api/types/index.rst:174 +#: ../../api/types/index.rst:184 msgid "Payments" msgstr "" -#: ../../api/types/index.rst:189 -msgid "Games" -msgstr "" - #: ../../api/types/index.rst:199 -msgid "Internals" +msgid "Games" msgstr "" #~ msgid "Internal events" #~ msgstr "" + +#~ msgid "Internals" +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/inline_keyboard_button.po b/docs/locale/en/LC_MESSAGES/api/types/inline_keyboard_button.po index 7e6bedbe..3db47e31 100644 --- a/docs/locale/en/LC_MESSAGES/api/types/inline_keyboard_button.po +++ b/docs/locale/en/LC_MESSAGES/api/types/inline_keyboard_button.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 22:51+0300\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/inline_keyboard_button.rst:3 msgid "InlineKeyboardButton" @@ -91,6 +91,15 @@ msgid "" "empty, in which case only the bot's username will be inserted." msgstr "" +#: ../../docstring +#: aiogram.types.inline_keyboard_button.InlineKeyboardButton.switch_inline_query_chosen_chat:1 +#: of +msgid "" +"*Optional*. If set, pressing the button will prompt the user to select " +"one of their chats of the specified type, open that chat and insert the " +"bot's username and the specified inline query in the input field" +msgstr "" + #: ../../docstring #: aiogram.types.inline_keyboard_button.InlineKeyboardButton.callback_game:1 of msgid "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/inline_query.po b/docs/locale/en/LC_MESSAGES/api/types/inline_query.po index 4146b049..f848f5d0 100644 --- a/docs/locale/en/LC_MESSAGES/api/types/inline_query.po +++ b/docs/locale/en/LC_MESSAGES/api/types/inline_query.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-23 00:47+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/inline_query.rst:3 msgid "InlineQuery" @@ -103,7 +103,7 @@ msgstr "" msgid "" "Pass :code:`True` if results may be cached on the server side only for " "the user that sent the query. By default, results may be returned to any " -"user who sends the same query" +"user who sends the same query." msgstr "" #: aiogram.types.inline_query.InlineQuery.answer:15 of @@ -116,9 +116,8 @@ msgstr "" #: aiogram.types.inline_query.InlineQuery.answer:16 of msgid "" -"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*" +"A JSON-serialized object describing a button to be shown above inline " +"query results" msgstr "" #: aiogram.types.inline_query.InlineQuery.answer:17 of @@ -129,12 +128,28 @@ msgid "" ":code:`0-9`, :code:`_` and :code:`-` are allowed." msgstr "" +#: aiogram.types.inline_query.InlineQuery.answer:18 of +msgid "" +"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*" +msgstr "" + #: aiogram.types.inline_query.InlineQuery.answer of msgid "Returns" msgstr "" -#: aiogram.types.inline_query.InlineQuery.answer:18 of +#: aiogram.types.inline_query.InlineQuery.answer:19 of msgid "" "instance of method " ":class:`aiogram.methods.answer_inline_query.AnswerInlineQuery`" msgstr "" + +#~ msgid "" +#~ "Pass :code:`True` if results may be " +#~ "cached on the server side only for" +#~ " the user that sent the query. " +#~ "By default, results may be returned " +#~ "to any user who sends the same " +#~ "query" +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/inline_query_results_button.po b/docs/locale/en/LC_MESSAGES/api/types/inline_query_results_button.po new file mode 100644 index 00000000..3dcf4f0f --- /dev/null +++ b/docs/locale/en/LC_MESSAGES/api/types/inline_query_results_button.po @@ -0,0 +1,59 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../api/types/inline_query_results_button.rst:3 +msgid "InlineQueryResultsButton" +msgstr "" + +#: aiogram.types.inline_query_results_button.InlineQueryResultsButton:1 of +msgid "" +"This object represents a button to be shown above inline query results. " +"You **must** use exactly one of the optional fields." +msgstr "" + +#: aiogram.types.inline_query_results_button.InlineQueryResultsButton:3 of +msgid "Source: https://core.telegram.org/bots/api#inlinequeryresultsbutton" +msgstr "" + +#: ../../docstring +#: aiogram.types.inline_query_results_button.InlineQueryResultsButton.text:1 of +msgid "Label text on the button" +msgstr "" + +#: ../../docstring +#: aiogram.types.inline_query_results_button.InlineQueryResultsButton.web_app:1 +#: of +msgid "" +"*Optional*. Description of the `Web App " +"`_ that will be launched when the" +" user presses the button. The Web App will be able to switch back to the " +"inline mode using the method `switchInlineQuery " +"`_ inside " +"the Web App." +msgstr "" + +#: ../../docstring +#: aiogram.types.inline_query_results_button.InlineQueryResultsButton.start_parameter:1 +#: of +msgid "" +"*Optional*. `Deep-linking `_ parameter for the /start message sent to the bot when a user " +"presses the button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, " +":code:`0-9`, :code:`_` and :code:`-` are allowed." +msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/input_sticker.po b/docs/locale/en/LC_MESSAGES/api/types/input_sticker.po index 3bbc8b33..fb2433c4 100644 --- a/docs/locale/en/LC_MESSAGES/api/types/input_sticker.po +++ b/docs/locale/en/LC_MESSAGES/api/types/input_sticker.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-11 01:52+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.11.0\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/input_sticker.rst:3 msgid "InputSticker" @@ -33,9 +33,11 @@ msgstr "" msgid "" "The added sticker. Pass a *file_id* as a String to send a file that " "already exists on the Telegram servers, pass an HTTP URL as a String for " -"Telegram to get a file from the Internet, or upload a new one using " -"multipart/form-data. Animated and video stickers can't be uploaded via " -"HTTP URL. :ref:`More information on Sending Files » `" +"Telegram to get a file from the Internet, upload a new one using " +"multipart/form-data, or pass 'attach://' to upload a " +"new one using multipart/form-data under name. Animated" +" and video stickers can't be uploaded via HTTP URL. :ref:`More " +"information on Sending Files » `" msgstr "" #: ../../docstring aiogram.types.input_sticker.InputSticker.emoji_list:1 of @@ -54,3 +56,17 @@ msgid "" "length of up to 64 characters. For 'regular' and 'custom_emoji' stickers " "only." msgstr "" + +#~ msgid "" +#~ "The added sticker. Pass a *file_id* " +#~ "as a String to send a file " +#~ "that already exists on the Telegram " +#~ "servers, pass an HTTP URL as a " +#~ "String for Telegram to get a file" +#~ " from the Internet, or upload a " +#~ "new one using multipart/form-data. " +#~ "Animated and video stickers can't be " +#~ "uploaded via HTTP URL. :ref:`More " +#~ "information on Sending Files » " +#~ "`" +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/keyboard_button_request_chat.po b/docs/locale/en/LC_MESSAGES/api/types/keyboard_button_request_chat.po index 69f4736f..2912a3f0 100644 --- a/docs/locale/en/LC_MESSAGES/api/types/keyboard_button_request_chat.po +++ b/docs/locale/en/LC_MESSAGES/api/types/keyboard_button_request_chat.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-11 01:52+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.11.0\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/keyboard_button_request_chat.rst:3 msgid "KeyboardButtonRequestChat" @@ -25,7 +25,8 @@ msgstr "" msgid "" "This object defines the criteria used to request a suitable chat. The " "identifier of the selected chat will be shared with the bot when the " -"corresponding button is pressed." +"corresponding button is pressed. `More about requesting chats » " +"`_" msgstr "" #: aiogram.types.keyboard_button_request_chat.KeyboardButtonRequestChat:3 of @@ -102,3 +103,11 @@ msgid "" "*Optional*. Pass :code:`True` to request a chat with the bot as a member." " Otherwise, no additional restrictions are applied." msgstr "" + +#~ msgid "" +#~ "This object defines the criteria used" +#~ " to request a suitable chat. The " +#~ "identifier of the selected chat will " +#~ "be shared with the bot when the" +#~ " corresponding button is pressed." +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/keyboard_button_request_user.po b/docs/locale/en/LC_MESSAGES/api/types/keyboard_button_request_user.po index faf737b0..1e0bca68 100644 --- a/docs/locale/en/LC_MESSAGES/api/types/keyboard_button_request_user.po +++ b/docs/locale/en/LC_MESSAGES/api/types/keyboard_button_request_user.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-11 01:52+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.11.0\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/keyboard_button_request_user.rst:3 msgid "KeyboardButtonRequestUser" @@ -25,7 +25,8 @@ msgstr "" msgid "" "This object defines the criteria used to request a suitable user. The " "identifier of the selected user will be shared with the bot when the " -"corresponding button is pressed." +"corresponding button is pressed. `More about requesting users » " +"`_" msgstr "" #: aiogram.types.keyboard_button_request_user.KeyboardButtonRequestUser:3 of @@ -58,3 +59,11 @@ msgid "" ":code:`False` to request a non-premium user. If not specified, no " "additional restrictions are applied." msgstr "" + +#~ msgid "" +#~ "This object defines the criteria used" +#~ " to request a suitable user. The " +#~ "identifier of the selected user will " +#~ "be shared with the bot when the" +#~ " corresponding button is pressed." +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/switch_inline_query_chosen_chat.po b/docs/locale/en/LC_MESSAGES/api/types/switch_inline_query_chosen_chat.po new file mode 100644 index 00000000..3b8f431d --- /dev/null +++ b/docs/locale/en/LC_MESSAGES/api/types/switch_inline_query_chosen_chat.po @@ -0,0 +1,66 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../api/types/switch_inline_query_chosen_chat.rst:3 +msgid "SwitchInlineQueryChosenChat" +msgstr "" + +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat:1 +#: of +msgid "" +"This object represents an inline button that switches the current user to" +" inline mode in a chosen chat, with an optional default inline query." +msgstr "" + +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat:3 +#: of +msgid "Source: https://core.telegram.org/bots/api#switchinlinequerychosenchat" +msgstr "" + +#: ../../docstring +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat.query:1 +#: of +msgid "" +"*Optional*. The default inline query to be inserted in the input field. " +"If left empty, only the bot's username will be inserted" +msgstr "" + +#: ../../docstring +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat.allow_user_chats:1 +#: of +msgid "*Optional*. True, if private chats with users can be chosen" +msgstr "" + +#: ../../docstring +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat.allow_bot_chats:1 +#: of +msgid "*Optional*. True, if private chats with bots can be chosen" +msgstr "" + +#: ../../docstring +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat.allow_group_chats:1 +#: of +msgid "*Optional*. True, if group and supergroup chats can be chosen" +msgstr "" + +#: ../../docstring +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat.allow_channel_chats:1 +#: of +msgid "*Optional*. True, if channel chats can be chosen" +msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/types/write_access_allowed.po b/docs/locale/en/LC_MESSAGES/api/types/write_access_allowed.po index e2754dd2..4fee2157 100644 --- a/docs/locale/en/LC_MESSAGES/api/types/write_access_allowed.po +++ b/docs/locale/en/LC_MESSAGES/api/types/write_access_allowed.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-30 22:28+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/write_access_allowed.rst:3 msgid "WriteAccessAllowed" @@ -23,11 +23,24 @@ msgstr "" #: aiogram.types.write_access_allowed.WriteAccessAllowed:1 of msgid "" -"This object represents a service message about a user allowing a bot " -"added to the attachment menu to write messages. Currently holds no " -"information." +"This object represents a service message about a user allowing a bot to " +"write messages after adding the bot to the attachment menu or launching a" +" Web App from a link." msgstr "" #: aiogram.types.write_access_allowed.WriteAccessAllowed:3 of msgid "Source: https://core.telegram.org/bots/api#writeaccessallowed" msgstr "" + +#: ../../docstring +#: aiogram.types.write_access_allowed.WriteAccessAllowed.web_app_name:1 of +msgid "*Optional*. Name of the Web App which was launched from a link" +msgstr "" + +#~ msgid "" +#~ "This object represents a service message" +#~ " about a user allowing a bot " +#~ "added to the attachment menu to " +#~ "write messages. Currently holds no " +#~ "information." +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/api/upload_file.po b/docs/locale/en/LC_MESSAGES/api/upload_file.po index 8e01cf9e..a7ff966a 100644 --- a/docs/locale/en/LC_MESSAGES/api/upload_file.po +++ b/docs/locale/en/LC_MESSAGES/api/upload_file.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-11 01:52+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.11.0\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/upload_file.rst:5 msgid "How to upload file?" @@ -37,7 +37,7 @@ msgstr "" #: ../../api/upload_file.rst:13 msgid "" "But if you need to upload a new file just use subclasses of `InputFile " -"`__." +"`__." msgstr "" #: ../../api/upload_file.rst:15 @@ -187,3 +187,9 @@ msgstr "" #~ "want's to sent it to the " #~ "Telegram):" #~ msgstr "" + +#~ msgid "" +#~ "But if you need to upload a " +#~ "new file just use subclasses of " +#~ "`InputFile `__." +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/changelog.po b/docs/locale/en/LC_MESSAGES/changelog.po index ec08c2fa..25d6a145 100644 --- a/docs/locale/en/LC_MESSAGES/changelog.po +++ b/docs/locale/en/LC_MESSAGES/changelog.po @@ -8,59 +8,240 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-11 01:52+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.11.0\n" +"Generated-By: Babel 2.12.1\n" #: ../../../CHANGES.rst:3 msgid "Changelog" msgstr "" #: ../../[towncrier-fragments]:2 -msgid "\\ |release| [UNRELEASED DRAFT] (2023-03-11)" +msgid "\\ |release| [UNRELEASED DRAFT] (2023-07-02)" msgstr "" -#: ../../../CHANGES.rst:193 ../../../CHANGES.rst:243 ../../../CHANGES.rst:623 +#: ../../../CHANGES.rst:56 ../../../CHANGES.rst:156 ../../../CHANGES.rst:216 +#: ../../../CHANGES.rst:267 ../../../CHANGES.rst:340 ../../../CHANGES.rst:381 +#: ../../../CHANGES.rst:419 ../../../CHANGES.rst:467 ../../../CHANGES.rst:543 +#: ../../../CHANGES.rst:576 ../../../CHANGES.rst:607 #: ../../[towncrier-fragments]:5 -msgid "Improved Documentation" +msgid "Features" msgstr "" #: ../../[towncrier-fragments]:7 msgid "" +"If router does not support custom event it does not break and passes it " +"to included routers `#1147 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:9 +msgid "Added support for FSM in Forum topics." +msgstr "" + +#: ../../[towncrier-fragments]:11 +msgid "The strategy can be changed in dispatcher:" +msgstr "" + +#: ../../[towncrier-fragments]:24 +msgid "" +"If you have implemented you own storages you should extend record key " +"generation with new one attribute - `thread_id`" +msgstr "" + +#: ../../[towncrier-fragments]:26 +msgid "`#1161 `_" +msgstr "" + +#: ../../[towncrier-fragments]:27 +msgid "Improved CallbackData serialization." +msgstr "" + +#: ../../[towncrier-fragments]:29 +msgid "Minimized UUID (hex without dashes)" +msgstr "" + +#: ../../[towncrier-fragments]:30 +msgid "Replaced bool values with int (true=1, false=0)" +msgstr "" + +#: ../../[towncrier-fragments]:31 +msgid "`#1163 `_" +msgstr "" + +#: ../../[towncrier-fragments]:32 +msgid "" +"Added a tool to make text formatting flexible and easy. More details on " +"the :ref:`corresponding documentation page ` `#1172 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:35 +msgid "" +"Added X-Telegram-Bot-Api-Secret-Token header check `#1173 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:37 +msgid "" +"Added possibility to pass custom headers to URLInputFile object `#1191 " +"`_" +msgstr "" + +#: ../../../CHANGES.rst:118 ../../../CHANGES.rst:181 ../../../CHANGES.rst:230 +#: ../../../CHANGES.rst:291 ../../../CHANGES.rst:349 ../../../CHANGES.rst:395 +#: ../../../CHANGES.rst:443 ../../../CHANGES.rst:499 ../../../CHANGES.rst:584 +#: ../../../CHANGES.rst:616 ../../[towncrier-fragments]:42 +msgid "Bugfixes" +msgstr "" + +#: ../../[towncrier-fragments]:44 +msgid "" +"Change type of result in InlineQueryResult enum for " +"`InlineQueryResultCachedMpeg4Gif` and `InlineQueryResultMpeg4Gif` to more" +" correct according to documentation." +msgstr "" + +#: ../../[towncrier-fragments]:47 +msgid "" +"Change regexp for entities parsing to more correct " +"(`InlineQueryResultType.yml`). `#1146 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:49 +msgid "" +"Fixed signature of startup/shutdown events to include the " +"**dispatcher.workflow_data as the handler arguments. `#1155 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:51 +msgid "" +"Added missing FORUM_TOPIC_EDITED value to content_type property `#1160 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:53 +msgid "" +"Fixed compatibility with Python 3.8-3.9 `#1162 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:55 +msgid "" +"Fixed the markdown spoiler parser. `#1176 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:57 +msgid "" +"Fixed workflow data propagation `#1196 " +"`_" +msgstr "" + +#: ../../../CHANGES.rst:193 ../../../CHANGES.rst:243 ../../../CHANGES.rst:623 +#: ../../[towncrier-fragments]:62 +msgid "Improved Documentation" +msgstr "" + +#: ../../[towncrier-fragments]:64 +msgid "" "Changed small grammar typos for `upload_file` `#1133 " "`_" msgstr "" +#: ../../../CHANGES.rst:250 ../../[towncrier-fragments]:69 +msgid "Deprecations and Removals" +msgstr "" + +#: ../../[towncrier-fragments]:71 +msgid "" +"Removed text filter in due to is planned to remove this filter few " +"versions ago." +msgstr "" + +#: ../../[towncrier-fragments]:73 +msgid "" +"Use :code:`F.text` instead `#1170 " +"`_" +msgstr "" + #: ../../../CHANGES.rst:127 ../../../CHANGES.rst:204 ../../../CHANGES.rst:257 #: ../../../CHANGES.rst:308 ../../../CHANGES.rst:362 ../../../CHANGES.rst:404 #: ../../../CHANGES.rst:450 ../../../CHANGES.rst:510 ../../../CHANGES.rst:531 #: ../../../CHANGES.rst:554 ../../../CHANGES.rst:591 ../../../CHANGES.rst:630 -#: ../../[towncrier-fragments]:12 +#: ../../[towncrier-fragments]:78 msgid "Misc" msgstr "" -#: ../../[towncrier-fragments]:14 +#: ../../[towncrier-fragments]:80 msgid "" "Added full support of `Bot API 6.6 `_" msgstr "" -#: ../../[towncrier-fragments]:18 +#: ../../[towncrier-fragments]:84 msgid "" "Note that this issue has breaking changes described in in the Bot API " "changelog, this changes is not breaking in the API but breaking inside " "aiogram because Beta stage is not finished." msgstr "" -#: ../../[towncrier-fragments]:21 +#: ../../[towncrier-fragments]:87 msgid "`#1139 `_" msgstr "" +#: ../../[towncrier-fragments]:88 +msgid "" +"Added global defaults `disable_web_page_preview` and `protect_content` in" +" addition to `parse_mode` to the Bot instance, reworked internal request " +"builder mechanism. `#1142 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:91 +msgid "" +"Removed bot parameters from storages `#1144 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:93 +msgid "" +"Added full support of `Bot API 6.7 `_" +msgstr "" + +#: ../../[towncrier-fragments]:97 +msgid "" +"Note that arguments *switch_pm_parameter* and *switch_pm_text* was " +"deprecated and should be changed to *button* argument as described in API" +" docs." +msgstr "" + +#: ../../[towncrier-fragments]:99 +msgid "`#1168 `_" +msgstr "" + +#: ../../[towncrier-fragments]:100 +msgid "Updated `Pydantic to V2 `_" +msgstr "" + +#: ../../[towncrier-fragments]:104 +msgid "" +"Be careful, not all libraries is already updated to using V2 (for example" +" at the time, when this warning was added FastAPI still not support V2)" +msgstr "" + +#: ../../[towncrier-fragments]:106 +msgid "`#1202 `_" +msgstr "" + #: ../../../CHANGES.rst:20 msgid "3.0.0b7 (2023-02-18)" msgstr "" @@ -83,13 +264,6 @@ msgstr "" msgid "But if you change it like this it should works as well:" msgstr "" -#: ../../../CHANGES.rst:56 ../../../CHANGES.rst:156 ../../../CHANGES.rst:216 -#: ../../../CHANGES.rst:267 ../../../CHANGES.rst:340 ../../../CHANGES.rst:381 -#: ../../../CHANGES.rst:419 ../../../CHANGES.rst:467 ../../../CHANGES.rst:543 -#: ../../../CHANGES.rst:576 ../../../CHANGES.rst:607 -msgid "Features" -msgstr "" - #: ../../../CHANGES.rst:58 msgid "Added missing shortcuts, new enums, reworked old stuff" msgstr "" @@ -189,13 +363,6 @@ msgid "" "`_" msgstr "" -#: ../../../CHANGES.rst:118 ../../../CHANGES.rst:181 ../../../CHANGES.rst:230 -#: ../../../CHANGES.rst:291 ../../../CHANGES.rst:349 ../../../CHANGES.rst:395 -#: ../../../CHANGES.rst:443 ../../../CHANGES.rst:499 ../../../CHANGES.rst:584 -#: ../../../CHANGES.rst:616 -msgid "Bugfixes" -msgstr "" - #: ../../../CHANGES.rst:120 msgid "" "Check status code when downloading file `#816 " @@ -459,10 +626,6 @@ msgid "" "`_" msgstr "" -#: ../../../CHANGES.rst:250 -msgid "Deprecations and Removals" -msgstr "" - #: ../../../CHANGES.rst:252 msgid "" "Removed filters factory as described in corresponding issue. `#942 " @@ -2618,3 +2781,6 @@ msgstr "" #~ ":class:`aiogram.enums.topic_icon_color.TopicIconColor`, " #~ ":class:`aiogram.enums.update_type.UpdateType`," #~ msgstr "" + +#~ msgid "\\ |release| [UNRELEASED DRAFT] (2023-03-11)" +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/dispatcher/finite_state_machine/storages.po b/docs/locale/en/LC_MESSAGES/dispatcher/finite_state_machine/storages.po index 271fd8e1..f8669452 100644 --- a/docs/locale/en/LC_MESSAGES/dispatcher/finite_state_machine/storages.po +++ b/docs/locale/en/LC_MESSAGES/dispatcher/finite_state_machine/storages.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-02 22:41+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../dispatcher/finite_state_machine/storages.rst:3 msgid "Storages" @@ -79,10 +79,6 @@ msgstr "" msgid "TTL for data records" msgstr "" -#: aiogram.fsm.storage.redis.RedisStorage.__init__:5 of -msgid "Custom arguments for Redis lock" -msgstr "" - #: aiogram.fsm.storage.redis.RedisStorage.from_url:1 of msgid "" "Create an instance of :class:`RedisStorage` with specifying the " @@ -169,18 +165,10 @@ msgstr "" #: aiogram.fsm.storage.base.BaseStorage.set_data:3 #: aiogram.fsm.storage.base.BaseStorage.set_state:3 #: aiogram.fsm.storage.base.BaseStorage.update_data:3 of -msgid "instance of the current bot" -msgstr "" - -#: aiogram.fsm.storage.base.BaseStorage.get_data:4 -#: aiogram.fsm.storage.base.BaseStorage.get_state:4 -#: aiogram.fsm.storage.base.BaseStorage.set_data:4 -#: aiogram.fsm.storage.base.BaseStorage.set_state:4 -#: aiogram.fsm.storage.base.BaseStorage.update_data:4 of msgid "storage key" msgstr "" -#: aiogram.fsm.storage.base.BaseStorage.set_state:5 of +#: aiogram.fsm.storage.base.BaseStorage.set_state:4 of msgid "new state" msgstr "" @@ -188,7 +176,7 @@ msgstr "" msgid "Get key state" msgstr "" -#: aiogram.fsm.storage.base.BaseStorage.get_state:5 of +#: aiogram.fsm.storage.base.BaseStorage.get_state:4 of msgid "current state" msgstr "" @@ -196,8 +184,8 @@ msgstr "" msgid "Write data (replace)" msgstr "" -#: aiogram.fsm.storage.base.BaseStorage.set_data:5 -#: aiogram.fsm.storage.base.BaseStorage.update_data:6 of +#: aiogram.fsm.storage.base.BaseStorage.set_data:4 +#: aiogram.fsm.storage.base.BaseStorage.update_data:5 of msgid "new data" msgstr "" @@ -205,7 +193,7 @@ msgstr "" msgid "Get current data for key" msgstr "" -#: aiogram.fsm.storage.base.BaseStorage.get_data:5 of +#: aiogram.fsm.storage.base.BaseStorage.get_data:4 of msgid "current data" msgstr "" @@ -213,7 +201,7 @@ msgstr "" msgid "Update date in the storage for key (like dict.update)" msgstr "" -#: aiogram.fsm.storage.base.BaseStorage.update_data:5 of +#: aiogram.fsm.storage.base.BaseStorage.update_data:4 of msgid "partial data" msgstr "" @@ -229,3 +217,9 @@ msgstr "" #~ msgid "see :code:`aioredis` docs" #~ msgstr "" + +#~ msgid "Custom arguments for Redis lock" +#~ msgstr "" + +#~ msgid "instance of the current bot" +#~ msgstr "" diff --git a/docs/locale/en/LC_MESSAGES/utils/formatting.po b/docs/locale/en/LC_MESSAGES/utils/formatting.po new file mode 100644 index 00000000..49966ca8 --- /dev/null +++ b/docs/locale/en/LC_MESSAGES/utils/formatting.po @@ -0,0 +1,439 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../utils/formatting.rst:5 +msgid "Formatting" +msgstr "" + +#: ../../utils/formatting.rst:7 +msgid "Make your message formatting flexible and simple" +msgstr "" + +#: ../../utils/formatting.rst:9 +msgid "" +"This instrument works on top of Message entities instead of using HTML or" +" Markdown markups, you can easily construct your message and sent it to " +"the Telegram without the need to remember tag parity (opening and " +"closing) or escaping user input." +msgstr "" + +#: ../../utils/formatting.rst:14 +msgid "Usage" +msgstr "" + +#: ../../utils/formatting.rst:17 +msgid "Basic scenario" +msgstr "" + +#: ../../utils/formatting.rst:19 +msgid "Construct your message and send it to the Telegram." +msgstr "" + +#: ../../utils/formatting.rst:26 +msgid "Is the same as the next example, but without usage markup" +msgstr "" + +#: ../../utils/formatting.rst:35 +msgid "" +"Literally when you execute :code:`as_kwargs` method the Text object is " +"converted into text :code:`Hello, Alex!` with entities list " +":code:`[MessageEntity(type='bold', offset=7, length=4)]` and passed into " +"dict which can be used as :code:`**kwargs` in API call." +msgstr "" + +#: ../../utils/formatting.rst:39 +msgid "" +"The complete list of elements is listed `on this page below <#available-" +"elements>`_." +msgstr "" + +#: ../../utils/formatting.rst:42 +msgid "Advanced scenario" +msgstr "" + +#: ../../utils/formatting.rst:44 +msgid "" +"On top of base elements can be implemented content rendering structures, " +"so, out of the box aiogram has a few already implemented functions that " +"helps you to format your messages:" +msgstr "" + +#: aiogram.utils.formatting.as_line:1 of +msgid "Wrap multiple nodes into line with :code:`\\\\n` at the end of line." +msgstr "" + +#: aiogram.utils.formatting.Text.as_kwargs +#: aiogram.utils.formatting.as_key_value aiogram.utils.formatting.as_line +#: aiogram.utils.formatting.as_list aiogram.utils.formatting.as_marked_list +#: aiogram.utils.formatting.as_marked_section +#: aiogram.utils.formatting.as_numbered_list +#: aiogram.utils.formatting.as_numbered_section +#: aiogram.utils.formatting.as_section of +msgid "Parameters" +msgstr "" + +#: aiogram.utils.formatting.as_line:3 of +msgid "Text or Any" +msgstr "" + +#: aiogram.utils.formatting.as_line:4 of +msgid "ending of the line, by default is :code:`\\\\n`" +msgstr "" + +#: aiogram.utils.formatting.Text.as_kwargs aiogram.utils.formatting.Text.render +#: aiogram.utils.formatting.as_key_value aiogram.utils.formatting.as_line +#: aiogram.utils.formatting.as_list aiogram.utils.formatting.as_marked_list +#: aiogram.utils.formatting.as_marked_section +#: aiogram.utils.formatting.as_numbered_list +#: aiogram.utils.formatting.as_numbered_section +#: aiogram.utils.formatting.as_section of +msgid "Returns" +msgstr "" + +#: aiogram.utils.formatting.as_key_value:5 aiogram.utils.formatting.as_line:5 +#: aiogram.utils.formatting.as_marked_list:5 +#: aiogram.utils.formatting.as_numbered_list:6 +#: aiogram.utils.formatting.as_section:5 of +msgid "Text" +msgstr "" + +#: aiogram.utils.formatting.as_list:1 of +msgid "Wrap each element to separated lines" +msgstr "" + +#: aiogram.utils.formatting.as_marked_list:1 of +msgid "Wrap elements as marked list" +msgstr "" + +#: aiogram.utils.formatting.as_marked_list:4 of +msgid "line marker, by default is :code:`- `" +msgstr "" + +#: aiogram.utils.formatting.as_numbered_list:1 of +msgid "Wrap elements as numbered list" +msgstr "" + +#: aiogram.utils.formatting.as_numbered_list:4 of +msgid "initial number, by default 1" +msgstr "" + +#: aiogram.utils.formatting.as_numbered_list:5 of +msgid "number format, by default :code:`{}. `" +msgstr "" + +#: aiogram.utils.formatting.as_section:1 of +msgid "Wrap elements as simple section, section has title and body" +msgstr "" + +#: aiogram.utils.formatting.as_marked_section:1 of +msgid "Wrap elements as section with marked list" +msgstr "" + +#: aiogram.utils.formatting.as_numbered_section:1 of +msgid "Wrap elements as section with numbered list" +msgstr "" + +#: aiogram.utils.formatting.as_key_value:1 of +msgid "Wrap elements pair as key-value line. (:code:`{key}: {value}`)" +msgstr "" + +#: ../../utils/formatting.rst:64 +msgid "and lets complete them all:" +msgstr "" + +#: ../../utils/formatting.rst:92 +msgid "Will be rendered into:" +msgstr "" + +#: ../../utils/formatting.rst:94 +msgid "**Success:**" +msgstr "" + +#: ../../utils/formatting.rst:96 +msgid "✅ Test 1" +msgstr "" + +#: ../../utils/formatting.rst:98 +msgid "✅ Test 3" +msgstr "" + +#: ../../utils/formatting.rst:100 +msgid "✅ Test 4" +msgstr "" + +#: ../../utils/formatting.rst:102 +msgid "**Failed:**" +msgstr "" + +#: ../../utils/formatting.rst:104 +msgid "❌ Test 2" +msgstr "" + +#: ../../utils/formatting.rst:106 +msgid "**Summary:**" +msgstr "" + +#: ../../utils/formatting.rst:108 +msgid "**Total**: 4" +msgstr "" + +#: ../../utils/formatting.rst:110 +msgid "**Success**: 3" +msgstr "" + +#: ../../utils/formatting.rst:112 +msgid "**Failed**: 1" +msgstr "" + +#: ../../utils/formatting.rst:114 +msgid "#test" +msgstr "" + +#: ../../utils/formatting.rst:117 +msgid "Or as HTML:" +msgstr "" + +#: ../../utils/formatting.rst:137 +msgid "Available methods" +msgstr "" + +#: aiogram.utils.formatting.Text:1 of +msgid "Bases: :py:class:`~typing.Iterable`\\ [:py:obj:`~typing.Any`]" +msgstr "" + +#: aiogram.utils.formatting.Text:1 of +msgid "Simple text element" +msgstr "" + +#: aiogram.utils.formatting.Text.render:1 of +msgid "Render elements tree as text with entities list" +msgstr "" + +#: aiogram.utils.formatting.Text.as_kwargs:1 of +msgid "" +"Render elements tree as keyword arguments for usage in the API call, for " +"example:" +msgstr "" + +#: aiogram.utils.formatting.Text.as_html:1 of +msgid "Render elements tree as HTML markup" +msgstr "" + +#: aiogram.utils.formatting.Text.as_markdown:1 of +msgid "Render elements tree as MarkdownV2 markup" +msgstr "" + +#: ../../utils/formatting.rst:147 +msgid "Available elements" +msgstr "" + +#: aiogram.utils.formatting.Bold:1 aiogram.utils.formatting.BotCommand:1 +#: aiogram.utils.formatting.CashTag:1 aiogram.utils.formatting.Code:1 +#: aiogram.utils.formatting.CustomEmoji:1 aiogram.utils.formatting.Email:1 +#: aiogram.utils.formatting.HashTag:1 aiogram.utils.formatting.Italic:1 +#: aiogram.utils.formatting.PhoneNumber:1 aiogram.utils.formatting.Pre:1 +#: aiogram.utils.formatting.Spoiler:1 aiogram.utils.formatting.Strikethrough:1 +#: aiogram.utils.formatting.TextLink:1 aiogram.utils.formatting.TextMention:1 +#: aiogram.utils.formatting.Underline:1 aiogram.utils.formatting.Url:1 of +msgid "Bases: :py:class:`~aiogram.utils.formatting.Text`" +msgstr "" + +#: aiogram.utils.formatting.HashTag:1 of +msgid "Hashtag element." +msgstr "" + +#: aiogram.utils.formatting.HashTag:5 of +msgid "The value should always start with '#' symbol" +msgstr "" + +#: aiogram.utils.formatting.HashTag:7 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.HASHTAG`" +msgstr "" + +#: aiogram.utils.formatting.CashTag:1 of +msgid "Cashtag element." +msgstr "" + +#: aiogram.utils.formatting.CashTag:5 of +msgid "The value should always start with '$' symbol" +msgstr "" + +#: aiogram.utils.formatting.CashTag:7 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.CASHTAG`" +msgstr "" + +#: aiogram.utils.formatting.BotCommand:1 of +msgid "Bot command element." +msgstr "" + +#: aiogram.utils.formatting.BotCommand:5 of +msgid "The value should always start with '/' symbol" +msgstr "" + +#: aiogram.utils.formatting.BotCommand:7 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.BOT_COMMAND`" +msgstr "" + +#: aiogram.utils.formatting.Url:1 of +msgid "Url element." +msgstr "" + +#: aiogram.utils.formatting.Url:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.URL`" +msgstr "" + +#: aiogram.utils.formatting.Email:1 of +msgid "Email element." +msgstr "" + +#: aiogram.utils.formatting.Email:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.EMAIL`" +msgstr "" + +#: aiogram.utils.formatting.PhoneNumber:1 of +msgid "Phone number element." +msgstr "" + +#: aiogram.utils.formatting.PhoneNumber:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.PHONE_NUMBER`" +msgstr "" + +#: aiogram.utils.formatting.Bold:1 of +msgid "Bold element." +msgstr "" + +#: aiogram.utils.formatting.Bold:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.BOLD`" +msgstr "" + +#: aiogram.utils.formatting.Italic:1 of +msgid "Italic element." +msgstr "" + +#: aiogram.utils.formatting.Italic:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.ITALIC`" +msgstr "" + +#: aiogram.utils.formatting.Underline:1 of +msgid "Underline element." +msgstr "" + +#: aiogram.utils.formatting.Underline:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.UNDERLINE`" +msgstr "" + +#: aiogram.utils.formatting.Strikethrough:1 of +msgid "Strikethrough element." +msgstr "" + +#: aiogram.utils.formatting.Strikethrough:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.STRIKETHROUGH`" +msgstr "" + +#: aiogram.utils.formatting.Spoiler:1 of +msgid "Spoiler element." +msgstr "" + +#: aiogram.utils.formatting.Spoiler:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.SPOILER`" +msgstr "" + +#: aiogram.utils.formatting.Code:1 of +msgid "Code element." +msgstr "" + +#: aiogram.utils.formatting.Code:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.CODE`" +msgstr "" + +#: aiogram.utils.formatting.Pre:1 of +msgid "Pre element." +msgstr "" + +#: aiogram.utils.formatting.Pre:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.PRE`" +msgstr "" + +#: aiogram.utils.formatting.TextLink:1 of +msgid "Text link element." +msgstr "" + +#: aiogram.utils.formatting.TextLink:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.TEXT_LINK`" +msgstr "" + +#: aiogram.utils.formatting.TextMention:1 of +msgid "Text mention element." +msgstr "" + +#: aiogram.utils.formatting.TextMention:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.TEXT_MENTION`" +msgstr "" + +#: aiogram.utils.formatting.CustomEmoji:1 of +msgid "Custom emoji element." +msgstr "" + +#: aiogram.utils.formatting.CustomEmoji:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.CUSTOM_EMOJI`" +msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/bot.po b/docs/locale/uk_UA/LC_MESSAGES/api/bot.po index 0a7dbcc9..96a78215 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/bot.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/bot.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-01-07 23:01+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/bot.rst:3 msgid "Bot" @@ -77,11 +77,23 @@ msgid "" "methods at runtime." msgstr "" +#: aiogram.client.bot.Bot.__init__:8 of +msgid "" +"Default disable_web_page_preview mode. If specified it will be propagated" +" into the API methods at runtime." +msgstr "" + +#: aiogram.client.bot.Bot.__init__:10 of +msgid "" +"Default protect_content mode. If specified it will be propagated into the" +" API methods at runtime." +msgstr "" + #: aiogram.client.bot.Bot.__init__ of msgid "Raises" msgstr "" -#: aiogram.client.bot.Bot.__init__:8 of +#: aiogram.client.bot.Bot.__init__:12 of msgid "When token has invalid format this exception will be raised" msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/methods/answer_inline_query.po b/docs/locale/uk_UA/LC_MESSAGES/api/methods/answer_inline_query.po index 22834a67..329640c8 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/methods/answer_inline_query.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/methods/answer_inline_query.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-23 00:47+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/methods/answer_inline_query.rst:3 msgid "answerInlineQuery" @@ -61,7 +61,7 @@ msgstr "" msgid "" "Pass :code:`True` if results may be cached on the server side only for " "the user that sent the query. By default, results may be returned to any " -"user who sends the same query" +"user who sends the same query." msgstr "" #: ../../docstring @@ -74,11 +74,10 @@ msgid "" msgstr "" #: ../../docstring -#: aiogram.methods.answer_inline_query.AnswerInlineQuery.switch_pm_text:1 of +#: aiogram.methods.answer_inline_query.AnswerInlineQuery.button:1 of msgid "" -"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*" +"A JSON-serialized object describing a button to be shown above inline " +"query results" msgstr "" #: ../../docstring @@ -91,6 +90,20 @@ msgid "" ":code:`0-9`, :code:`_` and :code:`-` are allowed." msgstr "" +#: ../../docstring +#: aiogram.methods.answer_inline_query.AnswerInlineQuery.switch_pm_parameter:3 +#: aiogram.methods.answer_inline_query.AnswerInlineQuery.switch_pm_text:3 of +msgid "https://core.telegram.org/bots/api-changelog#april-21-2023" +msgstr "" + +#: ../../docstring +#: aiogram.methods.answer_inline_query.AnswerInlineQuery.switch_pm_text:1 of +msgid "" +"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*" +msgstr "" + #: ../../api/methods/answer_inline_query.rst:14 msgid "Usage" msgstr "" @@ -140,3 +153,12 @@ msgstr "" #~ ":code:`0-9`, :code:`_` and :code:`-` are " #~ "allowed." #~ msgstr "" + +#~ msgid "" +#~ "Pass :code:`True` if results may be " +#~ "cached on the server side only for" +#~ " the user that sent the query. " +#~ "By default, results may be returned " +#~ "to any user who sends the same " +#~ "query" +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/methods/get_my_name.po b/docs/locale/uk_UA/LC_MESSAGES/api/methods/get_my_name.po new file mode 100644 index 00000000..0437b444 --- /dev/null +++ b/docs/locale/uk_UA/LC_MESSAGES/api/methods/get_my_name.po @@ -0,0 +1,68 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../api/methods/get_my_name.rst:3 +msgid "getMyName" +msgstr "" + +#: ../../api/methods/get_my_name.rst:5 +msgid "Returns: :obj:`BotName`" +msgstr "" + +#: aiogram.methods.get_my_name.GetMyName:1 of +msgid "" +"Use this method to get the current bot name for the given user language. " +"Returns :class:`aiogram.types.bot_name.BotName` on success." +msgstr "" + +#: aiogram.methods.get_my_name.GetMyName:3 of +msgid "Source: https://core.telegram.org/bots/api#getmyname" +msgstr "" + +#: ../../docstring aiogram.methods.get_my_name.GetMyName.language_code:1 of +msgid "A two-letter ISO 639-1 language code or an empty string" +msgstr "" + +#: ../../api/methods/get_my_name.rst:14 +msgid "Usage" +msgstr "" + +#: ../../api/methods/get_my_name.rst:17 +msgid "As bot method" +msgstr "" + +#: ../../api/methods/get_my_name.rst:25 +msgid "Method as object" +msgstr "" + +#: ../../api/methods/get_my_name.rst:27 +msgid "Imports:" +msgstr "" + +#: ../../api/methods/get_my_name.rst:29 +msgid ":code:`from aiogram.methods.get_my_name import GetMyName`" +msgstr "" + +#: ../../api/methods/get_my_name.rst:30 +msgid "alias: :code:`from aiogram.methods import GetMyName`" +msgstr "" + +#: ../../api/methods/get_my_name.rst:33 +msgid "With specific bot" +msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/methods/get_updates.po b/docs/locale/uk_UA/LC_MESSAGES/api/methods/get_updates.po index e64a0df6..39a54f54 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/methods/get_updates.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/methods/get_updates.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 22:51+0300\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/methods/get_updates.rst:3 msgid "getUpdates" @@ -59,7 +59,7 @@ msgid "" ":class:`aiogram.methods.get_updates.GetUpdates` is called with an " "*offset* higher than its *update_id*. The negative offset can be " "specified to retrieve updates starting from *-offset* update from the end" -" of the updates queue. All previous updates will forgotten." +" of the updates queue. All previous updates will be forgotten." msgstr "" #: ../../docstring aiogram.methods.get_updates.GetUpdates.limit:1 of @@ -113,3 +113,21 @@ msgstr "" #: ../../api/methods/get_updates.rst:33 msgid "With specific bot" msgstr "" + +#~ msgid "" +#~ "Identifier of the first update to " +#~ "be returned. Must be greater by " +#~ "one than the highest among the " +#~ "identifiers of previously received updates." +#~ " By default, updates starting with " +#~ "the earliest unconfirmed update are " +#~ "returned. An update is considered " +#~ "confirmed as soon as " +#~ ":class:`aiogram.methods.get_updates.GetUpdates` is called" +#~ " with an *offset* higher than its " +#~ "*update_id*. The negative offset can be" +#~ " specified to retrieve updates starting " +#~ "from *-offset* update from the end " +#~ "of the updates queue. All previous " +#~ "updates will forgotten." +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/methods/set_my_name.po b/docs/locale/uk_UA/LC_MESSAGES/api/methods/set_my_name.po new file mode 100644 index 00000000..b5befc8d --- /dev/null +++ b/docs/locale/uk_UA/LC_MESSAGES/api/methods/set_my_name.po @@ -0,0 +1,78 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../api/methods/set_my_name.rst:3 +msgid "setMyName" +msgstr "" + +#: ../../api/methods/set_my_name.rst:5 +msgid "Returns: :obj:`bool`" +msgstr "" + +#: aiogram.methods.set_my_name.SetMyName:1 of +msgid "Use this method to change the bot's name. Returns :code:`True` on success." +msgstr "" + +#: aiogram.methods.set_my_name.SetMyName:3 of +msgid "Source: https://core.telegram.org/bots/api#setmyname" +msgstr "" + +#: ../../docstring aiogram.methods.set_my_name.SetMyName.name:1 of +msgid "" +"New bot name; 0-64 characters. Pass an empty string to remove the " +"dedicated name for the given language." +msgstr "" + +#: ../../docstring aiogram.methods.set_my_name.SetMyName.language_code:1 of +msgid "" +"A two-letter ISO 639-1 language code. If empty, the name will be shown to" +" all users for whose language there is no dedicated name." +msgstr "" + +#: ../../api/methods/set_my_name.rst:14 +msgid "Usage" +msgstr "" + +#: ../../api/methods/set_my_name.rst:17 +msgid "As bot method" +msgstr "" + +#: ../../api/methods/set_my_name.rst:25 +msgid "Method as object" +msgstr "" + +#: ../../api/methods/set_my_name.rst:27 +msgid "Imports:" +msgstr "" + +#: ../../api/methods/set_my_name.rst:29 +msgid ":code:`from aiogram.methods.set_my_name import SetMyName`" +msgstr "" + +#: ../../api/methods/set_my_name.rst:30 +msgid "alias: :code:`from aiogram.methods import SetMyName`" +msgstr "" + +#: ../../api/methods/set_my_name.rst:33 +msgid "With specific bot" +msgstr "" + +#: ../../api/methods/set_my_name.rst:40 +msgid "As reply into Webhook in handler" +msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/session/base.po b/docs/locale/uk_UA/LC_MESSAGES/api/session/base.po index 3587676e..413eafd2 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/session/base.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/session/base.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 22:51+0300\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/session/base.rst:3 msgid "Base" @@ -29,10 +29,6 @@ msgstr "" msgid "Check response status" msgstr "" -#: aiogram.client.session.base.BaseSession.clean_json:1 of -msgid "Clean data before send" -msgstr "" - #: aiogram.client.session.base.BaseSession.close:1 of msgid "Close client session" msgstr "" @@ -72,3 +68,6 @@ msgstr "" #: aiogram.client.session.base.BaseSession.stream_content:1 of msgid "Stream reader" msgstr "" + +#~ msgid "Clean data before send" +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/bot_name.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/bot_name.po new file mode 100644 index 00000000..64e89253 --- /dev/null +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/bot_name.po @@ -0,0 +1,34 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../api/types/bot_name.rst:3 +msgid "BotName" +msgstr "" + +#: aiogram.types.bot_name.BotName:1 of +msgid "This object represents the bot's name." +msgstr "" + +#: aiogram.types.bot_name.BotName:3 of +msgid "Source: https://core.telegram.org/bots/api#botname" +msgstr "" + +#: ../../docstring aiogram.types.bot_name.BotName.name:1 of +msgid "The bot's name" +msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/chat_member_updated.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/chat_member_updated.po index a362821e..756e5b94 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/types/chat_member_updated.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/chat_member_updated.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 22:51+0300\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/chat_member_updated.rst:3 msgid "ChatMemberUpdated" @@ -60,3 +60,11 @@ msgid "" "*Optional*. Chat invite link, which was used by the user to join the " "chat; for joining by invite link events only." msgstr "" + +#: ../../docstring +#: aiogram.types.chat_member_updated.ChatMemberUpdated.via_chat_folder_invite_link:1 +#: of +msgid "" +"*Optional*. True, if the user joined the chat via a chat folder invite " +"link" +msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/index.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/index.po index 8ee34c1a..dd347157 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/types/index.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/index.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-30 22:28+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/index.rst:3 msgid "Types" @@ -29,33 +29,32 @@ msgstr "" msgid "Inline mode" msgstr "" -#: ../../api/types/index.rst:46 +#: ../../api/types/index.rst:47 msgid "Available types" msgstr "" -#: ../../api/types/index.rst:134 +#: ../../api/types/index.rst:143 msgid "Telegram Passport" msgstr "" -#: ../../api/types/index.rst:155 +#: ../../api/types/index.rst:164 msgid "Getting updates" msgstr "" -#: ../../api/types/index.rst:164 +#: ../../api/types/index.rst:173 msgid "Stickers" msgstr "" -#: ../../api/types/index.rst:174 +#: ../../api/types/index.rst:184 msgid "Payments" msgstr "" -#: ../../api/types/index.rst:189 -msgid "Games" -msgstr "" - #: ../../api/types/index.rst:199 -msgid "Internals" +msgid "Games" msgstr "" #~ msgid "Internal events" #~ msgstr "" + +#~ msgid "Internals" +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_keyboard_button.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_keyboard_button.po index 7e6bedbe..3db47e31 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_keyboard_button.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_keyboard_button.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 22:51+0300\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/inline_keyboard_button.rst:3 msgid "InlineKeyboardButton" @@ -91,6 +91,15 @@ msgid "" "empty, in which case only the bot's username will be inserted." msgstr "" +#: ../../docstring +#: aiogram.types.inline_keyboard_button.InlineKeyboardButton.switch_inline_query_chosen_chat:1 +#: of +msgid "" +"*Optional*. If set, pressing the button will prompt the user to select " +"one of their chats of the specified type, open that chat and insert the " +"bot's username and the specified inline query in the input field" +msgstr "" + #: ../../docstring #: aiogram.types.inline_keyboard_button.InlineKeyboardButton.callback_game:1 of msgid "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_query.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_query.po index 4146b049..f848f5d0 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_query.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_query.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-23 00:47+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/inline_query.rst:3 msgid "InlineQuery" @@ -103,7 +103,7 @@ msgstr "" msgid "" "Pass :code:`True` if results may be cached on the server side only for " "the user that sent the query. By default, results may be returned to any " -"user who sends the same query" +"user who sends the same query." msgstr "" #: aiogram.types.inline_query.InlineQuery.answer:15 of @@ -116,9 +116,8 @@ msgstr "" #: aiogram.types.inline_query.InlineQuery.answer:16 of msgid "" -"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*" +"A JSON-serialized object describing a button to be shown above inline " +"query results" msgstr "" #: aiogram.types.inline_query.InlineQuery.answer:17 of @@ -129,12 +128,28 @@ msgid "" ":code:`0-9`, :code:`_` and :code:`-` are allowed." msgstr "" +#: aiogram.types.inline_query.InlineQuery.answer:18 of +msgid "" +"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*" +msgstr "" + #: aiogram.types.inline_query.InlineQuery.answer of msgid "Returns" msgstr "" -#: aiogram.types.inline_query.InlineQuery.answer:18 of +#: aiogram.types.inline_query.InlineQuery.answer:19 of msgid "" "instance of method " ":class:`aiogram.methods.answer_inline_query.AnswerInlineQuery`" msgstr "" + +#~ msgid "" +#~ "Pass :code:`True` if results may be " +#~ "cached on the server side only for" +#~ " the user that sent the query. " +#~ "By default, results may be returned " +#~ "to any user who sends the same " +#~ "query" +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_query_results_button.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_query_results_button.po new file mode 100644 index 00000000..3dcf4f0f --- /dev/null +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/inline_query_results_button.po @@ -0,0 +1,59 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../api/types/inline_query_results_button.rst:3 +msgid "InlineQueryResultsButton" +msgstr "" + +#: aiogram.types.inline_query_results_button.InlineQueryResultsButton:1 of +msgid "" +"This object represents a button to be shown above inline query results. " +"You **must** use exactly one of the optional fields." +msgstr "" + +#: aiogram.types.inline_query_results_button.InlineQueryResultsButton:3 of +msgid "Source: https://core.telegram.org/bots/api#inlinequeryresultsbutton" +msgstr "" + +#: ../../docstring +#: aiogram.types.inline_query_results_button.InlineQueryResultsButton.text:1 of +msgid "Label text on the button" +msgstr "" + +#: ../../docstring +#: aiogram.types.inline_query_results_button.InlineQueryResultsButton.web_app:1 +#: of +msgid "" +"*Optional*. Description of the `Web App " +"`_ that will be launched when the" +" user presses the button. The Web App will be able to switch back to the " +"inline mode using the method `switchInlineQuery " +"`_ inside " +"the Web App." +msgstr "" + +#: ../../docstring +#: aiogram.types.inline_query_results_button.InlineQueryResultsButton.start_parameter:1 +#: of +msgid "" +"*Optional*. `Deep-linking `_ parameter for the /start message sent to the bot when a user " +"presses the button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, " +":code:`0-9`, :code:`_` and :code:`-` are allowed." +msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/input_sticker.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/input_sticker.po index 3bbc8b33..fb2433c4 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/types/input_sticker.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/input_sticker.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-11 01:52+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.11.0\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/input_sticker.rst:3 msgid "InputSticker" @@ -33,9 +33,11 @@ msgstr "" msgid "" "The added sticker. Pass a *file_id* as a String to send a file that " "already exists on the Telegram servers, pass an HTTP URL as a String for " -"Telegram to get a file from the Internet, or upload a new one using " -"multipart/form-data. Animated and video stickers can't be uploaded via " -"HTTP URL. :ref:`More information on Sending Files » `" +"Telegram to get a file from the Internet, upload a new one using " +"multipart/form-data, or pass 'attach://' to upload a " +"new one using multipart/form-data under name. Animated" +" and video stickers can't be uploaded via HTTP URL. :ref:`More " +"information on Sending Files » `" msgstr "" #: ../../docstring aiogram.types.input_sticker.InputSticker.emoji_list:1 of @@ -54,3 +56,17 @@ msgid "" "length of up to 64 characters. For 'regular' and 'custom_emoji' stickers " "only." msgstr "" + +#~ msgid "" +#~ "The added sticker. Pass a *file_id* " +#~ "as a String to send a file " +#~ "that already exists on the Telegram " +#~ "servers, pass an HTTP URL as a " +#~ "String for Telegram to get a file" +#~ " from the Internet, or upload a " +#~ "new one using multipart/form-data. " +#~ "Animated and video stickers can't be " +#~ "uploaded via HTTP URL. :ref:`More " +#~ "information on Sending Files » " +#~ "`" +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/keyboard_button_request_chat.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/keyboard_button_request_chat.po index 392f3b2e..2912a3f0 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/types/keyboard_button_request_chat.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/keyboard_button_request_chat.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-02-12 00:22+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/keyboard_button_request_chat.rst:3 msgid "KeyboardButtonRequestChat" @@ -25,7 +25,8 @@ msgstr "" msgid "" "This object defines the criteria used to request a suitable chat. The " "identifier of the selected chat will be shared with the bot when the " -"corresponding button is pressed." +"corresponding button is pressed. `More about requesting chats » " +"`_" msgstr "" #: aiogram.types.keyboard_button_request_chat.KeyboardButtonRequestChat:3 of @@ -103,3 +104,10 @@ msgid "" " Otherwise, no additional restrictions are applied." msgstr "" +#~ msgid "" +#~ "This object defines the criteria used" +#~ " to request a suitable chat. The " +#~ "identifier of the selected chat will " +#~ "be shared with the bot when the" +#~ " corresponding button is pressed." +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/keyboard_button_request_user.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/keyboard_button_request_user.po index a6b317ec..1e0bca68 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/types/keyboard_button_request_user.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/keyboard_button_request_user.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-02-12 00:22+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/keyboard_button_request_user.rst:3 msgid "KeyboardButtonRequestUser" @@ -25,7 +25,8 @@ msgstr "" msgid "" "This object defines the criteria used to request a suitable user. The " "identifier of the selected user will be shared with the bot when the " -"corresponding button is pressed." +"corresponding button is pressed. `More about requesting users » " +"`_" msgstr "" #: aiogram.types.keyboard_button_request_user.KeyboardButtonRequestUser:3 of @@ -59,3 +60,10 @@ msgid "" "additional restrictions are applied." msgstr "" +#~ msgid "" +#~ "This object defines the criteria used" +#~ " to request a suitable user. The " +#~ "identifier of the selected user will " +#~ "be shared with the bot when the" +#~ " corresponding button is pressed." +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/switch_inline_query_chosen_chat.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/switch_inline_query_chosen_chat.po new file mode 100644 index 00000000..3b8f431d --- /dev/null +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/switch_inline_query_chosen_chat.po @@ -0,0 +1,66 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../api/types/switch_inline_query_chosen_chat.rst:3 +msgid "SwitchInlineQueryChosenChat" +msgstr "" + +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat:1 +#: of +msgid "" +"This object represents an inline button that switches the current user to" +" inline mode in a chosen chat, with an optional default inline query." +msgstr "" + +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat:3 +#: of +msgid "Source: https://core.telegram.org/bots/api#switchinlinequerychosenchat" +msgstr "" + +#: ../../docstring +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat.query:1 +#: of +msgid "" +"*Optional*. The default inline query to be inserted in the input field. " +"If left empty, only the bot's username will be inserted" +msgstr "" + +#: ../../docstring +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat.allow_user_chats:1 +#: of +msgid "*Optional*. True, if private chats with users can be chosen" +msgstr "" + +#: ../../docstring +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat.allow_bot_chats:1 +#: of +msgid "*Optional*. True, if private chats with bots can be chosen" +msgstr "" + +#: ../../docstring +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat.allow_group_chats:1 +#: of +msgid "*Optional*. True, if group and supergroup chats can be chosen" +msgstr "" + +#: ../../docstring +#: aiogram.types.switch_inline_query_chosen_chat.SwitchInlineQueryChosenChat.allow_channel_chats:1 +#: of +msgid "*Optional*. True, if channel chats can be chosen" +msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/types/write_access_allowed.po b/docs/locale/uk_UA/LC_MESSAGES/api/types/write_access_allowed.po index e2754dd2..4fee2157 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/types/write_access_allowed.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/types/write_access_allowed.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-30 22:28+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/types/write_access_allowed.rst:3 msgid "WriteAccessAllowed" @@ -23,11 +23,24 @@ msgstr "" #: aiogram.types.write_access_allowed.WriteAccessAllowed:1 of msgid "" -"This object represents a service message about a user allowing a bot " -"added to the attachment menu to write messages. Currently holds no " -"information." +"This object represents a service message about a user allowing a bot to " +"write messages after adding the bot to the attachment menu or launching a" +" Web App from a link." msgstr "" #: aiogram.types.write_access_allowed.WriteAccessAllowed:3 of msgid "Source: https://core.telegram.org/bots/api#writeaccessallowed" msgstr "" + +#: ../../docstring +#: aiogram.types.write_access_allowed.WriteAccessAllowed.web_app_name:1 of +msgid "*Optional*. Name of the Web App which was launched from a link" +msgstr "" + +#~ msgid "" +#~ "This object represents a service message" +#~ " about a user allowing a bot " +#~ "added to the attachment menu to " +#~ "write messages. Currently holds no " +#~ "information." +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/upload_file.po b/docs/locale/uk_UA/LC_MESSAGES/api/upload_file.po index 0506fffc..693fc1ea 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/upload_file.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/upload_file.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-11 01:52+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: 2022-12-13 21:40+0200\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.11.0\n" +"Generated-By: Babel 2.12.1\n" #: ../../api/upload_file.rst:5 msgid "How to upload file?" @@ -42,7 +42,7 @@ msgstr "" #, fuzzy msgid "" "But if you need to upload a new file just use subclasses of `InputFile " -"`__." +"`__." msgstr "" "Але якщо вам потрібно завантажити новий файл, просто використовуйте " "підкласи `InputFile `__." diff --git a/docs/locale/uk_UA/LC_MESSAGES/changelog.po b/docs/locale/uk_UA/LC_MESSAGES/changelog.po index eb5c4ffc..8c342278 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/changelog.po +++ b/docs/locale/uk_UA/LC_MESSAGES/changelog.po @@ -8,59 +8,240 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-11 01:52+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.11.0\n" +"Generated-By: Babel 2.12.1\n" #: ../../../CHANGES.rst:3 msgid "Changelog" msgstr "" #: ../../[towncrier-fragments]:2 -msgid "\\ |release| [UNRELEASED DRAFT] (2023-03-11)" +msgid "\\ |release| [UNRELEASED DRAFT] (2023-07-02)" msgstr "" -#: ../../../CHANGES.rst:193 ../../../CHANGES.rst:243 ../../../CHANGES.rst:623 +#: ../../../CHANGES.rst:56 ../../../CHANGES.rst:156 ../../../CHANGES.rst:216 +#: ../../../CHANGES.rst:267 ../../../CHANGES.rst:340 ../../../CHANGES.rst:381 +#: ../../../CHANGES.rst:419 ../../../CHANGES.rst:467 ../../../CHANGES.rst:543 +#: ../../../CHANGES.rst:576 ../../../CHANGES.rst:607 #: ../../[towncrier-fragments]:5 -msgid "Improved Documentation" +msgid "Features" msgstr "" #: ../../[towncrier-fragments]:7 msgid "" +"If router does not support custom event it does not break and passes it " +"to included routers `#1147 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:9 +msgid "Added support for FSM in Forum topics." +msgstr "" + +#: ../../[towncrier-fragments]:11 +msgid "The strategy can be changed in dispatcher:" +msgstr "" + +#: ../../[towncrier-fragments]:24 +msgid "" +"If you have implemented you own storages you should extend record key " +"generation with new one attribute - `thread_id`" +msgstr "" + +#: ../../[towncrier-fragments]:26 +msgid "`#1161 `_" +msgstr "" + +#: ../../[towncrier-fragments]:27 +msgid "Improved CallbackData serialization." +msgstr "" + +#: ../../[towncrier-fragments]:29 +msgid "Minimized UUID (hex without dashes)" +msgstr "" + +#: ../../[towncrier-fragments]:30 +msgid "Replaced bool values with int (true=1, false=0)" +msgstr "" + +#: ../../[towncrier-fragments]:31 +msgid "`#1163 `_" +msgstr "" + +#: ../../[towncrier-fragments]:32 +msgid "" +"Added a tool to make text formatting flexible and easy. More details on " +"the :ref:`corresponding documentation page ` `#1172 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:35 +msgid "" +"Added X-Telegram-Bot-Api-Secret-Token header check `#1173 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:37 +msgid "" +"Added possibility to pass custom headers to URLInputFile object `#1191 " +"`_" +msgstr "" + +#: ../../../CHANGES.rst:118 ../../../CHANGES.rst:181 ../../../CHANGES.rst:230 +#: ../../../CHANGES.rst:291 ../../../CHANGES.rst:349 ../../../CHANGES.rst:395 +#: ../../../CHANGES.rst:443 ../../../CHANGES.rst:499 ../../../CHANGES.rst:584 +#: ../../../CHANGES.rst:616 ../../[towncrier-fragments]:42 +msgid "Bugfixes" +msgstr "" + +#: ../../[towncrier-fragments]:44 +msgid "" +"Change type of result in InlineQueryResult enum for " +"`InlineQueryResultCachedMpeg4Gif` and `InlineQueryResultMpeg4Gif` to more" +" correct according to documentation." +msgstr "" + +#: ../../[towncrier-fragments]:47 +msgid "" +"Change regexp for entities parsing to more correct " +"(`InlineQueryResultType.yml`). `#1146 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:49 +msgid "" +"Fixed signature of startup/shutdown events to include the " +"**dispatcher.workflow_data as the handler arguments. `#1155 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:51 +msgid "" +"Added missing FORUM_TOPIC_EDITED value to content_type property `#1160 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:53 +msgid "" +"Fixed compatibility with Python 3.8-3.9 `#1162 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:55 +msgid "" +"Fixed the markdown spoiler parser. `#1176 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:57 +msgid "" +"Fixed workflow data propagation `#1196 " +"`_" +msgstr "" + +#: ../../../CHANGES.rst:193 ../../../CHANGES.rst:243 ../../../CHANGES.rst:623 +#: ../../[towncrier-fragments]:62 +msgid "Improved Documentation" +msgstr "" + +#: ../../[towncrier-fragments]:64 +msgid "" "Changed small grammar typos for `upload_file` `#1133 " "`_" msgstr "" +#: ../../../CHANGES.rst:250 ../../[towncrier-fragments]:69 +msgid "Deprecations and Removals" +msgstr "" + +#: ../../[towncrier-fragments]:71 +msgid "" +"Removed text filter in due to is planned to remove this filter few " +"versions ago." +msgstr "" + +#: ../../[towncrier-fragments]:73 +msgid "" +"Use :code:`F.text` instead `#1170 " +"`_" +msgstr "" + #: ../../../CHANGES.rst:127 ../../../CHANGES.rst:204 ../../../CHANGES.rst:257 #: ../../../CHANGES.rst:308 ../../../CHANGES.rst:362 ../../../CHANGES.rst:404 #: ../../../CHANGES.rst:450 ../../../CHANGES.rst:510 ../../../CHANGES.rst:531 #: ../../../CHANGES.rst:554 ../../../CHANGES.rst:591 ../../../CHANGES.rst:630 -#: ../../[towncrier-fragments]:12 +#: ../../[towncrier-fragments]:78 msgid "Misc" msgstr "" -#: ../../[towncrier-fragments]:14 +#: ../../[towncrier-fragments]:80 msgid "" "Added full support of `Bot API 6.6 `_" msgstr "" -#: ../../[towncrier-fragments]:18 +#: ../../[towncrier-fragments]:84 msgid "" "Note that this issue has breaking changes described in in the Bot API " "changelog, this changes is not breaking in the API but breaking inside " "aiogram because Beta stage is not finished." msgstr "" -#: ../../[towncrier-fragments]:21 +#: ../../[towncrier-fragments]:87 msgid "`#1139 `_" msgstr "" +#: ../../[towncrier-fragments]:88 +msgid "" +"Added global defaults `disable_web_page_preview` and `protect_content` in" +" addition to `parse_mode` to the Bot instance, reworked internal request " +"builder mechanism. `#1142 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:91 +msgid "" +"Removed bot parameters from storages `#1144 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:93 +msgid "" +"Added full support of `Bot API 6.7 `_" +msgstr "" + +#: ../../[towncrier-fragments]:97 +msgid "" +"Note that arguments *switch_pm_parameter* and *switch_pm_text* was " +"deprecated and should be changed to *button* argument as described in API" +" docs." +msgstr "" + +#: ../../[towncrier-fragments]:99 +msgid "`#1168 `_" +msgstr "" + +#: ../../[towncrier-fragments]:100 +msgid "Updated `Pydantic to V2 `_" +msgstr "" + +#: ../../[towncrier-fragments]:104 +msgid "" +"Be careful, not all libraries is already updated to using V2 (for example" +" at the time, when this warning was added FastAPI still not support V2)" +msgstr "" + +#: ../../[towncrier-fragments]:106 +msgid "`#1202 `_" +msgstr "" + #: ../../../CHANGES.rst:20 msgid "3.0.0b7 (2023-02-18)" msgstr "" @@ -83,13 +264,6 @@ msgstr "" msgid "But if you change it like this it should works as well:" msgstr "" -#: ../../../CHANGES.rst:56 ../../../CHANGES.rst:156 ../../../CHANGES.rst:216 -#: ../../../CHANGES.rst:267 ../../../CHANGES.rst:340 ../../../CHANGES.rst:381 -#: ../../../CHANGES.rst:419 ../../../CHANGES.rst:467 ../../../CHANGES.rst:543 -#: ../../../CHANGES.rst:576 ../../../CHANGES.rst:607 -msgid "Features" -msgstr "" - #: ../../../CHANGES.rst:58 msgid "Added missing shortcuts, new enums, reworked old stuff" msgstr "" @@ -189,13 +363,6 @@ msgid "" "`_" msgstr "" -#: ../../../CHANGES.rst:118 ../../../CHANGES.rst:181 ../../../CHANGES.rst:230 -#: ../../../CHANGES.rst:291 ../../../CHANGES.rst:349 ../../../CHANGES.rst:395 -#: ../../../CHANGES.rst:443 ../../../CHANGES.rst:499 ../../../CHANGES.rst:584 -#: ../../../CHANGES.rst:616 -msgid "Bugfixes" -msgstr "" - #: ../../../CHANGES.rst:120 msgid "" "Check status code when downloading file `#816 " @@ -459,10 +626,6 @@ msgid "" "`_" msgstr "" -#: ../../../CHANGES.rst:250 -msgid "Deprecations and Removals" -msgstr "" - #: ../../../CHANGES.rst:252 msgid "" "Removed filters factory as described in corresponding issue. `#942 " @@ -2621,3 +2784,6 @@ msgstr "" #~ ":class:`aiogram.enums.topic_icon_color.TopicIconColor`, " #~ ":class:`aiogram.enums.update_type.UpdateType`," #~ msgstr "" + +#~ msgid "\\ |release| [UNRELEASED DRAFT] (2023-03-11)" +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/dispatcher/filters/text.po b/docs/locale/uk_UA/LC_MESSAGES/dispatcher/filters/text.po index a19ae4ad..b5b6c91d 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/dispatcher/filters/text.po +++ b/docs/locale/uk_UA/LC_MESSAGES/dispatcher/filters/text.po @@ -1,24 +1,25 @@ # SOME DESCRIPTIVE TITLE. -# Copyright (C) 2022, aiogram Team +# Copyright (C) 2023, aiogram Team # This file is distributed under the same license as the aiogram package. -# FIRST AUTHOR , 2022. +# FIRST AUTHOR , 2023. # +#, fuzzy msgid "" msgstr "" -"Project-Id-Version: aiogram\n" +"Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-25 22:10+0300\n" -"PO-Revision-Date: 2022-10-25 17:49+0300\n" -"Last-Translator: \n" -"Language-Team: \n" +"POT-Creation-Date: 2023-01-07 23:01+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../dispatcher/filters/text.rst:3 msgid "Text" -msgstr "Текст" +msgstr "" #: aiogram.filters.text.Text:1 of msgid "" @@ -27,10 +28,6 @@ msgid "" ":class:`aiogram.types.inline_query.InlineQuery` or " ":class:`aiogram.types.poll.Poll` question." msgstr "" -"Корисно для фільтрації тексту :class:`aiogram.types.message.Message`, " -"будь-якого :class:`aiogram.types.callback_query.CallbackQuery` з `data`, " -":class:`aiogram.types.inline_query.InlineQuery` або : " -"class:`aiogram.types.poll.Poll` опитування." #: aiogram.filters.text.Text:7 of msgid "" @@ -38,65 +35,52 @@ msgid "" "be used at once. Any of that arguments can be string, list, set or tuple " "of strings." msgstr "" -"Одночасно можна використати лише один із аргументів `text`, `contains`, " -"`startswith` або `endswith` . Будь-який із цих аргументів може бути " -"рядком, списком, набором (set) або кортежем рядків." #: aiogram.filters.text.Text:12 of msgid "" "use :ref:`magic-filter `. For example do :pycode:`F.text " "== \"text\"` instead" msgstr "" -"використати :ref:`magic-filter `. Наприклад " -":pycode:`F.text == \"text\"` instead" #: ../../dispatcher/filters/text.rst:10 msgid "Can be imported:" -msgstr "Можна імпортувати:" +msgstr "" #: ../../dispatcher/filters/text.rst:12 msgid ":code:`from aiogram.filters.text import Text`" -msgstr ":code:`from aiogram.filters.text import Text`" +msgstr "" #: ../../dispatcher/filters/text.rst:13 msgid ":code:`from aiogram.filters import Text`" -msgstr ":code:`from aiogram.filters import Text`" +msgstr "" #: ../../dispatcher/filters/text.rst:16 msgid "Usage" -msgstr "Використання" +msgstr "" #: ../../dispatcher/filters/text.rst:18 msgid "" "Text equals with the specified value: :code:`Text(text=\"text\") # value" " == 'text'`" msgstr "" -"Текст дорівнює вказаному значенню: :code:`Text(text=\"text\") # value ==" -" 'text'`" #: ../../dispatcher/filters/text.rst:19 msgid "" "Text starts with the specified value: :code:`Text(startswith=\"text\") #" " value.startswith('text')`" msgstr "" -"Текст починається з указаного значення: :code:`Text(startswith=\"text\")" -" # value.startswith('text')`" #: ../../dispatcher/filters/text.rst:20 msgid "" "Text ends with the specified value: :code:`Text(endswith=\"text\") # " "value.endswith('text')`" msgstr "" -"Текст закінчується вказаним значенням: :code:`Text(endswith=\"text\") # " -"value.endswith('text')`" #: ../../dispatcher/filters/text.rst:21 msgid "" "Text contains the specified value: :code:`Text(contains=\"text\") # " "value in 'text'`" msgstr "" -"Текст містить вказане значення: :code:`Text(contains=\"text\") # value " -"in 'text'`" #: ../../dispatcher/filters/text.rst:22 msgid "" @@ -105,10 +89,6 @@ msgid "" "equals/startswith/endswith/contains: :code:`Text(text=[\"text\", " "\"spam\"])`" msgstr "" -"Будь-який із попередніх перерахованих фільтрів може бути списком, набором" -" або кортежем рядків, що означає, що будь-яке значення у списку має " -"дорівнювати/починатися/закінчуватися/містити: :code:`Text(text=[\"text\"," -" \"spam\"])`" #: ../../dispatcher/filters/text.rst:23 msgid "" @@ -116,38 +96,35 @@ msgid "" ":code:`Text(text=\"Text\", ignore_case=True) # value.lower() == " "'text'.lower()`" msgstr "" -"Ігнорування регістру можна поєднати з будь-яким фільтром із попереднього " -"списку: :code:`Text(text=\"Text\", ignore_case=True) # value.lower() == " -"'text'.lower()`" #: ../../dispatcher/filters/text.rst:26 msgid "Allowed handlers" -msgstr "Дозволені обробники (handlers)" +msgstr "" #: ../../dispatcher/filters/text.rst:28 msgid "Allowed update types for this filter:" -msgstr "Дозволені типи оновлень для цього фільтра:" +msgstr "" #: ../../dispatcher/filters/text.rst:30 msgid ":code:`message`" -msgstr ":code:`message`" +msgstr "" #: ../../dispatcher/filters/text.rst:31 msgid ":code:`edited_message`" -msgstr ":code:`edited_message`" +msgstr "" #: ../../dispatcher/filters/text.rst:32 msgid ":code:`channel_post`" -msgstr ":code:`channel_post`" +msgstr "" #: ../../dispatcher/filters/text.rst:33 msgid ":code:`edited_channel_post`" -msgstr ":code:`edited_channel_post`" +msgstr "" #: ../../dispatcher/filters/text.rst:34 msgid ":code:`inline_query`" -msgstr ":code:`inline_query`" +msgstr "" #: ../../dispatcher/filters/text.rst:35 msgid ":code:`callback_query`" -msgstr ":code:`callback_query`" +msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/dispatcher/finite_state_machine/storages.po b/docs/locale/uk_UA/LC_MESSAGES/dispatcher/finite_state_machine/storages.po index 48a899f8..dd8a43f3 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/dispatcher/finite_state_machine/storages.po +++ b/docs/locale/uk_UA/LC_MESSAGES/dispatcher/finite_state_machine/storages.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-02 22:41+0200\n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" "PO-Revision-Date: 2022-10-20 22:00+0300\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.12.1\n" #: ../../dispatcher/finite_state_machine/storages.rst:3 msgid "Storages" @@ -83,10 +83,6 @@ msgstr "" msgid "TTL for data records" msgstr "" -#: aiogram.fsm.storage.redis.RedisStorage.__init__:5 of -msgid "Custom arguments for Redis lock" -msgstr "" - #: aiogram.fsm.storage.redis.RedisStorage.from_url:1 of msgid "" "Create an instance of :class:`RedisStorage` with specifying the " @@ -175,18 +171,10 @@ msgstr "Установити стан для вказаного ключа" #: aiogram.fsm.storage.base.BaseStorage.set_data:3 #: aiogram.fsm.storage.base.BaseStorage.set_state:3 #: aiogram.fsm.storage.base.BaseStorage.update_data:3 of -msgid "instance of the current bot" -msgstr "екземпляр поточного бота" - -#: aiogram.fsm.storage.base.BaseStorage.get_data:4 -#: aiogram.fsm.storage.base.BaseStorage.get_state:4 -#: aiogram.fsm.storage.base.BaseStorage.set_data:4 -#: aiogram.fsm.storage.base.BaseStorage.set_state:4 -#: aiogram.fsm.storage.base.BaseStorage.update_data:4 of msgid "storage key" msgstr "ключ сховища" -#: aiogram.fsm.storage.base.BaseStorage.set_state:5 of +#: aiogram.fsm.storage.base.BaseStorage.set_state:4 of msgid "new state" msgstr "новий стан" @@ -194,7 +182,7 @@ msgstr "новий стан" msgid "Get key state" msgstr "Отримання стану ключа" -#: aiogram.fsm.storage.base.BaseStorage.get_state:5 of +#: aiogram.fsm.storage.base.BaseStorage.get_state:4 of msgid "current state" msgstr "поточний стан" @@ -202,8 +190,8 @@ msgstr "поточний стан" msgid "Write data (replace)" msgstr "Запис даних (заміна)" -#: aiogram.fsm.storage.base.BaseStorage.set_data:5 -#: aiogram.fsm.storage.base.BaseStorage.update_data:6 of +#: aiogram.fsm.storage.base.BaseStorage.set_data:4 +#: aiogram.fsm.storage.base.BaseStorage.update_data:5 of msgid "new data" msgstr "нові дані" @@ -211,7 +199,7 @@ msgstr "нові дані" msgid "Get current data for key" msgstr "Отримання поточних даних для ключа" -#: aiogram.fsm.storage.base.BaseStorage.get_data:5 of +#: aiogram.fsm.storage.base.BaseStorage.get_data:4 of msgid "current data" msgstr "нинішні дані" @@ -219,10 +207,16 @@ msgstr "нинішні дані" msgid "Update date in the storage for key (like dict.update)" msgstr "Дата оновлення в сховищі для ключа (наприклад, dict.update)" -#: aiogram.fsm.storage.base.BaseStorage.update_data:5 of +#: aiogram.fsm.storage.base.BaseStorage.update_data:4 of msgid "partial data" msgstr "неповні дані" #: aiogram.fsm.storage.base.BaseStorage.close:1 of msgid "Close storage (database connection, file or etc.)" msgstr "Закриття сховища (підключення до бази даних, файлу тощо)" + +#~ msgid "Custom arguments for Redis lock" +#~ msgstr "" + +#~ msgid "instance of the current bot" +#~ msgstr "екземпляр поточного бота" diff --git a/docs/locale/uk_UA/LC_MESSAGES/utils/formatting.po b/docs/locale/uk_UA/LC_MESSAGES/utils/formatting.po new file mode 100644 index 00000000..49966ca8 --- /dev/null +++ b/docs/locale/uk_UA/LC_MESSAGES/utils/formatting.po @@ -0,0 +1,439 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, aiogram Team +# This file is distributed under the same license as the aiogram package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: aiogram \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-02 15:10+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../utils/formatting.rst:5 +msgid "Formatting" +msgstr "" + +#: ../../utils/formatting.rst:7 +msgid "Make your message formatting flexible and simple" +msgstr "" + +#: ../../utils/formatting.rst:9 +msgid "" +"This instrument works on top of Message entities instead of using HTML or" +" Markdown markups, you can easily construct your message and sent it to " +"the Telegram without the need to remember tag parity (opening and " +"closing) or escaping user input." +msgstr "" + +#: ../../utils/formatting.rst:14 +msgid "Usage" +msgstr "" + +#: ../../utils/formatting.rst:17 +msgid "Basic scenario" +msgstr "" + +#: ../../utils/formatting.rst:19 +msgid "Construct your message and send it to the Telegram." +msgstr "" + +#: ../../utils/formatting.rst:26 +msgid "Is the same as the next example, but without usage markup" +msgstr "" + +#: ../../utils/formatting.rst:35 +msgid "" +"Literally when you execute :code:`as_kwargs` method the Text object is " +"converted into text :code:`Hello, Alex!` with entities list " +":code:`[MessageEntity(type='bold', offset=7, length=4)]` and passed into " +"dict which can be used as :code:`**kwargs` in API call." +msgstr "" + +#: ../../utils/formatting.rst:39 +msgid "" +"The complete list of elements is listed `on this page below <#available-" +"elements>`_." +msgstr "" + +#: ../../utils/formatting.rst:42 +msgid "Advanced scenario" +msgstr "" + +#: ../../utils/formatting.rst:44 +msgid "" +"On top of base elements can be implemented content rendering structures, " +"so, out of the box aiogram has a few already implemented functions that " +"helps you to format your messages:" +msgstr "" + +#: aiogram.utils.formatting.as_line:1 of +msgid "Wrap multiple nodes into line with :code:`\\\\n` at the end of line." +msgstr "" + +#: aiogram.utils.formatting.Text.as_kwargs +#: aiogram.utils.formatting.as_key_value aiogram.utils.formatting.as_line +#: aiogram.utils.formatting.as_list aiogram.utils.formatting.as_marked_list +#: aiogram.utils.formatting.as_marked_section +#: aiogram.utils.formatting.as_numbered_list +#: aiogram.utils.formatting.as_numbered_section +#: aiogram.utils.formatting.as_section of +msgid "Parameters" +msgstr "" + +#: aiogram.utils.formatting.as_line:3 of +msgid "Text or Any" +msgstr "" + +#: aiogram.utils.formatting.as_line:4 of +msgid "ending of the line, by default is :code:`\\\\n`" +msgstr "" + +#: aiogram.utils.formatting.Text.as_kwargs aiogram.utils.formatting.Text.render +#: aiogram.utils.formatting.as_key_value aiogram.utils.formatting.as_line +#: aiogram.utils.formatting.as_list aiogram.utils.formatting.as_marked_list +#: aiogram.utils.formatting.as_marked_section +#: aiogram.utils.formatting.as_numbered_list +#: aiogram.utils.formatting.as_numbered_section +#: aiogram.utils.formatting.as_section of +msgid "Returns" +msgstr "" + +#: aiogram.utils.formatting.as_key_value:5 aiogram.utils.formatting.as_line:5 +#: aiogram.utils.formatting.as_marked_list:5 +#: aiogram.utils.formatting.as_numbered_list:6 +#: aiogram.utils.formatting.as_section:5 of +msgid "Text" +msgstr "" + +#: aiogram.utils.formatting.as_list:1 of +msgid "Wrap each element to separated lines" +msgstr "" + +#: aiogram.utils.formatting.as_marked_list:1 of +msgid "Wrap elements as marked list" +msgstr "" + +#: aiogram.utils.formatting.as_marked_list:4 of +msgid "line marker, by default is :code:`- `" +msgstr "" + +#: aiogram.utils.formatting.as_numbered_list:1 of +msgid "Wrap elements as numbered list" +msgstr "" + +#: aiogram.utils.formatting.as_numbered_list:4 of +msgid "initial number, by default 1" +msgstr "" + +#: aiogram.utils.formatting.as_numbered_list:5 of +msgid "number format, by default :code:`{}. `" +msgstr "" + +#: aiogram.utils.formatting.as_section:1 of +msgid "Wrap elements as simple section, section has title and body" +msgstr "" + +#: aiogram.utils.formatting.as_marked_section:1 of +msgid "Wrap elements as section with marked list" +msgstr "" + +#: aiogram.utils.formatting.as_numbered_section:1 of +msgid "Wrap elements as section with numbered list" +msgstr "" + +#: aiogram.utils.formatting.as_key_value:1 of +msgid "Wrap elements pair as key-value line. (:code:`{key}: {value}`)" +msgstr "" + +#: ../../utils/formatting.rst:64 +msgid "and lets complete them all:" +msgstr "" + +#: ../../utils/formatting.rst:92 +msgid "Will be rendered into:" +msgstr "" + +#: ../../utils/formatting.rst:94 +msgid "**Success:**" +msgstr "" + +#: ../../utils/formatting.rst:96 +msgid "✅ Test 1" +msgstr "" + +#: ../../utils/formatting.rst:98 +msgid "✅ Test 3" +msgstr "" + +#: ../../utils/formatting.rst:100 +msgid "✅ Test 4" +msgstr "" + +#: ../../utils/formatting.rst:102 +msgid "**Failed:**" +msgstr "" + +#: ../../utils/formatting.rst:104 +msgid "❌ Test 2" +msgstr "" + +#: ../../utils/formatting.rst:106 +msgid "**Summary:**" +msgstr "" + +#: ../../utils/formatting.rst:108 +msgid "**Total**: 4" +msgstr "" + +#: ../../utils/formatting.rst:110 +msgid "**Success**: 3" +msgstr "" + +#: ../../utils/formatting.rst:112 +msgid "**Failed**: 1" +msgstr "" + +#: ../../utils/formatting.rst:114 +msgid "#test" +msgstr "" + +#: ../../utils/formatting.rst:117 +msgid "Or as HTML:" +msgstr "" + +#: ../../utils/formatting.rst:137 +msgid "Available methods" +msgstr "" + +#: aiogram.utils.formatting.Text:1 of +msgid "Bases: :py:class:`~typing.Iterable`\\ [:py:obj:`~typing.Any`]" +msgstr "" + +#: aiogram.utils.formatting.Text:1 of +msgid "Simple text element" +msgstr "" + +#: aiogram.utils.formatting.Text.render:1 of +msgid "Render elements tree as text with entities list" +msgstr "" + +#: aiogram.utils.formatting.Text.as_kwargs:1 of +msgid "" +"Render elements tree as keyword arguments for usage in the API call, for " +"example:" +msgstr "" + +#: aiogram.utils.formatting.Text.as_html:1 of +msgid "Render elements tree as HTML markup" +msgstr "" + +#: aiogram.utils.formatting.Text.as_markdown:1 of +msgid "Render elements tree as MarkdownV2 markup" +msgstr "" + +#: ../../utils/formatting.rst:147 +msgid "Available elements" +msgstr "" + +#: aiogram.utils.formatting.Bold:1 aiogram.utils.formatting.BotCommand:1 +#: aiogram.utils.formatting.CashTag:1 aiogram.utils.formatting.Code:1 +#: aiogram.utils.formatting.CustomEmoji:1 aiogram.utils.formatting.Email:1 +#: aiogram.utils.formatting.HashTag:1 aiogram.utils.formatting.Italic:1 +#: aiogram.utils.formatting.PhoneNumber:1 aiogram.utils.formatting.Pre:1 +#: aiogram.utils.formatting.Spoiler:1 aiogram.utils.formatting.Strikethrough:1 +#: aiogram.utils.formatting.TextLink:1 aiogram.utils.formatting.TextMention:1 +#: aiogram.utils.formatting.Underline:1 aiogram.utils.formatting.Url:1 of +msgid "Bases: :py:class:`~aiogram.utils.formatting.Text`" +msgstr "" + +#: aiogram.utils.formatting.HashTag:1 of +msgid "Hashtag element." +msgstr "" + +#: aiogram.utils.formatting.HashTag:5 of +msgid "The value should always start with '#' symbol" +msgstr "" + +#: aiogram.utils.formatting.HashTag:7 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.HASHTAG`" +msgstr "" + +#: aiogram.utils.formatting.CashTag:1 of +msgid "Cashtag element." +msgstr "" + +#: aiogram.utils.formatting.CashTag:5 of +msgid "The value should always start with '$' symbol" +msgstr "" + +#: aiogram.utils.formatting.CashTag:7 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.CASHTAG`" +msgstr "" + +#: aiogram.utils.formatting.BotCommand:1 of +msgid "Bot command element." +msgstr "" + +#: aiogram.utils.formatting.BotCommand:5 of +msgid "The value should always start with '/' symbol" +msgstr "" + +#: aiogram.utils.formatting.BotCommand:7 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.BOT_COMMAND`" +msgstr "" + +#: aiogram.utils.formatting.Url:1 of +msgid "Url element." +msgstr "" + +#: aiogram.utils.formatting.Url:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.URL`" +msgstr "" + +#: aiogram.utils.formatting.Email:1 of +msgid "Email element." +msgstr "" + +#: aiogram.utils.formatting.Email:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.EMAIL`" +msgstr "" + +#: aiogram.utils.formatting.PhoneNumber:1 of +msgid "Phone number element." +msgstr "" + +#: aiogram.utils.formatting.PhoneNumber:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.PHONE_NUMBER`" +msgstr "" + +#: aiogram.utils.formatting.Bold:1 of +msgid "Bold element." +msgstr "" + +#: aiogram.utils.formatting.Bold:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.BOLD`" +msgstr "" + +#: aiogram.utils.formatting.Italic:1 of +msgid "Italic element." +msgstr "" + +#: aiogram.utils.formatting.Italic:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.ITALIC`" +msgstr "" + +#: aiogram.utils.formatting.Underline:1 of +msgid "Underline element." +msgstr "" + +#: aiogram.utils.formatting.Underline:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.UNDERLINE`" +msgstr "" + +#: aiogram.utils.formatting.Strikethrough:1 of +msgid "Strikethrough element." +msgstr "" + +#: aiogram.utils.formatting.Strikethrough:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.STRIKETHROUGH`" +msgstr "" + +#: aiogram.utils.formatting.Spoiler:1 of +msgid "Spoiler element." +msgstr "" + +#: aiogram.utils.formatting.Spoiler:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.SPOILER`" +msgstr "" + +#: aiogram.utils.formatting.Code:1 of +msgid "Code element." +msgstr "" + +#: aiogram.utils.formatting.Code:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.CODE`" +msgstr "" + +#: aiogram.utils.formatting.Pre:1 of +msgid "Pre element." +msgstr "" + +#: aiogram.utils.formatting.Pre:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type :obj:`aiogram.enums.message_entity_type.MessageEntityType.PRE`" +msgstr "" + +#: aiogram.utils.formatting.TextLink:1 of +msgid "Text link element." +msgstr "" + +#: aiogram.utils.formatting.TextLink:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.TEXT_LINK`" +msgstr "" + +#: aiogram.utils.formatting.TextMention:1 of +msgid "Text mention element." +msgstr "" + +#: aiogram.utils.formatting.TextMention:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.TEXT_MENTION`" +msgstr "" + +#: aiogram.utils.formatting.CustomEmoji:1 of +msgid "Custom emoji element." +msgstr "" + +#: aiogram.utils.formatting.CustomEmoji:3 of +msgid "" +"Will be wrapped into :obj:`aiogram.types.message_entity.MessageEntity` " +"with type " +":obj:`aiogram.enums.message_entity_type.MessageEntityType.CUSTOM_EMOJI`" +msgstr "" diff --git a/docs/utils/formatting.rst b/docs/utils/formatting.rst new file mode 100644 index 00000000..96d727f3 --- /dev/null +++ b/docs/utils/formatting.rst @@ -0,0 +1,199 @@ +.. _formatting-tool + +========== +Formatting +========== + +Make your message formatting flexible and simple + +This instrument works on top of Message entities instead of using HTML or Markdown markups, +you can easily construct your message and sent it to the Telegram without the need to +remember tag parity (opening and closing) or escaping user input. + +Usage +===== + +Basic scenario +-------------- + +Construct your message and send it to the Telegram. + +.. code-block:: python + + content = Text("Hello, ", Bold(message.from_user.full_name), "!") + await message.answer(**content.as_kwargs()) + +Is the same as the next example, but without usage markup + +.. code-block:: python + + await message.answer( + text=f"Hello, {html.quote(message.from_user.full_name)}!", + parse_mode=ParseMode.HTML + ) + +Literally when you execute :code:`as_kwargs` method the Text object is converted +into text :code:`Hello, Alex!` with entities list :code:`[MessageEntity(type='bold', offset=7, length=4)]` +and passed into dict which can be used as :code:`**kwargs` in API call. + +The complete list of elements is listed `on this page below <#available-elements>`_. + +Advanced scenario +----------------- + +On top of base elements can be implemented content rendering structures, +so, out of the box aiogram has a few already implemented functions that helps you to format +your messages: + +.. autofunction:: aiogram.utils.formatting.as_line + +.. autofunction:: aiogram.utils.formatting.as_list + +.. autofunction:: aiogram.utils.formatting.as_marked_list + +.. autofunction:: aiogram.utils.formatting.as_numbered_list + +.. autofunction:: aiogram.utils.formatting.as_section + +.. autofunction:: aiogram.utils.formatting.as_marked_section + +.. autofunction:: aiogram.utils.formatting.as_numbered_section + +.. autofunction:: aiogram.utils.formatting.as_key_value + +and lets complete them all: + +.. code-block:: python + + content = as_list( + as_marked_section( + Bold("Success:"), + "Test 1", + "Test 3", + "Test 4", + marker="✅ ", + ), + as_marked_section( + Bold("Failed:"), + "Test 2", + marker="❌ ", + ), + as_marked_section( + Bold("Summary:"), + as_key_value("Total", 4), + as_key_value("Success", 3), + as_key_value("Failed", 1), + marker=" ", + ), + HashTag("#test"), + sep="\n\n", + ) + +Will be rendered into: + + **Success:** + + ✅ Test 1 + + ✅ Test 3 + + ✅ Test 4 + + **Failed:** + + ❌ Test 2 + + **Summary:** + + **Total**: 4 + + **Success**: 3 + + **Failed**: 1 + + #test + + +Or as HTML: + +.. code-block:: html + + Success: + ✅ Test 1 + ✅ Test 3 + ✅ Test 4 + + Failed: + ❌ Test 2 + + Summary: + Total: 4 + Success: 3 + Failed: 1 + + #test + +Available methods +================= + +.. autoclass:: aiogram.utils.formatting.Text + :members: + :show-inheritance: + :member-order: bysource + :special-members: __init__ + + +Available elements +================== + +.. autoclass:: aiogram.utils.formatting.Text + :show-inheritance: + :noindex: + +.. autoclass:: aiogram.utils.formatting.HashTag + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.CashTag + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.BotCommand + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.Url + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.Email + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.PhoneNumber + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.Bold + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.Italic + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.Underline + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.Strikethrough + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.Spoiler + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.Code + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.Pre + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.TextLink + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.TextMention + :show-inheritance: + +.. autoclass:: aiogram.utils.formatting.CustomEmoji + :show-inheritance: diff --git a/docs/utils/index.rst b/docs/utils/index.rst index cfe5a543..fbab2e4a 100644 --- a/docs/utils/index.rst +++ b/docs/utils/index.rst @@ -9,3 +9,4 @@ Utils chat_action web_app callback_answer + formatting diff --git a/examples/echo_bot.py b/examples/echo_bot.py index d51a0eeb..e18201af 100644 --- a/examples/echo_bot.py +++ b/examples/echo_bot.py @@ -5,7 +5,7 @@ from aiogram import Bot, Dispatcher, Router, types from aiogram.filters import Command from aiogram.types import Message -# Bot token can be obtained via https://t.me/BotFahter +# Bot token can be obtained via https://t.me/BotFather TOKEN = "42:TOKEN" # All handlers should be attached to the Router (or Dispatcher) diff --git a/pyproject.toml b/pyproject.toml index 5a203c92..a9d32f1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,66 +40,67 @@ classifiers = [ "Topic :: Communications :: Chat", ] dependencies = [ - "magic-filter~=1.0.9", - "aiohttp~=3.8.4", - "pydantic~=1.10.4", + "magic-filter~=1.0", + "aiohttp~=3.8.5", + "pydantic~=2.1.1", "aiofiles~=23.1.0", - "certifi>=2022.9.24", + "certifi>=2023.7.22", ] dynamic = ["version"] [tool.hatch.version] -path = "aiogram/__init__.py" +path = "aiogram/__meta__.py" [project.optional-dependencies] fast = [ "uvloop>=0.17.0; (sys_platform == 'darwin' or sys_platform == 'linux') and platform_python_implementation != 'PyPy'", ] redis = [ - "redis~=4.5.1", + "redis~=4.6.0", ] proxy = [ - "aiohttp-socks~=0.7.1", + "aiohttp-socks~=0.8.0", ] i18n = [ - "Babel~=2.11.0", + "Babel~=2.12.1", ] test = [ - "pytest~=7.2.1", + "pytest~=7.4.0", "pytest-html~=3.2.0", - "pytest-asyncio~=0.20.3", + "pytest-asyncio~=0.21.0", "pytest-lazy-fixture~=0.6.3", "pytest-mock~=3.10.0", "pytest-mypy~=0.10.0", "pytest-cov~=4.0.0", "pytest-aiohttp~=1.0.4", "aresponses~=2.1.6", + "pytz~=2022.7.1" ] docs = [ - "Sphinx~=5.2.3", + "Sphinx~=7.1.1", "sphinx-intl~=2.0.1", "sphinx-autobuild~=2021.3.14", - "sphinx-copybutton~=0.5.0", - "furo~=2022.9.29", - "sphinx-prompt~=1.5.0", + "sphinx-copybutton~=0.5.2", + "furo~=2023.7.26", + "sphinx-prompt~=1.7.0", "Sphinx-Substitution-Extensions~=2022.2.16", - "towncrier~=22.8.0", - "pygments~=2.4", - "pymdown-extensions~=9.6", - "markdown-include~=0.7.0", - "Pygments~=2.13.0", - "sphinxcontrib-towncrier~=0.3.1a3", + "towncrier~=23.6.0", + "pygments~=2.15.1", + "pymdown-extensions~=10.1", + "markdown-include~=0.8.1", + "Pygments~=2.15.1", + "sphinxcontrib-towncrier~=0.3.2a0", ] dev = [ - "black~=23.1", + "black~=23.7.0", "isort~=5.11", - "ruff~=0.0.246", - "mypy~=1.0.0", + "ruff~=0.0.280", + "mypy~=1.4.1", "toml~=0.10.2", - "pre-commit~=3.0.4", - "towncrier~=22.12.0", + "pre-commit~=3.3.3", + "towncrier~=23.6.0", "packaging~=23.0", - "typing-extensions~=4.4.0", + "typing-extensions~=4.7.1", ] [project.urls] @@ -148,7 +149,14 @@ features = [ "test", ] extra-dependencies = [ - "butcher @ git+https://github.com/aiogram/butcher.git@v0.1.13" + "butcher @ git+https://github.com/aiogram/butcher.git@v0.1.17" +] + +[tool.hatch.envs.dev.scripts] +update = [ + "butcher parse", + "butcher refresh", + "butcher apply all", ] [tool.hatch.envs.test] diff --git a/scripts/bump_versions.py b/scripts/bump_versions.py index 7459192a..84f1f788 100644 --- a/scripts/bump_versions.py +++ b/scripts/bump_versions.py @@ -46,7 +46,7 @@ def replace_line(content: str, pattern: re.Pattern, new_value: str) -> str: def write_package_meta(api_version: str) -> None: - path = Path.cwd() / "aiogram" / "__init__.py" + path = Path.cwd() / "aiogram" / "__meta__.py" content = path.read_text() content = replace_line(content, API_VERSION, api_version) diff --git a/tests/conftest.py b/tests/conftest.py index b7b7774a..1c72f386 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,7 +4,7 @@ import pytest from _pytest.config import UsageError from redis.asyncio.connection import parse_url as parse_redis_url -from aiogram import Bot, Dispatcher +from aiogram import Dispatcher from aiogram.fsm.storage.memory import ( DisabledEventIsolation, MemoryStorage, @@ -109,12 +109,7 @@ async def disabled_isolation(): @pytest.fixture() def bot(): - bot = MockedBot() - token = Bot.set_current(bot) - try: - yield bot - finally: - Bot.reset_current(token) + return MockedBot() @pytest.fixture() diff --git a/tests/mocked_bot.py b/tests/mocked_bot.py index 29c477a0..cd137aee 100644 --- a/tests/mocked_bot.py +++ b/tests/mocked_bot.py @@ -1,5 +1,5 @@ from collections import deque -from typing import TYPE_CHECKING, AsyncGenerator, Deque, Optional, Type +from typing import TYPE_CHECKING, Any, AsyncGenerator, Deque, Dict, Optional, Type from aiogram import Bot from aiogram.client.session.base import BaseSession @@ -35,16 +35,20 @@ class MockedSession(BaseSession): self.requests.append(method) response: Response[TelegramType] = self.responses.pop() self.check_response( - method=method, status_code=response.error_code, content=response.json() + bot=bot, + method=method, + status_code=response.error_code, + content=response.model_dump_json(), ) return response.result # type: ignore async def stream_content( self, url: str, - timeout: int, - chunk_size: int, - raise_for_status: bool, + headers: Optional[Dict[str, Any]] = None, + timeout: int = 30, + chunk_size: int = 65536, + raise_for_status: bool = True, ) -> AsyncGenerator[bytes, None]: # pragma: no cover yield b"" diff --git a/tests/test_api/test_client/test_context_controller.py b/tests/test_api/test_client/test_context_controller.py new file mode 100644 index 00000000..25643b27 --- /dev/null +++ b/tests/test_api/test_client/test_context_controller.py @@ -0,0 +1,36 @@ +from aiogram.client.context_controller import BotContextController +from tests.mocked_bot import MockedBot + + +class MyModel(BotContextController): + id: int + + +class TestBotContextController: + def test_via_model_validate(self, bot: MockedBot): + my_model = MyModel.model_validate({"id": 1}, context={"bot": bot}) + assert my_model.id == 1 + assert my_model._bot == bot + + def test_via_model_validate_none(self): + my_model = MyModel.model_validate({"id": 1}, context={}) + assert my_model.id == 1 + assert my_model._bot is None + + def test_as(self, bot: MockedBot): + my_model = MyModel(id=1).as_(bot) + assert my_model.id == 1 + assert my_model._bot == bot + + def test_as_none(self): + my_model = MyModel(id=1).as_(None) + assert my_model.id == 1 + assert my_model._bot is None + + def test_replacement(self, bot: MockedBot): + my_model = MyModel(id=1).as_(bot) + assert my_model.id == 1 + assert my_model._bot == bot + my_model = my_model.as_(None) + assert my_model.id == 1 + assert my_model._bot is None 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 48d43cef..3793f22a 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,6 +1,6 @@ import datetime import json -from typing import Any, AsyncContextManager, AsyncGenerator, Optional +from typing import Any, AsyncContextManager, AsyncGenerator, Dict, Optional from unittest.mock import AsyncMock, patch import pytest @@ -44,7 +44,12 @@ class CustomSession(BaseSession): assert isinstance(method, TelegramMethod) async def stream_content( - self, url: str, timeout: int, chunk_size: int, raise_for_status: bool + self, + url: str, + headers: Optional[Dict[str, Any]] = None, + timeout: int = 30, + chunk_size: int = 65536, + raise_for_status: bool = True, ) -> AsyncGenerator[bytes, None]: # pragma: no cover assert isinstance(url, str) assert isinstance(timeout, int) @@ -165,9 +170,11 @@ class TestBaseSession: ) def test_check_response(self, status_code, content, error): session = CustomSession() + bot = MockedBot() method = DeleteMessage(chat_id=42, message_id=42) if error is None: session.check_response( + bot=bot, method=method, status_code=status_code, content=content, @@ -175,6 +182,7 @@ class TestBaseSession: else: with pytest.raises(error) as exc_info: session.check_response( + bot=bot, method=method, status_code=status_code, content=content, @@ -186,10 +194,12 @@ class TestBaseSession: def test_check_response_json_decode_error(self): session = CustomSession() + bot = MockedBot() method = DeleteMessage(chat_id=42, message_id=42) with pytest.raises(ClientDecodeError, match="JSONDecodeError"): session.check_response( + bot=bot, method=method, status_code=200, content="is not a JSON object", @@ -197,10 +207,12 @@ class TestBaseSession: def test_check_response_validation_error(self): session = CustomSession() + bot = MockedBot() method = DeleteMessage(chat_id=42, message_id=42) with pytest.raises(ClientDecodeError, match="ValidationError"): session.check_response( + bot=bot, method=method, status_code=200, content='{"ok": "test"}', @@ -215,6 +227,7 @@ class TestBaseSession: session = CustomSession() stream = session.stream_content( "https://www.python.org/static/img/python-logo.png", + headers={}, timeout=5, chunk_size=65536, raise_for_status=True, diff --git a/tests/test_api/test_methods/test_answer_inline_query.py b/tests/test_api/test_methods/test_answer_inline_query.py index a0cec362..cd8ba266 100644 --- a/tests/test_api/test_methods/test_answer_inline_query.py +++ b/tests/test_api/test_methods/test_answer_inline_query.py @@ -2,6 +2,7 @@ from aiogram import Bot from aiogram.methods import AnswerInlineQuery, Request from aiogram.types import ( InlineQueryResult, + InlineQueryResultArticle, InlineQueryResultPhoto, InputTextMessageContent, ) @@ -13,7 +14,14 @@ class TestAnswerInlineQuery: prepare_result = bot.add_result_for(AnswerInlineQuery, ok=True, result=True) response: bool = await bot.answer_inline_query( - inline_query_id="query id", results=[InlineQueryResult()] + inline_query_id="query id", + results=[ + InlineQueryResultArticle( + id="1", + title="title", + input_message_content=InputTextMessageContent(message_text="text"), + ) + ], ) request = bot.get_request() assert response == prepare_result.result diff --git a/tests/test_api/test_methods/test_answer_web_app_query.py b/tests/test_api/test_methods/test_answer_web_app_query.py index 6948bead..a42640a8 100644 --- a/tests/test_api/test_methods/test_answer_web_app_query.py +++ b/tests/test_api/test_methods/test_answer_web_app_query.py @@ -1,5 +1,5 @@ -from aiogram.methods import AnswerWebAppQuery, Request -from aiogram.types import InlineQueryResult, SentWebAppMessage +from aiogram.methods import AnswerWebAppQuery +from aiogram.types import InlineQueryResultPhoto, SentWebAppMessage from tests.mocked_bot import MockedBot @@ -9,7 +9,11 @@ class TestAnswerWebAppQuery: response: SentWebAppMessage = await bot.answer_web_app_query( web_app_query_id="test", - result=InlineQueryResult(), + result=InlineQueryResultPhoto( + id="test", + photo_url="test", + thumbnail_url="test", + ), ) request = bot.get_request() assert response == prepare_result.result diff --git a/tests/test_api/test_methods/test_base.py b/tests/test_api/test_methods/test_base.py index f2351d40..9626c9b7 100644 --- a/tests/test_api/test_methods/test_base.py +++ b/tests/test_api/test_methods/test_base.py @@ -22,6 +22,14 @@ class TestTelegramMethodRemoveUnset: class TestTelegramMethodCall: + async def test_async_emit_unsuccessful(self, bot: MockedBot): + with pytest.raises( + RuntimeError, + match="This method is not mounted to a any bot instance.+", + ): + await GetMe() + async def test_async_emit(self, bot: MockedBot): bot.add_result_for(GetMe, ok=True, result=User(id=42, is_bot=True, first_name="Test")) - assert isinstance(await GetMe(), User) + method = GetMe().as_(bot) + assert isinstance(await method, User) diff --git a/tests/test_api/test_methods/test_get_my_name.py b/tests/test_api/test_methods/test_get_my_name.py new file mode 100644 index 00000000..085ac0db --- /dev/null +++ b/tests/test_api/test_methods/test_get_my_name.py @@ -0,0 +1,11 @@ +from aiogram.methods import GetMyName +from aiogram.types import BotDescription, BotName +from tests.mocked_bot import MockedBot + + +class TestGetMyName: + async def test_bot_method(self, bot: MockedBot): + prepare_result = bot.add_result_for(GetMyName, ok=True, result=BotName(name="Test")) + + response: BotName = await bot.get_my_name() + assert response == prepare_result.result diff --git a/tests/test_api/test_methods/test_send_message.py b/tests/test_api/test_methods/test_send_message.py index 0210d73f..1458ed4e 100644 --- a/tests/test_api/test_methods/test_send_message.py +++ b/tests/test_api/test_methods/test_send_message.py @@ -1,7 +1,7 @@ import datetime from aiogram.methods import Request, SendMessage -from aiogram.types import Chat, ForceReply, Message +from aiogram.types import Chat, ForceReply, Message, ReplyKeyboardRemove from tests.mocked_bot import MockedBot @@ -24,5 +24,11 @@ class TestSendMessage: async def test_force_reply(self): # https://github.com/aiogram/aiogram/issues/901 + print("::::", SendMessage.__pydantic_core_schema__) method = SendMessage(text="test", chat_id=42, reply_markup=ForceReply()) assert isinstance(method.reply_markup, ForceReply) + + async def test_reply_keyboard_remove(self): + # https://github.com/aiogram/aiogram/issues/901 + method = SendMessage(text="test", chat_id=42, reply_markup=ReplyKeyboardRemove()) + assert isinstance(method.reply_markup, ReplyKeyboardRemove) diff --git a/tests/test_api/test_methods/test_set_my_name.py b/tests/test_api/test_methods/test_set_my_name.py new file mode 100644 index 00000000..3b511f2f --- /dev/null +++ b/tests/test_api/test_methods/test_set_my_name.py @@ -0,0 +1,10 @@ +from aiogram.methods import SetMyName +from tests.mocked_bot import MockedBot + + +class TestSetMyName: + async def test_bot_method(self, bot: MockedBot): + prepare_result = bot.add_result_for(SetMyName, ok=True, result=True) + + response: bool = await bot.set_my_name() + assert response == prepare_result.result diff --git a/tests/test_api/test_methods/test_set_passport_data_errors.py b/tests/test_api/test_methods/test_set_passport_data_errors.py index ecc2425b..0e5647fb 100644 --- a/tests/test_api/test_methods/test_set_passport_data_errors.py +++ b/tests/test_api/test_methods/test_set_passport_data_errors.py @@ -1,5 +1,5 @@ from aiogram.methods import Request, SetPassportDataErrors -from aiogram.types import PassportElementError +from aiogram.types import PassportElementError, PassportElementErrorFile from tests.mocked_bot import MockedBot @@ -8,7 +8,14 @@ class TestSetPassportDataErrors: prepare_result = bot.add_result_for(SetPassportDataErrors, ok=True, result=True) response: bool = await bot.set_passport_data_errors( - user_id=42, errors=[PassportElementError()] + user_id=42, + errors=[ + PassportElementErrorFile( + type="type", + file_hash="hash", + message="message", + ) + ], ) request = bot.get_request() assert response == prepare_result.result diff --git a/tests/test_api/test_types/test_input_file.py b/tests/test_api/test_types/test_input_file.py index 05391a8e..81e80ad5 100644 --- a/tests/test_api/test_types/test_input_file.py +++ b/tests/test_api/test_types/test_input_file.py @@ -4,6 +4,7 @@ from aresponses import ResponsesMockServer from aiogram import Bot from aiogram.types import BufferedInputFile, FSInputFile, InputFile, URLInputFile +from tests.mocked_bot import MockedBot class TestInputFile: @@ -72,10 +73,8 @@ class TestInputFile: aresponses.add( aresponses.ANY, aresponses.ANY, "get", aresponses.Response(status=200, body=b"\f" * 10) ) - - Bot.set_current(Bot("42:TEST")) - - file = URLInputFile("https://test.org/", chunk_size=1) + bot = Bot(token="42:TEST") + file = URLInputFile("https://test.org/", bot, chunk_size=1) size = 0 async for chunk in file: diff --git a/tests/test_api/test_types/test_message.py b/tests/test_api/test_types/test_message.py index 7eec99c7..1b15327f 100644 --- a/tests/test_api/test_types/test_message.py +++ b/tests/test_api/test_types/test_message.py @@ -44,6 +44,7 @@ from aiogram.types import ( EncryptedCredentials, ForumTopicClosed, ForumTopicCreated, + ForumTopicEdited, ForumTopicReopened, Game, InlineKeyboardButton, @@ -414,6 +415,16 @@ TEST_FORUM_TOPIC_CREATED = Message( icon_color=0xFFD67E, ), ) +TEST_FORUM_TOPIC_EDITED = Message( + message_id=42, + date=datetime.datetime.now(), + chat=Chat(id=42, type="private"), + from_user=User(id=42, is_bot=False, first_name="Test"), + forum_topic_edited=ForumTopicEdited( + name="test_edited", + icon_color=0xFFD67E, + ), +) TEST_FORUM_TOPIC_CLOSED = Message( message_id=42, date=datetime.datetime.now(), @@ -484,6 +495,7 @@ class TestMessage: [TEST_MESSAGE_DICE, ContentType.DICE], [TEST_MESSAGE_WEB_APP_DATA, ContentType.WEB_APP_DATA], [TEST_FORUM_TOPIC_CREATED, ContentType.FORUM_TOPIC_CREATED], + [TEST_FORUM_TOPIC_EDITED, ContentType.FORUM_TOPIC_EDITED], [TEST_FORUM_TOPIC_CLOSED, ContentType.FORUM_TOPIC_CLOSED], [TEST_FORUM_TOPIC_REOPENED, ContentType.FORUM_TOPIC_REOPENED], [TEST_MESSAGE_UNKNOWN, ContentType.UNKNOWN], diff --git a/tests/test_dispatcher/test_dispatcher.py b/tests/test_dispatcher/test_dispatcher.py index 4fb2b113..69aece69 100644 --- a/tests/test_dispatcher/test_dispatcher.py +++ b/tests/test_dispatcher/test_dispatcher.py @@ -14,7 +14,7 @@ from aiogram import Bot from aiogram.dispatcher.dispatcher import Dispatcher from aiogram.dispatcher.event.bases import UNHANDLED, SkipHandler from aiogram.dispatcher.router import Router -from aiogram.methods import GetMe, GetUpdates, Request, SendMessage, TelegramMethod +from aiogram.methods import GetMe, GetUpdates, SendMessage, TelegramMethod from aiogram.types import ( CallbackQuery, Chat, @@ -460,16 +460,20 @@ class TestDispatcher: @observer() async def my_handler(event: Any, **kwargs: Any): - assert event == getattr(update, event_type) + assert event.model_dump(exclude_defaults=True) == getattr( + update, event_type + ).model_dump(exclude_defaults=True) if has_chat: - assert Chat.get_current(False) + assert kwargs["event_chat"] if has_user: - assert User.get_current(False) + assert kwargs["event_from_user"] return kwargs result = await router.feed_update(bot, update, test="PASS") assert isinstance(result, dict) - assert result["event_update"] == update + assert result["event_update"].model_dump(exclude_defaults=True) == update.model_dump( + exclude_defaults=True + ) assert result["event_router"] == router assert result["test"] == "PASS" @@ -532,7 +536,9 @@ class TestDispatcher: ) result = await dp.feed_update(bot, update, test="PASS") assert isinstance(result, dict) - assert result["event_update"] == update + assert result["event_update"].model_dump(exclude_defaults=True) == update.model_dump( + exclude_defaults=True + ) assert result["event_router"] == router1 assert result["test"] == "PASS" @@ -708,10 +714,15 @@ class TestDispatcher: with pytest.raises(RuntimeError): await dispatcher.stop_polling() - assert not dispatcher._stop_signal.is_set() - assert not dispatcher._stopped_signal.is_set() + assert not dispatcher._stop_signal + assert not dispatcher._stopped_signal with patch("asyncio.locks.Event.wait", new_callable=AsyncMock) as mocked_wait: async with dispatcher._running_lock: + await dispatcher.stop_polling() + assert not dispatcher._stop_signal + + dispatcher._stop_signal = Event() + dispatcher._stopped_signal = Event() await dispatcher.stop_polling() assert dispatcher._stop_signal.is_set() mocked_wait.assert_awaited() @@ -723,6 +734,11 @@ class TestDispatcher: mocked_set.assert_not_called() async with dispatcher._running_lock: + dispatcher._signal_stop_polling(signal.SIGINT) + mocked_set.assert_not_called() + + dispatcher._stop_signal = Event() + dispatcher._stopped_signal = Event() dispatcher._signal_stop_polling(signal.SIGINT) mocked_set.assert_called() @@ -764,12 +780,29 @@ class TestDispatcher: def test_run_polling(self, bot: MockedBot): dispatcher = Dispatcher() + + async def stop(): + await asyncio.sleep(0.5) + await dispatcher.stop_polling() + + start_called = False + + @dispatcher.startup() + async def startup(): + nonlocal start_called + start_called = True + asyncio.create_task(stop()) + + original_start_polling = dispatcher.start_polling with patch( - "aiogram.dispatcher.dispatcher.Dispatcher.start_polling" + "aiogram.dispatcher.dispatcher.Dispatcher.start_polling", + side_effect=original_start_polling, ) as patched_start_polling: dispatcher.run_polling(bot) patched_start_polling.assert_awaited_once() + assert start_called + async def test_feed_webhook_update_fast_process(self, bot: MockedBot): dispatcher = Dispatcher() dispatcher.message.register(simple_message_handler) diff --git a/tests/test_dispatcher/test_middlewares/test_user_context.py b/tests/test_dispatcher/test_middlewares/test_user_context.py index ca2abb2d..54c09ce2 100644 --- a/tests/test_dispatcher/test_middlewares/test_user_context.py +++ b/tests/test_dispatcher/test_middlewares/test_user_context.py @@ -1,6 +1,9 @@ +from unittest.mock import patch + import pytest from aiogram.dispatcher.middlewares.user_context import UserContextMiddleware +from aiogram.types import Update async def next_handler(*args, **kwargs): @@ -11,3 +14,13 @@ class TestUserContextMiddleware: async def test_unexpected_event_type(self): with pytest.raises(RuntimeError): await UserContextMiddleware()(next_handler, object(), {}) + + async def test_call(self): + middleware = UserContextMiddleware() + data = {} + with patch.object(UserContextMiddleware, "resolve_event_context", return_value=[1, 2, 3]): + await middleware(next_handler, Update(update_id=42), data) + + assert data["event_chat"] == 1 + assert data["event_from_user"] == 2 + assert data["event_thread_id"] == 3 diff --git a/tests/test_dispatcher/test_router.py b/tests/test_dispatcher/test_router.py index 3404822d..1ac78480 100644 --- a/tests/test_dispatcher/test_router.py +++ b/tests/test_dispatcher/test_router.py @@ -1,6 +1,7 @@ import pytest from aiogram.dispatcher.event.bases import UNHANDLED, SkipHandler, skip +from aiogram.dispatcher.event.telegram import TelegramEventObserver from aiogram.dispatcher.router import Router @@ -161,3 +162,20 @@ class TestRouter: assert tuple(r2_1.chain_head) == (r2_1, r1) assert tuple(r2_2.chain_head) == (r2_2, r1) assert tuple(r3.chain_head) == (r3, r2_1, r1) + + async def test_custom_evenv_nested_router(self): + r1 = Router() + r2 = Router() + r3 = Router() + r3.observers["custom-event"] = TelegramEventObserver(r3, event_name="custom-event") + + async def handler(evt): + return evt + + r1.include_router(r2) + r1.include_router(r3) + r3.observers["custom-event"].register(handler) + + assert await r1.propagate_event(update_type="custom-event", event=None) is None + assert await r2.propagate_event(update_type="custom-event", event=None) is UNHANDLED + assert await r3.propagate_event(update_type="custom-event", event=None) is None diff --git a/tests/test_filters/test_callback_data.py b/tests/test_filters/test_callback_data.py index 70388689..e8721a41 100644 --- a/tests/test_filters/test_callback_data.py +++ b/tests/test_filters/test_callback_data.py @@ -49,34 +49,38 @@ class TestCallbackData: pass @pytest.mark.parametrize( - "value,success,expected", + "value,expected", [ - [None, True, ""], - [42, True, "42"], - ["test", True, "test"], - [9.99, True, "9.99"], - [Decimal("9.99"), True, "9.99"], - [Fraction("3/2"), True, "3/2"], - [ - UUID("123e4567-e89b-12d3-a456-426655440000"), - True, - "123e4567-e89b-12d3-a456-426655440000", - ], - [MyIntEnum.FOO, True, "1"], - [MyStringEnum.FOO, True, "FOO"], - [..., False, "..."], - [object, False, "..."], - [object(), False, "..."], - [User(id=42, is_bot=False, first_name="test"), False, "..."], + [None, ""], + [True, "1"], + [False, "0"], + [42, "42"], + ["test", "test"], + [9.99, "9.99"], + [Decimal("9.99"), "9.99"], + [Fraction("3/2"), "3/2"], + [UUID("123e4567-e89b-12d3-a456-426655440000"), "123e4567e89b12d3a456426655440000"], + [MyIntEnum.FOO, "1"], + [MyStringEnum.FOO, "FOO"], ], ) - def test_encode_value(self, value, success, expected): + def test_encode_value_positive(self, value, expected): callback = MyCallback(foo="test", bar=42) - if success: - assert callback._encode_value("test", value) == expected - else: - with pytest.raises(ValueError): - assert callback._encode_value("test", value) == expected + assert callback._encode_value("test", value) == expected + + @pytest.mark.parametrize( + "value", + [ + ..., + object, + object(), + User(id=42, is_bot=False, first_name="test"), + ], + ) + def test_encode_value_negative(self, value): + callback = MyCallback(foo="test", bar=42) + with pytest.raises(ValueError): + callback._encode_value("test", value) def test_pack(self): with pytest.raises(ValueError, match="Separator symbol .+"): diff --git a/tests/test_filters/test_chat_member_updated.py b/tests/test_filters/test_chat_member_updated.py index f3fdce66..46da8b8e 100644 --- a/tests/test_filters/test_chat_member_updated.py +++ b/tests/test_filters/test_chat_member_updated.py @@ -1,4 +1,5 @@ from datetime import datetime +from typing import Optional import pytest @@ -12,7 +13,21 @@ from aiogram.filters.chat_member_updated import ( _MemberStatusMarker, _MemberStatusTransition, ) -from aiogram.types import Chat, ChatMember, ChatMemberUpdated, User +from aiogram.types import ( + Chat, + ChatMember, + ChatMemberAdministrator, + ChatMemberLeft, + ChatMemberMember, + ChatMemberRestricted, + ChatMemberUpdated, + User, +) + + +class ChatMemberCustom(ChatMember): + status: str + is_member: Optional[bool] = None class TestMemberStatusMarker: @@ -104,11 +119,11 @@ class TestMemberStatusMarker: @pytest.mark.parametrize( "name,is_member,member,result", [ - ["test", None, ChatMember(status="member"), False], - ["test", None, ChatMember(status="test"), True], - ["test", True, ChatMember(status="test"), False], - ["test", True, ChatMember(status="test", is_member=True), True], - ["test", True, ChatMember(status="test", is_member=False), False], + ["test", None, ChatMemberCustom(status="member"), False], + ["test", None, ChatMemberCustom(status="test"), True], + ["test", True, ChatMemberCustom(status="test"), False], + ["test", True, ChatMemberCustom(status="test", is_member=True), True], + ["test", True, ChatMemberCustom(status="test", is_member=False), False], ], ) def test_check(self, name, is_member, member, result): @@ -235,29 +250,34 @@ class TestMemberStatusTransition: @pytest.mark.parametrize( "transition,old,new,result", [ - [JOIN_TRANSITION, ChatMember(status="left"), ChatMember(status="member"), True], [ JOIN_TRANSITION, - ChatMember(status="restricted", is_member=True), - ChatMember(status="member"), - False, - ], - [ - JOIN_TRANSITION, - ChatMember(status="restricted", is_member=False), - ChatMember(status="member"), + ChatMemberCustom(status="left"), + ChatMemberCustom(status="member"), True, ], [ JOIN_TRANSITION, - ChatMember(status="member"), - ChatMember(status="restricted", is_member=False), + ChatMemberCustom(status="restricted", is_member=True), + ChatMemberCustom(status="member"), + False, + ], + [ + JOIN_TRANSITION, + ChatMemberCustom(status="restricted", is_member=False), + ChatMemberCustom(status="member"), + True, + ], + [ + JOIN_TRANSITION, + ChatMemberCustom(status="member"), + ChatMemberCustom(status="restricted", is_member=False), False, ], [ LEAVE_TRANSITION, - ChatMember(status="member"), - ChatMember(status="restricted", is_member=False), + ChatMemberCustom(status="member"), + ChatMemberCustom(status="restricted", is_member=False), True, ], ], @@ -267,84 +287,91 @@ class TestMemberStatusTransition: class TestChatMemberUpdatedStatusFilter: + USER = User(id=42, first_name="Test", is_bot=False) + PARAMS = { + "user": USER, + "until_date": datetime.now(), + "is_anonymous": True, + "custom_title": "title", + "can_be_edited": True, + "can_manage_chat": True, + "can_delete_messages": True, + "can_manage_video_chats": True, + "can_restrict_members": True, + "can_promote_members": True, + "can_change_info": True, + "can_invite_users": True, + "can_post_messages": True, + "can_edit_messages": True, + "can_pin_messages": True, + "can_manage_topics": True, + "can_send_messages": True, + "can_send_audios": True, + "can_send_documents": True, + "can_send_photos": True, + "can_send_videos": True, + "can_send_video_notes": True, + "can_send_voice_notes": True, + "can_send_polls": True, + "can_send_other_messages": True, + "can_add_web_page_previews": True, + } + @pytest.mark.parametrize( "transition,old,new,result", [ - [JOIN_TRANSITION, ChatMember(status="left"), ChatMember(status="member"), True], [ JOIN_TRANSITION, - ChatMember(status="restricted", is_member=True), - ChatMember(status="member"), - False, - ], - [ - JOIN_TRANSITION, - ChatMember(status="restricted", is_member=False), - ChatMember(status="member"), + ChatMemberLeft(status="left", **PARAMS), + ChatMemberMember(status="member", **PARAMS), True, ], [ JOIN_TRANSITION, - ChatMember(status="member"), - ChatMember(status="restricted", is_member=False), + ChatMemberRestricted(status="restricted", is_member=True, **PARAMS), + ChatMemberMember(status="member", **PARAMS), + False, + ], + [ + JOIN_TRANSITION, + ChatMemberRestricted(status="restricted", is_member=False, **PARAMS), + ChatMemberMember(status="member", **PARAMS), + True, + ], + [ + JOIN_TRANSITION, + ChatMemberMember(status="member", **PARAMS), + ChatMemberRestricted(status="restricted", is_member=False, **PARAMS), False, ], [ LEAVE_TRANSITION, - ChatMember(status="member"), - ChatMember(status="restricted", is_member=False), + ChatMemberMember(status="member", **PARAMS), + ChatMemberRestricted(status="restricted", is_member=False, **PARAMS), True, ], [ ADMINISTRATOR, - ChatMember(status="member"), - ChatMember(status="administrator"), + ChatMemberMember(status="member", **PARAMS), + ChatMemberAdministrator(status="administrator", **PARAMS), True, ], [ IS_MEMBER, - ChatMember(status="restricted", is_member=False), - ChatMember(status="member"), + ChatMemberRestricted(status="restricted", is_member=False, **PARAMS), + ChatMemberMember(status="member", **PARAMS), True, ], ], ) async def test_call(self, transition, old, new, result): updated_filter = ChatMemberUpdatedFilter(member_status_changed=transition) - user = User(id=42, first_name="Test", is_bot=False) - update = { - "user": user, - "until_date": datetime.now(), - "is_anonymous": True, - "custom_title": True, - "can_be_edited": True, - "can_manage_chat": True, - "can_delete_messages": True, - "can_manage_video_chats": True, - "can_restrict_members": True, - "can_promote_members": True, - "can_change_info": True, - "can_invite_users": True, - "can_post_messages": True, - "can_edit_messages": True, - "can_pin_messages": True, - "can_manage_topics": True, - "can_send_messages": True, - "can_send_audios": True, - "can_send_documents": True, - "can_send_photos": True, - "can_send_videos": True, - "can_send_video_notes": True, - "can_send_voice_notes": True, - "can_send_polls": True, - "can_send_other_messages": True, - "can_add_web_page_previews": True, - } + event = ChatMemberUpdated( chat=Chat(id=42, type="test"), - from_user=user, - old_chat_member=old.copy(update=update), - new_chat_member=new.copy(update=update), + from_user=self.USER, + old_chat_member=old, + new_chat_member=new, date=datetime.now(), ) diff --git a/tests/test_filters/test_logic.py b/tests/test_filters/test_logic.py index 9c4d4f48..b1382766 100644 --- a/tests/test_filters/test_logic.py +++ b/tests/test_filters/test_logic.py @@ -1,6 +1,6 @@ import pytest -from aiogram.filters import Text, and_f, invert_f, or_f +from aiogram.filters import Command, and_f, invert_f, or_f from aiogram.filters.logic import _AndFilter, _InvertFilter, _OrFilter @@ -28,10 +28,10 @@ class TestLogic: @pytest.mark.parametrize( "case,type_", [ - [or_f(Text(text="test"), Text(text="test")), _OrFilter], - [and_f(Text(text="test"), Text(text="test")), _AndFilter], - [invert_f(Text(text="test")), _InvertFilter], - [~Text(text="test"), _InvertFilter], + [or_f(Command("test"), Command("test")), _OrFilter], + [and_f(Command("test"), Command("test")), _AndFilter], + [invert_f(Command("test")), _InvertFilter], + [~Command("test"), _InvertFilter], ], ) def test_dunder_methods(self, case, type_): diff --git a/tests/test_filters/test_text.py b/tests/test_filters/test_text.py deleted file mode 100644 index de823097..00000000 --- a/tests/test_filters/test_text.py +++ /dev/null @@ -1,245 +0,0 @@ -import datetime -from itertools import permutations -from typing import Sequence, Type - -import pytest - -from aiogram.filters import Text -from aiogram.types import ( - CallbackQuery, - Chat, - InlineQuery, - Message, - Poll, - PollOption, - User, -) - - -class TestText: - @pytest.mark.parametrize( - "kwargs", - [ - {}, - {"ignore_case": True}, - {"ignore_case": False}, - ], - ) - def test_not_enough_arguments(self, kwargs): - with pytest.raises(ValueError): - Text(**kwargs) - - @pytest.mark.parametrize( - "first,last", - permutations(["text", "contains", "startswith", "endswith"], 2), - ) - @pytest.mark.parametrize("ignore_case", [True, False]) - def test_validator_too_few_arguments(self, first, last, ignore_case): - kwargs = {first: "test", last: "test", "ignore_case": ignore_case} - - with pytest.raises(ValueError): - Text(**kwargs) - - @pytest.mark.parametrize("argument", ["text", "contains", "startswith", "endswith"]) - @pytest.mark.parametrize("input_type", [str, list, tuple]) - def test_validator_convert_to_list(self, argument: str, input_type: Type): - text = Text(**{argument: input_type("test")}) - assert hasattr(text, argument) - assert isinstance(getattr(text, argument), Sequence) - - @pytest.mark.parametrize( - "argument,ignore_case,input_value,update_type,result", - [ - [ - "text", - False, - "test", - Message( - message_id=42, - date=datetime.datetime.now(), - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - False, - ], - [ - "text", - False, - "test", - Message( - message_id=42, - date=datetime.datetime.now(), - caption="test", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "text", - False, - "test", - Message( - message_id=42, - date=datetime.datetime.now(), - text="test", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "text", - True, - "TEst", - Message( - message_id=42, - date=datetime.datetime.now(), - text="tesT", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "text", - False, - "TEst", - Message( - message_id=42, - date=datetime.datetime.now(), - text="tesT", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - False, - ], - [ - "startswith", - False, - "test", - Message( - message_id=42, - date=datetime.datetime.now(), - text="test case", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "endswith", - False, - "case", - Message( - message_id=42, - date=datetime.datetime.now(), - text="test case", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "contains", - False, - " ", - Message( - message_id=42, - date=datetime.datetime.now(), - text="test case", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "startswith", - True, - "question", - Message( - message_id=42, - date=datetime.datetime.now(), - poll=Poll( - id="poll id", - question="Question?", - options=[PollOption(text="A", voter_count=0)], - is_closed=False, - is_anonymous=False, - type="regular", - allows_multiple_answers=False, - total_voter_count=0, - ), - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "startswith", - True, - "callback:", - CallbackQuery( - id="query id", - from_user=User(id=42, is_bot=False, first_name="Test"), - chat_instance="instance", - data="callback:data", - ), - True, - ], - [ - "startswith", - True, - "query", - InlineQuery( - id="query id", - from_user=User(id=42, is_bot=False, first_name="Test"), - query="query line", - offset="offset", - ), - True, - ], - [ - "text", - True, - "question", - Poll( - id="poll id", - question="Question", - options=[PollOption(text="A", voter_count=0)], - is_closed=False, - is_anonymous=False, - type="regular", - allows_multiple_answers=False, - total_voter_count=0, - ), - True, - ], - [ - "text", - True, - ["question", "another question"], - Poll( - id="poll id", - question="Another question", - options=[PollOption(text="A", voter_count=0)], - is_closed=False, - is_anonymous=False, - type="quiz", - allows_multiple_answers=False, - total_voter_count=0, - correct_option_id=0, - ), - True, - ], - ["text", True, ["question", "another question"], object(), False], - ], - ) - async def test_check_text(self, argument, ignore_case, input_value, result, update_type): - text = Text(**{argument: input_value}, ignore_case=ignore_case) - test = await text(update_type) - assert test is result - - def test_str(self): - text = Text("test") - assert str(text) == "Text(text=['test'], ignore_case=False)" diff --git a/tests/test_fsm/storage/test_isolation.py b/tests/test_fsm/storage/test_isolation.py index 042cc305..8212c955 100644 --- a/tests/test_fsm/storage/test_isolation.py +++ b/tests/test_fsm/storage/test_isolation.py @@ -5,7 +5,7 @@ from tests.mocked_bot import MockedBot @pytest.fixture(name="storage_key") -def create_storate_key(bot: MockedBot): +def create_storage_key(bot: MockedBot): return StorageKey(chat_id=-42, user_id=42, bot_id=bot.id) @@ -20,9 +20,8 @@ def create_storate_key(bot: MockedBot): class TestIsolations: async def test_lock( self, - bot: MockedBot, isolation: BaseEventIsolation, storage_key: StorageKey, ): - async with isolation.lock(bot=bot, key=storage_key): + async with isolation.lock(key=storage_key): assert True, "You are kidding me?" diff --git a/tests/test_fsm/storage/test_redis.py b/tests/test_fsm/storage/test_redis.py index 6e42eb48..adca384a 100644 --- a/tests/test_fsm/storage/test_redis.py +++ b/tests/test_fsm/storage/test_redis.py @@ -11,6 +11,7 @@ PREFIX = "test" BOT_ID = 42 CHAT_ID = -1 USER_ID = 2 +THREAD_ID = 3 FIELD = "data" @@ -46,6 +47,19 @@ class TestRedisDefaultKeyBuilder: with pytest.raises(ValueError): key_builder.build(key, FIELD) + def test_thread_id(self): + key_builder = DefaultKeyBuilder( + prefix=PREFIX, + ) + key = StorageKey( + chat_id=CHAT_ID, + user_id=USER_ID, + bot_id=BOT_ID, + thread_id=THREAD_ID, + destiny=DEFAULT_DESTINY, + ) + assert key_builder.build(key, FIELD) == f"{PREFIX}:{CHAT_ID}:{THREAD_ID}:{USER_ID}:{FIELD}" + def test_create_isolation(self): fake_redis = object() storage = RedisStorage(redis=fake_redis) diff --git a/tests/test_fsm/storage/test_storages.py b/tests/test_fsm/storage/test_storages.py index 83871722..3558e33d 100644 --- a/tests/test_fsm/storage/test_storages.py +++ b/tests/test_fsm/storage/test_storages.py @@ -5,7 +5,7 @@ from tests.mocked_bot import MockedBot @pytest.fixture(name="storage_key") -def create_storate_key(bot: MockedBot): +def create_storage_key(bot: MockedBot): return StorageKey(chat_id=-42, user_id=42, bot_id=bot.id) @@ -15,33 +15,31 @@ def create_storate_key(bot: MockedBot): ) class TestStorages: async def test_set_state(self, bot: MockedBot, storage: BaseStorage, storage_key: StorageKey): - assert await storage.get_state(bot=bot, key=storage_key) is None + assert await storage.get_state(key=storage_key) is None - await storage.set_state(bot=bot, key=storage_key, state="state") - assert await storage.get_state(bot=bot, key=storage_key) == "state" - await storage.set_state(bot=bot, key=storage_key, state=None) - assert await storage.get_state(bot=bot, key=storage_key) is None + await storage.set_state(key=storage_key, state="state") + assert await storage.get_state(key=storage_key) == "state" + await storage.set_state(key=storage_key, state=None) + assert await storage.get_state(key=storage_key) is None async def test_set_data(self, bot: MockedBot, storage: BaseStorage, storage_key: StorageKey): - assert await storage.get_data(bot=bot, key=storage_key) == {} + assert await storage.get_data(key=storage_key) == {} - await storage.set_data(bot=bot, key=storage_key, data={"foo": "bar"}) - assert await storage.get_data(bot=bot, key=storage_key) == {"foo": "bar"} - await storage.set_data(bot=bot, key=storage_key, data={}) - assert await storage.get_data(bot=bot, key=storage_key) == {} + await storage.set_data(key=storage_key, data={"foo": "bar"}) + assert await storage.get_data(key=storage_key) == {"foo": "bar"} + await storage.set_data(key=storage_key, data={}) + assert await storage.get_data(key=storage_key) == {} async def test_update_data( self, bot: MockedBot, storage: BaseStorage, storage_key: StorageKey ): - assert await storage.get_data(bot=bot, key=storage_key) == {} - assert await storage.update_data(bot=bot, key=storage_key, data={"foo": "bar"}) == { - "foo": "bar" - } - assert await storage.update_data(bot=bot, key=storage_key, data={"baz": "spam"}) == { + assert await storage.get_data(key=storage_key) == {} + assert await storage.update_data(key=storage_key, data={"foo": "bar"}) == {"foo": "bar"} + assert await storage.update_data(key=storage_key, data={"baz": "spam"}) == { "foo": "bar", "baz": "spam", } - assert await storage.get_data(bot=bot, key=storage_key) == { + assert await storage.get_data(key=storage_key) == { "foo": "bar", "baz": "spam", } diff --git a/tests/test_fsm/test_context.py b/tests/test_fsm/test_context.py index 5c31373c..f0c29911 100644 --- a/tests/test_fsm/test_context.py +++ b/tests/test_fsm/test_context.py @@ -13,7 +13,7 @@ def state(bot: MockedBot): ctx = storage.storage[key] ctx.state = "test" ctx.data = {"foo": "bar"} - return FSMContext(bot=bot, storage=storage, key=key) + return FSMContext(storage=storage, key=key) class TestFSMContext: @@ -22,15 +22,9 @@ class TestFSMContext: ctx = storage.storage[StorageKey(chat_id=-42, user_id=42, bot_id=bot.id)] ctx.state = "test" ctx.data = {"foo": "bar"} - state = FSMContext( - bot=bot, storage=storage, key=StorageKey(chat_id=-42, user_id=42, bot_id=bot.id) - ) - state2 = FSMContext( - bot=bot, storage=storage, key=StorageKey(chat_id=42, user_id=42, bot_id=bot.id) - ) - state3 = FSMContext( - bot=bot, storage=storage, key=StorageKey(chat_id=69, user_id=69, bot_id=bot.id) - ) + state = FSMContext(storage=storage, key=StorageKey(chat_id=-42, user_id=42, bot_id=bot.id)) + state2 = FSMContext(storage=storage, key=StorageKey(chat_id=42, user_id=42, bot_id=bot.id)) + state3 = FSMContext(storage=storage, key=StorageKey(chat_id=69, user_id=69, bot_id=bot.id)) assert await state.get_state() == "test" assert await state2.get_state() is None diff --git a/tests/test_fsm/test_strategy.py b/tests/test_fsm/test_strategy.py index b00a7b98..782d1eeb 100644 --- a/tests/test_fsm/test_strategy.py +++ b/tests/test_fsm/test_strategy.py @@ -2,19 +2,41 @@ import pytest from aiogram.fsm.strategy import FSMStrategy, apply_strategy +CHAT_ID = -42 +USER_ID = 42 +THREAD_ID = 1 + +PRIVATE = (USER_ID, USER_ID, None) +CHAT = (CHAT_ID, USER_ID, None) +THREAD = (CHAT_ID, USER_ID, THREAD_ID) + class TestStrategy: @pytest.mark.parametrize( "strategy,case,expected", [ - [FSMStrategy.USER_IN_CHAT, (-42, 42), (-42, 42)], - [FSMStrategy.CHAT, (-42, 42), (-42, -42)], - [FSMStrategy.GLOBAL_USER, (-42, 42), (42, 42)], - [FSMStrategy.USER_IN_CHAT, (42, 42), (42, 42)], - [FSMStrategy.CHAT, (42, 42), (42, 42)], - [FSMStrategy.GLOBAL_USER, (42, 42), (42, 42)], + [FSMStrategy.USER_IN_CHAT, CHAT, CHAT], + [FSMStrategy.USER_IN_CHAT, PRIVATE, PRIVATE], + [FSMStrategy.USER_IN_CHAT, THREAD, CHAT], + [FSMStrategy.CHAT, CHAT, (CHAT_ID, CHAT_ID, None)], + [FSMStrategy.CHAT, PRIVATE, (USER_ID, USER_ID, None)], + [FSMStrategy.CHAT, THREAD, (CHAT_ID, CHAT_ID, None)], + [FSMStrategy.GLOBAL_USER, CHAT, PRIVATE], + [FSMStrategy.GLOBAL_USER, PRIVATE, PRIVATE], + [FSMStrategy.GLOBAL_USER, THREAD, PRIVATE], + [FSMStrategy.USER_IN_TOPIC, CHAT, CHAT], + [FSMStrategy.USER_IN_TOPIC, PRIVATE, PRIVATE], + [FSMStrategy.USER_IN_TOPIC, THREAD, THREAD], ], ) def test_strategy(self, strategy, case, expected): - chat_id, user_id = case - assert apply_strategy(chat_id=chat_id, user_id=user_id, strategy=strategy) == expected + chat_id, user_id, thread_id = case + assert ( + apply_strategy( + chat_id=chat_id, + user_id=user_id, + thread_id=thread_id, + strategy=strategy, + ) + == expected + ) diff --git a/tests/test_handler/test_base.py b/tests/test_handler/test_base.py index f79a6a6b..5f3b1225 100644 --- a/tests/test_handler/test_base.py +++ b/tests/test_handler/test_base.py @@ -29,15 +29,17 @@ class TestBaseClassBasedHandler: async def test_bot_from_context(self): event = Update(update_id=42) - handler = MyHandler(event=event, key=42) bot = Bot("42:TEST") - - with pytest.raises(LookupError): - handler.bot - - Bot.set_current(bot) + handler = MyHandler(event=event, key=42, bot=bot) assert handler.bot == bot + async def test_bot_from_context_missing(self): + event = Update(update_id=42) + handler = MyHandler(event=event, key=42) + + with pytest.raises(RuntimeError): + handler.bot + async def test_bot_from_data(self): event = Update(update_id=42) bot = Bot("42:TEST") diff --git a/tests/test_issues/__init__.py b/tests/test_issues/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_issues/test_bot_context_is_usable.py b/tests/test_issues/test_bot_context_is_usable.py new file mode 100644 index 00000000..f3db6b99 --- /dev/null +++ b/tests/test_issues/test_bot_context_is_usable.py @@ -0,0 +1,27 @@ +from datetime import datetime + +from aiogram import Dispatcher, Router +from aiogram.enums import ChatType +from aiogram.filters import Command +from aiogram.methods import SendMessage +from aiogram.types import Chat, Message, Update, User +from tests.mocked_bot import MockedBot + +issue_router = Router() + + +@issue_router.message(Command("test")) +async def my_handler(message: Message): + await message.answer("PASS") + return True + + +async def test_something(bot: MockedBot): + dp = Dispatcher() + dp.include_router(issue_router) + bot.add_result_for(method=SendMessage, ok=True) + chat = Chat(id=666, type=ChatType.PRIVATE) + user = User(id=666, is_bot=False, first_name="User") + msg = Message(message_id=1, date=datetime.now(), from_user=user, chat=chat, text="/test") + result = await dp.feed_update(bot, Update(message=msg, update_id=1)) + assert result is True diff --git a/tests/test_utils/test_chat_action.py b/tests/test_utils/test_chat_action.py index 517b8e90..84cb8abb 100644 --- a/tests/test_utils/test_chat_action.py +++ b/tests/test_utils/test_chat_action.py @@ -36,10 +36,9 @@ class TestChatActionSender: "upload_video_note", ], ) - @pytest.mark.parametrize("pass_bot", [True, False]) - async def test_factory(self, action: str, bot: MockedBot, pass_bot: bool): + async def test_factory(self, action: str, bot: MockedBot): sender_factory = getattr(ChatActionSender, action) - sender = sender_factory(chat_id=42, bot=bot if pass_bot else None) + sender = sender_factory(chat_id=42, bot=bot) assert isinstance(sender, ChatActionSender) assert sender.action == action assert sender.chat_id == 42 diff --git a/tests/test_utils/test_formatting.py b/tests/test_utils/test_formatting.py new file mode 100644 index 00000000..f135aca6 --- /dev/null +++ b/tests/test_utils/test_formatting.py @@ -0,0 +1,365 @@ +import pytest + +from aiogram.enums import MessageEntityType +from aiogram.types import MessageEntity, User +from aiogram.utils.formatting import ( + Bold, + BotCommand, + CashTag, + Code, + CustomEmoji, + Email, + HashTag, + Italic, + PhoneNumber, + Pre, + Spoiler, + Strikethrough, + Text, + TextLink, + TextMention, + Underline, + Url, + _apply_entity, + as_key_value, + as_line, + as_list, + as_marked_list, + as_marked_section, + as_numbered_list, + as_numbered_section, + as_section, +) +from aiogram.utils.text_decorations import html_decoration + + +class TestNode: + @pytest.mark.parametrize( + "node,result", + [ + [ + Text("test"), + "test", + ], + [ + HashTag("#test"), + "#test", + ], + [ + CashTag("$TEST"), + "$TEST", + ], + [ + BotCommand("/test"), + "/test", + ], + [ + Url("https://example.com"), + "https://example.com", + ], + [ + Email("test@example.com"), + "test@example.com", + ], + [ + PhoneNumber("test"), + "test", + ], + [ + Bold("test"), + "test", + ], + [ + Italic("test"), + "test", + ], + [ + Underline("test"), + "test", + ], + [ + Strikethrough("test"), + "test", + ], + [ + Spoiler("test"), + "test", + ], + [ + Code("test"), + "test", + ], + [ + Pre("test", language="python"), + '
test
', + ], + [ + TextLink("test", url="https://example.com"), + '
test', + ], + [ + TextMention("test", user=User(id=42, is_bot=False, first_name="Test")), + 'test', + ], + [ + CustomEmoji("test", custom_emoji_id="42"), + 'test', + ], + ], + ) + def test_render_plain_only(self, node: Text, result: str): + text, entities = node.render() + if node.type: + assert len(entities) == 1 + entity = entities[0] + assert entity.type == node.type + + content = html_decoration.unparse(text, entities) + assert content == result + + def test_render_text(self): + node = Text("Hello, ", "World", "!") + text, entities = node.render() + assert text == "Hello, World!" + assert not entities + + def test_render_nested(self): + node = Text( + Text("Hello, ", Bold("World"), "!"), + "\n", + Text(Bold("This ", Underline("is"), " test", Italic("!"))), + "\n", + HashTag("#test"), + ) + text, entities = node.render() + assert text == "Hello, World!\nThis is test!\n#test" + assert entities == [ + MessageEntity(type="bold", offset=7, length=5), + MessageEntity(type="bold", offset=14, length=13), + MessageEntity(type="underline", offset=19, length=2), + MessageEntity(type="italic", offset=26, length=1), + MessageEntity(type="hashtag", offset=28, length=5), + ] + + def test_as_kwargs_default(self): + node = Text("Hello, ", Bold("World"), "!") + result = node.as_kwargs() + assert "text" in result + assert "entities" in result + assert "parse_mode" in result + + def test_as_kwargs_custom(self): + node = Text("Hello, ", Bold("World"), "!") + result = node.as_kwargs( + text_key="caption", + entities_key="custom_entities", + parse_mode_key="custom_parse_mode", + ) + assert "text" not in result + assert "caption" in result + assert "entities" not in result + assert "custom_entities" in result + assert "parse_mode" not in result + assert "custom_parse_mode" in result + + def test_as_html(self): + node = Text("Hello, ", Bold("World"), "!") + assert node.as_html() == "Hello, World!" + + def test_as_markdown(self): + node = Text("Hello, ", Bold("World"), "!") + assert node.as_markdown() == r"Hello, *World*\!" + + def test_replace(self): + node0 = Text("test0", param0="test1") + node1 = node0.replace("test1", "test2", param1="test1") + assert node0._body != node1._body + assert node0._params != node1._params + assert "param1" not in node0._params + assert "param1" in node1._params + + def test_add(self): + node0 = Text("Hello") + node1 = Bold("World") + + node2 = node0 + Text(", ") + node1 + "!" + assert node0 != node2 + assert node1 != node2 + assert len(node0._body) == 1 + assert len(node1._body) == 1 + assert len(node2._body) == 3 + + text, entities = node2.render() + assert text == "Hello, World!" + + def test_getitem_position(self): + node = Text("Hello, ", Bold("World"), "!") + with pytest.raises(TypeError): + node[2] + + def test_getitem_empty_slice(self): + node = Text("Hello, ", Bold("World"), "!") + new_node = node[:] + assert new_node is not node + assert isinstance(new_node, Text) + assert new_node._body == node._body + + def test_getitem_slice_zero(self): + node = Text("Hello, ", Bold("World"), "!") + new_node = node[2:2] + assert node is not new_node + assert isinstance(new_node, Text) + assert not new_node._body + + def test_getitem_slice_simple(self): + node = Text("Hello, ", Bold("World"), "!") + new_node = node[2:10] + assert isinstance(new_node, Text) + text, entities = new_node.render() + assert text == "llo, Wor" + assert len(entities) == 1 + assert entities[0].type == MessageEntityType.BOLD + + def test_getitem_slice_inside_child(self): + node = Text("Hello, ", Bold("World"), "!") + new_node = node[8:10] + assert isinstance(new_node, Text) + text, entities = new_node.render() + assert text == "or" + assert len(entities) == 1 + assert entities[0].type == MessageEntityType.BOLD + + def test_getitem_slice_tail(self): + node = Text("Hello, ", Bold("World"), "!") + new_node = node[12:13] + assert isinstance(new_node, Text) + text, entities = new_node.render() + assert text == "!" + assert not entities + + def test_from_entities(self): + # Most of the cases covered by text_decorations module + + node = Strikethrough.from_entities( + text="test1 test2 test3 test4 test5 test6 test7", + entities=[ + MessageEntity(type="bold", offset=6, length=29), + MessageEntity(type="underline", offset=12, length=5), + MessageEntity(type="italic", offset=24, length=5), + ], + ) + assert len(node._body) == 3 + assert isinstance(node, Strikethrough) + rendered = node.as_html() + assert rendered == "test1 test2 test3 test4 test5 test6 test7" + + def test_pretty_string(self): + node = Strikethrough.from_entities( + text="X", + entities=[ + MessageEntity( + type=MessageEntityType.CUSTOM_EMOJI, + offset=0, + length=1, + custom_emoji_id="42", + ), + ], + ) + assert ( + node.as_pretty_string(indent=True) + == """Strikethrough( + Text( + 'X', + custom_emoji_id='42' + ) +)""" + ) + + +class TestHashTag: + def test_only_one_element_in_body(self): + with pytest.raises(ValueError): + HashTag("test", "test") + + def test_body_is_not_str(self): + with pytest.raises(ValueError): + HashTag(Text("test")) + + def test_with_no_prefix(self): + node = HashTag("test") + assert node._body == ("#test",) + + def test_with_prefix(self): + node = HashTag("#test") + assert node._body == ("#test",) + + +class TestCashTag: + def test_only_one_element_in_body(self): + with pytest.raises(ValueError): + CashTag("test", "test") + + def test_body_is_not_str(self): + with pytest.raises(ValueError): + CashTag(Text("test")) + + def test_with_no_prefix(self): + node = CashTag("USD") + assert node._body == ("$USD",) + + def test_with_prefix(self): + node = CashTag("$USD") + assert node._body == ("$USD",) + + +class TestUtils: + def test_apply_entity(self): + node = _apply_entity( + MessageEntity(type=MessageEntityType.BOLD, offset=0, length=4), "test" + ) + assert isinstance(node, Bold) + assert node._body == ("test",) + + def test_as_line(self): + node = as_line("test", "test", "test") + assert isinstance(node, Text) + assert len(node._body) == 4 # 3 + '\n' + + def test_line_with_sep(self): + node = as_line("test", "test", "test", sep=" ") + assert isinstance(node, Text) + assert len(node._body) == 6 # 3 + 2 * ' ' + '\n' + + def test_as_line_single_element_with_sep(self): + node = as_line("test", sep=" ") + assert isinstance(node, Text) + assert len(node._body) == 2 # 1 + '\n' + + def test_as_list(self): + node = as_list("test", "test", "test") + assert isinstance(node, Text) + assert len(node._body) == 5 # 3 + 2 * '\n' between lines + + def test_as_marked_list(self): + node = as_marked_list("test 1", "test 2", "test 3") + assert node.as_html() == "- test 1\n- test 2\n- test 3" + + def test_as_numbered_list(self): + node = as_numbered_list("test 1", "test 2", "test 3", start=5) + assert node.as_html() == "5. test 1\n6. test 2\n7. test 3" + + def test_as_section(self): + node = as_section("title", "test 1", "test 2", "test 3") + assert node.as_html() == "title\ntest 1test 2test 3" + + def test_as_marked_section(self): + node = as_marked_section("Section", "test 1", "test 2", "test 3") + assert node.as_html() == "Section\n- test 1\n- test 2\n- test 3" + + def test_as_numbered_section(self): + node = as_numbered_section("Section", "test 1", "test 2", "test 3", start=5) + assert node.as_html() == "Section\n5. test 1\n6. test 2\n7. test 3" + + def test_as_key_value(self): + node = as_key_value("key", "test 1") + assert node.as_html() == "key: test 1" diff --git a/tests/test_utils/test_i18n.py b/tests/test_utils/test_i18n.py index 434d2e02..71fa2eb7 100644 --- a/tests/test_utils/test_i18n.py +++ b/tests/test_utils/test_i18n.py @@ -178,9 +178,7 @@ class TestFSMI18nMiddleware: async def test_middleware(self, i18n: I18n, bot: MockedBot, extra): middleware = FSMI18nMiddleware(i18n=i18n) storage = MemoryStorage() - state = FSMContext( - bot=bot, storage=storage, key=StorageKey(user_id=42, chat_id=42, bot_id=bot.id) - ) + state = FSMContext(storage=storage, key=StorageKey(user_id=42, chat_id=42, bot_id=bot.id)) data = { "event_from_user": User(id=42, is_bot=False, language_code="it", first_name="Test"), "state": state, diff --git a/tests/test_utils/test_link.py b/tests/test_utils/test_link.py index 8d74f0c6..f0276703 100644 --- a/tests/test_utils/test_link.py +++ b/tests/test_utils/test_link.py @@ -1,14 +1,22 @@ +from itertools import product from typing import Any, Dict +from urllib.parse import parse_qs import pytest -from aiogram.utils.link import BRANCH, create_telegram_link, create_tg_link, docs_url +from aiogram.utils.link import ( + BRANCH, + create_channel_bot_link, + create_telegram_link, + create_tg_link, + docs_url, +) class TestLink: @pytest.mark.parametrize( "base,params,result", - [["user", dict(id=42), "tg://user?id=42"]], + [["user", {"id": 42}, "tg://user?id=42"]], ) def test_create_tg_link(self, base: str, params: Dict[str, Any], result: str): assert create_tg_link(base, **params) == result @@ -16,8 +24,8 @@ class TestLink: @pytest.mark.parametrize( "base,params,result", [ - ["username", dict(), "https://t.me/username"], - ["username", dict(start="test"), "https://t.me/username?start=test"], + ["username", {}, "https://t.me/username"], + ["username", {"start": "test"}, "https://t.me/username?start=test"], ], ) def test_create_telegram_link(self, base: str, params: Dict[str, Any], result: str): @@ -31,3 +39,45 @@ class TestLink: def test_docs(self): assert docs_url("test.html") == f"https://docs.aiogram.dev/en/{BRANCH}/test.html" + + +class TestCreateChannelBotLink: + def test_without_params(self): + assert create_channel_bot_link("test_bot") == "https://t.me/test_bot" + + def test_parameter(self): + assert ( + create_channel_bot_link("test_bot", parameter="parameter in group") + == "https://t.me/test_bot?startgroup=parameter+in+group" + ) + + def test_permissions(self): + # Is bad idea to put over 2k cases into parameterized test, + # so I've preferred to implement it inside the test + + params = { + "change_info", + "post_messages", + "edit_messages", + "delete_messages", + "restrict_members", + "invite_users", + "pin_messages", + "promote_members", + "manage_video_chats", + "anonymous", + "manage_chat", + } + + variants = product([True, False], repeat=len(params)) + for index, variants in enumerate(variants): + kwargs = {k: v for k, v in zip(params, variants) if v} + if not kwargs: + # Variant without additional arguments is already covered + continue + + link = create_channel_bot_link("test", **kwargs) + query = parse_qs(link.split("?", maxsplit=1)[-1], max_num_fields=1) + assert "admin" in query + admin = query["admin"][0] + assert set(admin.split("+")) == set(kwargs) diff --git a/tests/test_utils/test_text_decorations.py b/tests/test_utils/test_text_decorations.py index 01fbabb6..056bd1cb 100644 --- a/tests/test_utils/test_text_decorations.py +++ b/tests/test_utils/test_text_decorations.py @@ -90,7 +90,7 @@ class TestTextDecoration: [markdown_decoration, MessageEntity(type="bot_command", offset=0, length=5), "test"], [markdown_decoration, MessageEntity(type="email", offset=0, length=5), "test"], [markdown_decoration, MessageEntity(type="phone_number", offset=0, length=5), "test"], - [markdown_decoration, MessageEntity(type="spoiler", offset=0, length=5), "|test|"], + [markdown_decoration, MessageEntity(type="spoiler", offset=0, length=5), "||test||"], [ markdown_decoration, MessageEntity(type="custom_emoji", offset=0, length=5, custom_emoji_id="42"), diff --git a/tests/test_webhook/test_aiohtt_server.py b/tests/test_webhook/test_aiohtt_server.py index 5be8f43e..4e3f6658 100644 --- a/tests/test_webhook/test_aiohtt_server.py +++ b/tests/test_webhook/test_aiohtt_server.py @@ -189,8 +189,24 @@ class TestSimpleRequestHandler: result = await resp.json() assert not result + async def test_verify_secret(self, bot: MockedBot, aiohttp_client): + app = Application() + dp = Dispatcher() + handler = SimpleRequestHandler( + dispatcher=dp, bot=bot, handle_in_background=False, secret_token="vasya228" + ) + handler.register(app, path="/webhook") + client: TestClient = await aiohttp_client(app) + resp = await self.make_reqest(client=client) + assert resp.status == 401 + class TestTokenBasedRequestHandler: + async def test_verify_secret(self, bot: MockedBot): + dispatcher = Dispatcher() + handler = TokenBasedRequestHandler(dispatcher=dispatcher) + assert handler.verify_secret("petro328", bot) + async def test_register(self): dispatcher = Dispatcher() app = Application()