From e0c314376321617d082206e065d382bbeebf66e9 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Mon, 22 Jun 2020 13:21:45 +0200 Subject: [PATCH] Update documentation with new errors and further clarifications --- telethon/client/downloads.py | 15 +++----- telethon/tl/custom/conversation.py | 53 ++++++++++++++++++++++------- telethon_generator/data/errors.csv | 2 ++ telethon_generator/data/methods.csv | 4 +-- 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/telethon/client/downloads.py b/telethon/client/downloads.py index 1b06bfe6..25910ffd 100644 --- a/telethon/client/downloads.py +++ b/telethon/client/downloads.py @@ -568,19 +568,12 @@ class DownloadMethods: # Fetching only the header of a file (32 bytes) # You should manually close the iterator in this case. # - # telethon.sync must be imported for this to work, - # and you must not be inside an "async def". + # "stream" is a common name for asynchronous generators, + # and iter_download will yield `bytes` (chunks of the file). stream = client.iter_download(media, request_size=32) - header = next(stream) - stream.close() + header = await stream.__anext__() # "manual" version of `async for` + await stream.close() assert len(header) == 32 - - # Fetching only the header, inside of an ``async def`` - async def main(): - stream = client.iter_download(media, request_size=32) - header = await stream.__anext__() - await stream.close() - assert len(header) == 32 """ info = utils._get_file_info(file) if info.dc_id is not None: diff --git a/telethon/tl/custom/conversation.py b/telethon/tl/custom/conversation.py index 46b67aa8..65ec2725 100644 --- a/telethon/tl/custom/conversation.py +++ b/telethon/tl/custom/conversation.py @@ -132,7 +132,8 @@ class Conversation(ChatGetter): def get_response(self, message=None, *, timeout=None): """ - Gets the next message that responds to a previous one. + Gets the next message that responds to a previous one. This is + the method you need most of the time, along with `get_edit`. Args: message (`Message ` | `int`, optional): @@ -142,6 +143,16 @@ class Conversation(ChatGetter): timeout (`int` | `float`, optional): If present, this `timeout` (in seconds) will override the per-action timeout defined for the conversation. + + .. code-block:: python + + async with client.conversation(...) as conv: + await conv.send_message('Hey, what is your name?') + + response = await conv.get_response() + name = response.text + + await conv.send_message('Nice to meet you, {}!'.format(name)) """ return self._get_message( message, self._response_indices, self._pending_responses, timeout, @@ -272,23 +283,41 @@ class Conversation(ChatGetter): .. note:: - Only use this if there isn't another method available! + **Only use this if there isn't another method available!** For example, don't use `wait_event` for new messages, since `get_response` already exists, etc. Unless you're certain that your code will run fast enough, generally you should get a "handle" of this special coroutine - before acting. Generally, you should do this: + before acting. In this example you will see how to wait for a user + to join a group with proper use of `wait_event`: - >>> from telethon import TelegramClient, events - >>> - >>> client = TelegramClient(...) - >>> - >>> async def main(): - >>> async with client.conversation(...) as conv: - >>> response = conv.wait_event(events.NewMessage(incoming=True)) - >>> await conv.send_message('Hi') - >>> response = await response + .. code-block:: python + + from telethon import TelegramClient, events + + client = TelegramClient(...) + group_id = ... + + async def main(): + # Could also get the user id from an event; this is just an example + user_id = ... + + async with client.conversation(user_id) as conv: + # Get a handle to the future event we'll wait for + handle = conv.wait_event(events.ChatAction( + group_id, + func=lambda e: e.user_joined and e.user_id == user_id + )) + + # Perform whatever action in between + await conv.send_message('Please join this group before speaking to me!') + + # Wait for the event we registered above to fire + event = await handle + + # Continue with the conversation + await conv.send_message('Thanks!') This way your event can be registered before acting, since the response may arrive before your event was diff --git a/telethon_generator/data/errors.csv b/telethon_generator/data/errors.csv index abe45be0..e93dced3 100644 --- a/telethon_generator/data/errors.csv +++ b/telethon_generator/data/errors.csv @@ -108,6 +108,7 @@ FILE_PART_SIZE_CHANGED,400,The file part size (chunk size) cannot change during FILE_PART_SIZE_INVALID,400,The provided file part size is invalid FILE_PART_X_MISSING,400,Part {which} of the file is missing from storage FILE_REFERENCE_EMPTY,400,The file reference must exist to access the media and it cannot be empty +FILE_REFERENCE_EXPIRED,400,The file reference has expired and is no longer valid or it belongs to self-destructing media and cannot be resent FILEREF_UPGRADE_NEEDED,406,The file reference needs to be refreshed before being used again FIRSTNAME_INVALID,400,The first name is invalid FLOOD_TEST_PHONE_WAIT_X,420,A wait of {seconds} seconds is required in the test servers @@ -163,6 +164,7 @@ MESSAGE_ID_INVALID,400,"The specified message ID is invalid or you can't do that MESSAGE_NOT_MODIFIED,400,Content of the message was not modified MESSAGE_POLL_CLOSED,400,The poll was closed and can no longer be voted on MESSAGE_TOO_LONG,400,Message was too long. Current maximum length is 4096 UTF-8 characters +METHOD_INVALID,400,The API method is invalid and cannot be used MSGID_DECREASE_RETRY,500,The request should be retried with a lower message ID MSG_ID_INVALID,400,The message ID used in the peer was invalid MSG_WAIT_FAILED,400,A waiting call returned an error diff --git a/telethon_generator/data/methods.csv b/telethon_generator/data/methods.csv index 71fd5ae7..20e50aae 100644 --- a/telethon_generator/data/methods.csv +++ b/telethon_generator/data/methods.csv @@ -265,14 +265,14 @@ messages.saveDraft,user,PEER_ID_INVALID messages.saveGif,user,GIF_ID_INVALID messages.saveRecentSticker,user,STICKER_ID_INVALID messages.search,user,CHAT_ADMIN_REQUIRED INPUT_CONSTRUCTOR_INVALID INPUT_USER_DEACTIVATED PEER_ID_INVALID PEER_ID_NOT_SUPPORTED SEARCH_QUERY_EMPTY USER_ID_INVALID -messages.searchGifs,user,SEARCH_QUERY_EMPTY +messages.searchGifs,user,METHOD_INVALID SEARCH_QUERY_EMPTY messages.searchGlobal,user,SEARCH_QUERY_EMPTY messages.searchStickerSets,user, messages.sendEncrypted,user,CHAT_ID_INVALID DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED messages.sendEncryptedFile,user,MSG_WAIT_FAILED messages.sendEncryptedService,user,DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED USER_IS_BLOCKED messages.sendInlineBotResult,user,CHAT_SEND_INLINE_FORBIDDEN CHAT_WRITE_FORBIDDEN INLINE_RESULT_EXPIRED PEER_ID_INVALID QUERY_ID_EMPTY SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY -messages.sendMedia,both,BOT_PAYMENTS_DISABLED BOT_POLLS_DISABLED BROADCAST_PUBLIC_VOTERS_FORBIDDEN CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EMOTICON_INVALID EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID FILE_REFERENCE_EMPTY GAME_BOT_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PAYMENT_PROVIDER_INVALID PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID POLL_ANSWERS_INVALID POLL_OPTION_DUPLICATE POLL_QUESTION_INVALID QUIZ_CORRECT_ANSWERS_EMPTY QUIZ_CORRECT_ANSWERS_TOO_MUCH QUIZ_CORRECT_ANSWER_INVALID QUIZ_MULTIPLE_INVALID RANDOM_ID_DUPLICATE SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY +messages.sendMedia,both,BOT_PAYMENTS_DISABLED BOT_POLLS_DISABLED BROADCAST_PUBLIC_VOTERS_FORBIDDEN CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EMOTICON_INVALID EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID FILE_REFERENCE_EMPTY FILE_REFERENCE_EXPIRED GAME_BOT_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PAYMENT_PROVIDER_INVALID PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID POLL_ANSWERS_INVALID POLL_OPTION_DUPLICATE POLL_QUESTION_INVALID QUIZ_CORRECT_ANSWERS_EMPTY QUIZ_CORRECT_ANSWERS_TOO_MUCH QUIZ_CORRECT_ANSWER_INVALID QUIZ_MULTIPLE_INVALID RANDOM_ID_DUPLICATE SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY messages.sendMessage,both,AUTH_KEY_DUPLICATED BUTTON_DATA_INVALID BUTTON_TYPE_INVALID BUTTON_URL_INVALID CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_ID_INVALID CHAT_RESTRICTED CHAT_WRITE_FORBIDDEN ENTITIES_TOO_LONG ENTITY_MENTION_USER_INVALID INPUT_USER_DEACTIVATED MESSAGE_EMPTY MESSAGE_TOO_LONG MSG_ID_INVALID PEER_ID_INVALID POLL_OPTION_INVALID RANDOM_ID_DUPLICATE REPLY_MARKUP_INVALID REPLY_MARKUP_TOO_LONG SCHEDULE_BOT_NOT_ALLOWED SCHEDULE_DATE_TOO_LATE SCHEDULE_STATUS_PRIVATE SCHEDULE_TOO_MUCH Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER messages.sendMultiMedia,both,SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH messages.sendScheduledMessages,user,