Update docstrings to have consistent style

This commit is contained in:
Lonami Exo 2019-05-20 11:38:26 +02:00
parent 4b74d16438
commit 7c1c040d50
15 changed files with 501 additions and 295 deletions

View File

@ -127,13 +127,6 @@ class AccountMethods(UserMethods):
them. In other words, returns the current client modified so that them. In other words, returns the current client modified so that
requests are done as a takeout: requests are done as a takeout:
>>> from telethon.sync import TelegramClient
>>>
>>> with TelegramClient(...) as client:
>>> with client.takeout() as takeout:
>>> client.get_messages('me') # normal call
>>> takeout.get_messages('me') # wrapped through takeout
Some of the calls made through the takeout session will have lower Some of the calls made through the takeout session will have lower
flood limits. This is useful if you want to export the data from flood limits. This is useful if you want to export the data from
conversations or mass-download media, since the rate limits will conversations or mass-download media, since the rate limits will
@ -159,7 +152,7 @@ class AccountMethods(UserMethods):
preserved for future usage as `client.session.takeout_id preserved for future usage as `client.session.takeout_id
<telethon.sessions.abstract.Session.takeout_id>`. <telethon.sessions.abstract.Session.takeout_id>`.
Args: Arguments
finalize (`bool`): finalize (`bool`):
Whether the takeout session should be finalized upon Whether the takeout session should be finalized upon
exit or not. exit or not.
@ -191,14 +184,16 @@ class AccountMethods(UserMethods):
The maximum file size, in bytes, that you plan The maximum file size, in bytes, that you plan
to download for each message with media. to download for each message with media.
Example: Example
.. code-block:: python .. code-block:: python
from telethon import errors from telethon import errors
try: try:
with client.takeout() as takeout: with client.takeout() as takeout:
client.get_messages('me') # normal call
takeout.get_messages('me') # wrapped through takeout (less limits)
for message in takeout.iter_messages(chat, wait_time=0): for message in takeout.iter_messages(chat, wait_time=0):
... # Do something with the message ... # Do something with the message
@ -228,12 +223,17 @@ class AccountMethods(UserMethods):
""" """
Finishes the current takeout session. Finishes the current takeout session.
Args: Arguments
success (`bool`): success (`bool`):
Whether the takeout completed successfully or not. Whether the takeout completed successfully or not.
Returns: Returns
``True`` if the operation was successful, ``False`` otherwise. ``True`` if the operation was successful, ``False`` otherwise.
Example
.. code-block:: python
client.end_takeout(success=False)
""" """
try: try:
async with _TakeoutClient(True, self, None) as takeout: async with _TakeoutClient(True, self, None) as takeout:

View File

@ -44,7 +44,7 @@ class AuthMethods(MessageParseMethods, UserMethods):
coroutine that you should await on your own code; otherwise coroutine that you should await on your own code; otherwise
the loop is ran until said coroutine completes. the loop is ran until said coroutine completes.
Args: Arguments
phone (`str` | `int` | `callable`): phone (`str` | `int` | `callable`):
The phone (or callable without arguments to get it) The phone (or callable without arguments to get it)
to which the code will be sent. If a bot-token-like to which the code will be sent. If a bot-token-like
@ -81,11 +81,11 @@ class AuthMethods(MessageParseMethods, UserMethods):
How many times the code/password callback should be How many times the code/password callback should be
retried or switching between signing in and signing up. retried or switching between signing in and signing up.
Returns: Returns
This `TelegramClient`, so initialization This `TelegramClient`, so initialization
can be chained with ``.start()``. can be chained with ``.start()``.
Example: Example
.. code-block:: python .. code-block:: python
client = TelegramClient('anon', api_id, api_hash) client = TelegramClient('anon', api_id, api_hash)
@ -271,7 +271,7 @@ class AuthMethods(MessageParseMethods, UserMethods):
This method will send the code if it's not provided. This method will send the code if it's not provided.
Args: Arguments
phone (`str` | `int`): phone (`str` | `int`):
The phone to send the code to if no code was provided, The phone to send the code to if no code was provided,
or to override the phone that was previously used with or to override the phone that was previously used with
@ -295,9 +295,18 @@ class AuthMethods(MessageParseMethods, UserMethods):
The hash returned by `send_code_request`. This can be left as The hash returned by `send_code_request`. This can be left as
``None`` to use the last hash known for the phone to be used. ``None`` to use the last hash known for the phone to be used.
Returns: Returns
The signed in user, or the information about The signed in user, or the information about
:meth:`send_code_request`. :meth:`send_code_request`.
Example
.. code-block:: python
phone = '+34 123 123 123'
client.sign_in(phone) # send code
code = input('enter code: ')
client.sign_in(phone, code)
""" """
me = await self.get_me() me = await self.get_me()
if me: if me:
@ -351,7 +360,7 @@ class AuthMethods(MessageParseMethods, UserMethods):
will be banned otherwise.** See https://telegram.org/tos will be banned otherwise.** See https://telegram.org/tos
and https://core.telegram.org/api/terms. and https://core.telegram.org/api/terms.
Args: Arguments
code (`str` | `int`): code (`str` | `int`):
The code sent by Telegram The code sent by Telegram
@ -369,8 +378,17 @@ class AuthMethods(MessageParseMethods, UserMethods):
The hash returned by `send_code_request`. This can be left as The hash returned by `send_code_request`. This can be left as
``None`` to use the last hash known for the phone to be used. ``None`` to use the last hash known for the phone to be used.
Returns: Returns
The new created :tl:`User`. The new created :tl:`User`.
Example
.. code-block:: python
phone = '+34 123 123 123'
client.send_code_request(phone)
code = input('enter code: ')
client.sign_up(code, first_name='Anna', last_name='Banana')
""" """
me = await self.get_me() me = await self.get_me()
if me: if me:
@ -421,15 +439,27 @@ class AuthMethods(MessageParseMethods, UserMethods):
""" """
Sends the Telegram code needed to login to the given phone number. Sends the Telegram code needed to login to the given phone number.
Args: Arguments
phone (`str` | `int`): phone (`str` | `int`):
The phone to which the code will be sent. The phone to which the code will be sent.
force_sms (`bool`, optional): force_sms (`bool`, optional):
Whether to force sending as SMS. Whether to force sending as SMS.
Returns: Returns
An instance of :tl:`SentCode`. An instance of :tl:`SentCode`.
Example
.. code-block:: python
phone = '+34 123 123 123'
sent = client.send_code_request(phone)
print(sent)
if sent.phone_registered:
print('This phone has an existing account registered')
else:
print('This phone does not have an account registered')
""" """
result = None result = None
phone = utils.parse_phone(phone) or self._phone phone = utils.parse_phone(phone) or self._phone
@ -461,11 +491,10 @@ class AuthMethods(MessageParseMethods, UserMethods):
""" """
Logs out Telegram and deletes the current ``*.session`` file. Logs out Telegram and deletes the current ``*.session`` file.
Returns: Returns
``True`` if the operation was successful. ``True`` if the operation was successful.
Example: Example
.. code-block:: python .. code-block:: python
# Note: you will need to login again! # Note: you will need to login again!
@ -504,37 +533,47 @@ class AuthMethods(MessageParseMethods, UserMethods):
Has no effect if both current and new password are omitted. Has no effect if both current and new password are omitted.
current_password (`str`, optional): Arguments
The current password, to authorize changing to ``new_password``. current_password (`str`, optional):
Must be set if changing existing 2FA settings. The current password, to authorize changing to ``new_password``.
Must **not** be set if 2FA is currently disabled. Must be set if changing existing 2FA settings.
Passing this by itself will remove 2FA (if correct). Must **not** be set if 2FA is currently disabled.
Passing this by itself will remove 2FA (if correct).
new_password (`str`, optional): new_password (`str`, optional):
The password to set as 2FA. The password to set as 2FA.
If 2FA was already enabled, ``current_password`` **must** be set. If 2FA was already enabled, ``current_password`` **must** be set.
Leaving this blank or ``None`` will remove the password. Leaving this blank or ``None`` will remove the password.
hint (`str`, optional): hint (`str`, optional):
Hint to be displayed by Telegram when it asks for 2FA. Hint to be displayed by Telegram when it asks for 2FA.
Leaving unspecified is highly discouraged. Leaving unspecified is highly discouraged.
Has no effect if ``new_password`` is not set. Has no effect if ``new_password`` is not set.
email (`str`, optional): email (`str`, optional):
Recovery and verification email. If present, you must also Recovery and verification email. If present, you must also
set `email_code_callback`, else it raises ``ValueError``. set `email_code_callback`, else it raises ``ValueError``.
email_code_callback (`callable`, optional): email_code_callback (`callable`, optional):
If an email is provided, a callback that returns the code sent If an email is provided, a callback that returns the code sent
to it must also be set. This callback may be asynchronous. to it must also be set. This callback may be asynchronous.
It should return a string with the code. The length of the It should return a string with the code. The length of the
code will be passed to the callback as an input parameter. code will be passed to the callback as an input parameter.
If the callback returns an invalid code, it will raise If the callback returns an invalid code, it will raise
``CodeInvalidError``. ``CodeInvalidError``.
Returns: Returns
``True`` if successful, ``False`` otherwise. ``True`` if successful, ``False`` otherwise.
Example
.. code-block:: python
# Setting a password for your account which didn't have
client.edit_2fa(new_password='I_<3_Telethon')
# Removing the password
client.edit_2fa(current_password='I_<3_Telethon')
""" """
if new_password is None and current_password is None: if new_password is None and current_password is None:
return False return False

View File

@ -19,10 +19,7 @@ class BotMethods(UserMethods):
""" """
Makes an inline query to the specified bot (e.g. ``@vote New Poll``). Makes an inline query to the specified bot (e.g. ``@vote New Poll``).
>>> client = ... Arguments
>>> client.inline_query('vote', 'My New Poll')
Args:
bot (`entity`): bot (`entity`):
The bot entity to which the inline query should be made. The bot entity to which the inline query should be made.
@ -36,12 +33,11 @@ class BotMethods(UserMethods):
The geo point location information to send to the bot The geo point location information to send to the bot
for localised results. Available under some bots. for localised results. Available under some bots.
Returns: Returns
A list of `custom.InlineResult A list of `custom.InlineResult
<telethon.tl.custom.inlineresult.InlineResult>`. <telethon.tl.custom.inlineresult.InlineResult>`.
Example: Example
.. code-block:: python .. code-block:: python
# Make an inline query to @like # Make an inline query to @like

View File

@ -24,6 +24,22 @@ class ButtonMethods(UpdateMethods):
the markup very often. Otherwise, it is not necessary. the markup very often. Otherwise, it is not necessary.
This method is **not** asynchronous (don't use ``await`` on it). This method is **not** asynchronous (don't use ``await`` on it).
Arguments
buttons (`hints.MarkupLike`):
The button, list of buttons, array of buttons or markup
to convert into a markup.
inline_only (`bool`, optional):
Whether the buttons **must** be inline buttons only or not.
Example
.. code-block:: python
from telethon import Button
markup = client.build_reply_markup(Button.inline('hi'))
client.send_message('click me', buttons=markup)
""" """
if buttons is None: if buttons is None:
return None return None

View File

@ -289,7 +289,7 @@ class ChatMethods(UserMethods):
""" """
Iterator over the participants belonging to the specified chat. Iterator over the participants belonging to the specified chat.
Args: Arguments
entity (`entity`): entity (`entity`):
The entity from which to retrieve the participants list. The entity from which to retrieve the participants list.
@ -323,14 +323,13 @@ class ChatMethods(UserMethods):
This has no effect if a ``filter`` is given. This has no effect if a ``filter`` is given.
Yields: Yields
The :tl:`User` objects returned by :tl:`GetParticipantsRequest` The :tl:`User` objects returned by :tl:`GetParticipantsRequest`
with an additional ``.participant`` attribute which is the with an additional ``.participant`` attribute which is the
matched :tl:`ChannelParticipant` type for channels/megagroups matched :tl:`ChannelParticipant` type for channels/megagroups
or :tl:`ChatParticipants` for normal chats. or :tl:`ChatParticipants` for normal chats.
Example: Example
.. code-block:: python .. code-block:: python
# Show all user IDs in a chat # Show all user IDs in a chat
@ -362,6 +361,16 @@ class ChatMethods(UserMethods):
""" """
Same as `iter_participants()`, but returns a Same as `iter_participants()`, but returns a
`TotalList <telethon.helpers.TotalList>` instead. `TotalList <telethon.helpers.TotalList>` instead.
Example
.. code-block:: python
users = client.get_participants(chat)
print(users[0].first_name)
for user in users:
if user.username is not None:
print(user.username)
""" """
return await self.iter_participants(*args, **kwargs).collect() return await self.iter_participants(*args, **kwargs).collect()
@ -397,7 +406,7 @@ class ChatMethods(UserMethods):
*all* event types will be returned. If at least one of them is *all* event types will be returned. If at least one of them is
``True``, only those that are true will be returned. ``True``, only those that are true will be returned.
Args: Arguments
entity (`entity`): entity (`entity`):
The channel entity from which to get its admin log. The channel entity from which to get its admin log.
@ -472,22 +481,15 @@ class ChatMethods(UserMethods):
delete (`bool`): delete (`bool`):
If ``True``, events of message deletions will be returned. If ``True``, events of message deletions will be returned.
Yields: Yields
Instances of `telethon.tl.custom.adminlogevent.AdminLogEvent`. Instances of `telethon.tl.custom.adminlogevent.AdminLogEvent`.
Example: Example
.. code-block:: python .. code-block:: python
for event in client.iter_admin_log(channel): for event in client.iter_admin_log(channel):
if event.changed_title: if event.changed_title:
print('The title changed from', event.old, 'to', event.new) print('The title changed from', event.old, 'to', event.new)
# Get a list of deleted message events which said "heck"
events = client.get_admin_log(channel, search='heck', delete=True)
# Print the old message before it was deleted
print(events[0].old)
""" """
return _AdminLogIter( return _AdminLogIter(
self, self,
@ -519,6 +521,15 @@ class ChatMethods(UserMethods):
**kwargs) -> 'hints.TotalList': **kwargs) -> 'hints.TotalList':
""" """
Same as `iter_admin_log()`, but returns a ``list`` instead. Same as `iter_admin_log()`, but returns a ``list`` instead.
Example
.. code-block:: python
# Get a list of deleted message events which said "heck"
events = client.get_admin_log(channel, search='heck', delete=True)
# Print the old message before it was deleted
print(events[0].old)
""" """
return await self.iter_admin_log(*args, **kwargs).collect() return await self.iter_admin_log(*args, **kwargs).collect()
@ -533,22 +544,14 @@ class ChatMethods(UserMethods):
Returns a context-manager object to represent a "chat action". Returns a context-manager object to represent a "chat action".
Chat actions indicate things like "user is typing", "user is Chat actions indicate things like "user is typing", "user is
uploading a photo", etc. Normal usage is as follows: uploading a photo", etc.
.. code-block:: python
async with client.action(chat, 'typing'):
await asyncio.sleep(2) # type for 2 seconds
await client.send_message(chat, 'Hello world! I type slow ^^')
If the action is ``'cancel'``, you should just ``await`` the result, If the action is ``'cancel'``, you should just ``await`` the result,
since it makes no sense to use a context-manager for it: since it makes no sense to use a context-manager for it.
.. code-block:: python See the example below for intended usage.
await client.action(chat, 'cancel') Arguments
Args:
entity (`entity`): entity (`entity`):
The entity where the action should be showed in. The entity where the action should be showed in.
@ -587,10 +590,23 @@ class ChatMethods(UserMethods):
you don't want progress to be shown when it has already you don't want progress to be shown when it has already
completed. completed.
If you are uploading a file, you may do Returns
``progress_callback=chat.progress`` to update the progress of Either a context-manager object or a coroutine.
the action. Some clients don't care about this progress, though,
so it's mostly not needed, but still available. Example
.. code-block:: python
# Type for 2 seconds, then send a message
async with client.action(chat, 'typing'):
await asyncio.sleep(2)
await client.send_message(chat, 'Hello world! I type slow ^^')
# Cancel any previous action
await client.action(chat, 'cancel')
# Upload a document, showing its progress (most clients ignore this)
async with client.action(chat, 'document') as action:
client.send_file(chat, zip_file, progress_callback=action.progress)
""" """
if isinstance(action, str): if isinstance(action, str):
try: try:

View File

@ -117,7 +117,7 @@ class DialogMethods(UserMethods):
""" """
Iterator over the dialogs (open conversations/subscribed channels). Iterator over the dialogs (open conversations/subscribed channels).
Args: Arguments
limit (`int` | `None`): limit (`int` | `None`):
How many dialogs to be retrieved as maximum. Can be set to How many dialogs to be retrieved as maximum. Can be set to
``None`` to retrieve all dialogs. Note that this may take ``None`` to retrieve all dialogs. Note that this may take
@ -159,31 +159,15 @@ class DialogMethods(UserMethods):
archived (`bool`, optional): archived (`bool`, optional):
Alias for `folder`. If unspecified, all will be returned, Alias for `folder`. If unspecified, all will be returned,
``False`` implies ``folder=0`` and ``True`` implies ``folder=1``. ``False`` implies ``folder=0`` and ``True`` implies ``folder=1``.
Yields: Yields
Instances of `telethon.tl.custom.dialog.Dialog`. Instances of `telethon.tl.custom.dialog.Dialog`.
Example: Example
.. code-block:: python .. code-block:: python
# Get all open conversation, print the title of the first # Print all dialog IDs and the title, nicely formatted
dialogs = client.get_dialogs() for dialog in client.iter_dialogs():
first = dialogs[0] print('{:>14}: {}'.format(dialog.id, dialog.title))
print(first.title)
# Use the dialog somewhere else
client.send_message(first, 'hi')
# Get drafts
drafts = client.get_drafts()
# Getting only non-archived dialogs (both equivalent)
non_archived = client.get_dialogs(folder=0)
non_archived = client.get_dialogs(archived=False)
# Getting only archived dialogs (both equivalent)
archived = client.get_dialogs(folder=1)
non_archived = client.get_dialogs(archived=True)
""" """
if archived is not None: if archived is not None:
folder = 1 if archived else 0 folder = 1 if archived else 0
@ -202,6 +186,25 @@ class DialogMethods(UserMethods):
""" """
Same as `iter_dialogs()`, but returns a Same as `iter_dialogs()`, but returns a
`TotalList <telethon.helpers.TotalList>` instead. `TotalList <telethon.helpers.TotalList>` instead.
Example
.. code-block:: python
# Get all open conversation, print the title of the first
dialogs = client.get_dialogs()
first = dialogs[0]
print(first.title)
# Use the dialog somewhere else
client.send_message(first, 'hi')
# Getting only non-archived dialogs (both equivalent)
non_archived = client.get_dialogs(folder=0)
non_archived = client.get_dialogs(archived=False)
# Getting only archived dialogs (both equivalent)
archived = client.get_dialogs(folder=1)
non_archived = client.get_dialogs(archived=True)
""" """
return await self.iter_dialogs(*args, **kwargs).collect() return await self.iter_dialogs(*args, **kwargs).collect()
@ -213,6 +216,13 @@ class DialogMethods(UserMethods):
You can call `telethon.tl.custom.draft.Draft.set_message` You can call `telethon.tl.custom.draft.Draft.set_message`
to change the message or `telethon.tl.custom.draft.Draft.delete` to change the message or `telethon.tl.custom.draft.Draft.delete`
among other things. among other things.
Example
.. code-block:: python
# Clear all drafts
for draft in client.get_drafts():
draft.delete()
""" """
# TODO Passing a limit here makes no sense # TODO Passing a limit here makes no sense
return _DraftsIter(self, None) return _DraftsIter(self, None)
@ -220,6 +230,13 @@ class DialogMethods(UserMethods):
async def get_drafts(self: 'TelegramClient') -> 'hints.TotalList': async def get_drafts(self: 'TelegramClient') -> 'hints.TotalList':
""" """
Same as `iter_drafts()`, but returns a list instead. Same as `iter_drafts()`, but returns a list instead.
Example
.. code-block:: python
# Get drafts, print the text of the first
drafts = client.get_drafts()
print(drafts[0].text)
""" """
return await self.iter_drafts().collect() return await self.iter_drafts().collect()
@ -233,7 +250,7 @@ class DialogMethods(UserMethods):
""" """
Archives (or un-archives) one or more dialogs. Archives (or un-archives) one or more dialogs.
Args: Arguments
entity (entities): entity (entities):
The entity or list of entities to move to the desired The entity or list of entities to move to the desired
archive folder. archive folder.
@ -258,11 +275,10 @@ class DialogMethods(UserMethods):
You can only use this parameter if the other two You can only use this parameter if the other two
are not set. are not set.
Returns: Returns
The :tl:`Updates` object that the request produces. The :tl:`Updates` object that the request produces.
Example: Example
.. code-block:: python .. code-block:: python
# Archiving the first 5 dialogs # Archiving the first 5 dialogs
@ -316,7 +332,7 @@ class DialogMethods(UserMethods):
with them, but rather a way to easily send messages and await for with them, but rather a way to easily send messages and await for
responses or other reactions. Refer to its documentation for more. responses or other reactions. Refer to its documentation for more.
Args: Arguments
entity (`entity`): entity (`entity`):
The entity with which a new conversation should be opened. The entity with which a new conversation should be opened.
@ -381,11 +397,10 @@ class DialogMethods(UserMethods):
With the setting disabled, both ``msg2`` and ``msg3`` will With the setting disabled, both ``msg2`` and ``msg3`` will
be ``'Hi!'`` since one is a response and also a reply. be ``'Hi!'`` since one is a response and also a reply.
Returns: Returns
A `Conversation <telethon.tl.custom.conversation.Conversation>`. A `Conversation <telethon.tl.custom.conversation.Conversation>`.
Example: Example
.. code-block:: python .. code-block:: python
# <you> denotes outgoing messages you sent # <you> denotes outgoing messages you sent

View File

@ -30,7 +30,7 @@ class DownloadMethods(UserMethods):
""" """
Downloads the profile photo from the given user, chat or channel. Downloads the profile photo from the given user, chat or channel.
Args: Arguments
entity (`entity`): entity (`entity`):
From who the photo will be downloaded. From who the photo will be downloaded.
@ -53,14 +53,14 @@ class DownloadMethods(UserMethods):
download_big (`bool`, optional): download_big (`bool`, optional):
Whether to use the big version of the available photos. Whether to use the big version of the available photos.
Returns: Returns
``None`` if no photo was provided, or if it was Empty. On success ``None`` if no photo was provided, or if it was Empty. On success
the file path is returned since it may differ from the one given. the file path is returned since it may differ from the one given.
Example: Example
.. code-block:: python .. code-block:: python
# Download your own profile photo
path = client.download_profile_photo('me') path = client.download_profile_photo('me')
print(path) print(path)
""" """
@ -147,42 +147,44 @@ class DownloadMethods(UserMethods):
``cryptg`` (through ``pip install cryptg``) so that decrypting the ``cryptg`` (through ``pip install cryptg``) so that decrypting the
received data is done in C instead of Python (much faster). received data is done in C instead of Python (much faster).
message (`Message <telethon.tl.custom.message.Message>` | :tl:`Media`): See also `Message.download_media() <telethon.tl.custom.message.Message.download_media>`.
The media or message containing the media that will be downloaded.
file (`str` | `file`, optional): Arguments
The output file path, directory, or stream-like object. message (`Message <telethon.tl.custom.message.Message>` | :tl:`Media`):
If the path exists and is a file, it will be overwritten. The media or message containing the media that will be downloaded.
If file is the type `bytes`, it will be downloaded in-memory
as a bytestring (e.g. ``file=bytes``).
progress_callback (`callable`, optional): file (`str` | `file`, optional):
A callback function accepting two parameters: The output file path, directory, or stream-like object.
``(received bytes, total)``. If the path exists and is a file, it will be overwritten.
If file is the type `bytes`, it will be downloaded in-memory
as a bytestring (e.g. ``file=bytes``).
thumb (`int` | :tl:`PhotoSize`, optional): progress_callback (`callable`, optional):
Which thumbnail size from the document or photo to download, A callback function accepting two parameters:
instead of downloading the document or photo itself. ``(received bytes, total)``.
If it's specified but the file does not have a thumbnail, thumb (`int` | :tl:`PhotoSize`, optional):
this method will return ``None``. Which thumbnail size from the document or photo to download,
instead of downloading the document or photo itself.
The parameter should be an integer index between ``0`` and If it's specified but the file does not have a thumbnail,
``len(sizes)``. ``0`` will download the smallest thumbnail, this method will return ``None``.
and ``len(sizes) - 1`` will download the largest thumbnail.
You can also use negative indices.
You can also pass the :tl:`PhotoSize` instance to use. The parameter should be an integer index between ``0`` and
``len(sizes)``. ``0`` will download the smallest thumbnail,
and ``len(sizes) - 1`` will download the largest thumbnail.
You can also use negative indices.
In short, use ``thumb=0`` if you want the smallest thumbnail You can also pass the :tl:`PhotoSize` instance to use.
and ``thumb=-1`` if you want the largest thumbnail.
Returns: In short, use ``thumb=0`` if you want the smallest thumbnail
and ``thumb=-1`` if you want the largest thumbnail.
Returns
``None`` if no media was provided, or if it was Empty. On success ``None`` if no media was provided, or if it was Empty. On success
the file path is returned since it may differ from the one given. the file path is returned since it may differ from the one given.
Example: Example
.. code-block:: python .. code-block:: python
path = client.download_media(message) path = client.download_media(message)
@ -190,7 +192,6 @@ class DownloadMethods(UserMethods):
# or # or
path = message.download_media() path = message.download_media()
message.download_media(filename) message.download_media(filename)
""" """
# TODO This won't work for messageService # TODO This won't work for messageService
if isinstance(message, types.Message): if isinstance(message, types.Message):
@ -236,7 +237,7 @@ class DownloadMethods(UserMethods):
""" """
Low-level method to download files from their input location. Low-level method to download files from their input location.
Args: Arguments
input_location (:tl:`InputFileLocation`): input_location (:tl:`InputFileLocation`):
The file location from which the file will be downloaded. The file location from which the file will be downloaded.
See `telethon.utils.get_input_location` source for a complete See `telethon.utils.get_input_location` source for a complete
@ -265,6 +266,13 @@ class DownloadMethods(UserMethods):
dc_id (`int`, optional): dc_id (`int`, optional):
The data center the library should connect to in order The data center the library should connect to in order
to download the file. You shouldn't worry about this. to download the file. You shouldn't worry about this.
Example
.. code-block:: python
# Download a file and print its header
data = client.download_file(input_file, bytes)
print(data[:16])
""" """
if not part_size_kb: if not part_size_kb:
if not file_size: if not file_size:

View File

@ -38,6 +38,15 @@ class MessageParseMethods(UserMethods):
that ``assert text == unparse(*parse(text))``. that ``assert text == unparse(*parse(text))``.
See :tl:`MessageEntity` for allowed message entities. See :tl:`MessageEntity` for allowed message entities.
Example
.. code-block:: python
# Disabling default formatting
client.parse_mode = None
# Enabling HTML as the default format
client.parse_mode = 'html'
""" """
return self._parse_mode return self._parse_mode

View File

@ -319,7 +319,13 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
If either `search`, `filter` or `from_user` are provided, If either `search`, `filter` or `from_user` are provided,
:tl:`messages.Search` will be used instead of :tl:`messages.getHistory`. :tl:`messages.Search` will be used instead of :tl:`messages.getHistory`.
Args: .. note::
Telegram's flood wait limit for :tl:`GetHistoryRequest` seems to
be around 30 seconds per 10 requests, therefore a sleep of 1
second is the default for this limit (or above).
Arguments
entity (`entity`): entity (`entity`):
The entity from whom to retrieve the message history. The entity from whom to retrieve the message history.
@ -406,16 +412,10 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
You cannot use this if both `entity` and `ids` are ``None``. You cannot use this if both `entity` and `ids` are ``None``.
Yields: Yields
Instances of `telethon.tl.custom.message.Message`. Instances of `telethon.tl.custom.message.Message`.
Notes: Example
Telegram's flood wait limit for :tl:`GetHistoryRequest` seems to
be around 30 seconds per 10 requests, therefore a sleep of 1
second is the default for this limit (or above).
Example:
.. code-block:: python .. code-block:: python
# From most-recent to oldest # From most-recent to oldest
@ -439,7 +439,6 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
for message in client.iter_messages(chat, filter=InputMessagesFilterPhotos): for message in client.iter_messages(chat, filter=InputMessagesFilterPhotos):
print(message.photo) print(message.photo)
""" """
if ids is not None: if ids is not None:
return _IDsIter(self, limit, entity=entity, ids=ids) return _IDsIter(self, limit, entity=entity, ids=ids)
@ -476,8 +475,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
a single `Message <telethon.tl.custom.message.Message>` will be a single `Message <telethon.tl.custom.message.Message>` will be
returned for convenience instead of a list. returned for convenience instead of a list.
Example: Example
.. code-block:: python .. code-block:: python
# Get 0 photos and print the total to show how many photos there are # Get 0 photos and print the total to show how many photos there are
@ -540,8 +538,10 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
is also done through this method. Simply send ``'/start data'`` to is also done through this method. Simply send ``'/start data'`` to
the bot. the bot.
Args: See also `Message.respond() <telethon.tl.custom.message.Message.respond>`
and `Message.reply() <telethon.tl.custom.message.Message.reply>`.
Arguments
entity (`entity`): entity (`entity`):
To who will it be sent. To who will it be sent.
@ -596,20 +596,14 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
channel or not. Defaults to ``False``, which means it will channel or not. Defaults to ``False``, which means it will
notify them. Set it to ``True`` to alter this behaviour. notify them. Set it to ``True`` to alter this behaviour.
Returns: Returns
The sent `custom.Message <telethon.tl.custom.message.Message>`. The sent `custom.Message <telethon.tl.custom.message.Message>`.
Example: Example
.. code-block:: python .. code-block:: python
client.send_message('lonami', 'Thanks for the Telethon library!') # Markdown is the default
client.send_message('lonami', 'Thanks for the **Telethon** library!')
# Replies and responses
message = client.send_message('me', 'Trying out **markdown**')
message.reply('Trying replies')
message.respond('Trying responses')
# Default to another parse mode # Default to another parse mode
client.parse_mode = 'html' client.parse_mode = 'html'
@ -748,7 +742,9 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
(the "forwarded from" text), you should use `send_message` with (the "forwarded from" text), you should use `send_message` with
the original message instead. This will send a copy of it. the original message instead. This will send a copy of it.
Args: See also `Message.forward_to() <telethon.tl.custom.message.Message.forward_to>`.
Arguments
entity (`entity`): entity (`entity`):
To which entity the message(s) will be forwarded. To which entity the message(s) will be forwarded.
@ -777,7 +773,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
``True`` will group always (even converting separate ``True`` will group always (even converting separate
images into albums), and ``False`` will never group. images into albums), and ``False`` will never group.
Returns: Returns
The list of forwarded `telethon.tl.custom.message.Message`, The list of forwarded `telethon.tl.custom.message.Message`,
or a single one if a list wasn't provided as input. or a single one if a list wasn't provided as input.
@ -785,8 +781,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
will fail with ``MessageIdInvalidError``. If only some are will fail with ``MessageIdInvalidError``. If only some are
invalid, the list will have ``None`` instead of those messages. invalid, the list will have ``None`` instead of those messages.
Example: Example
.. code-block:: python .. code-block:: python
# a single one # a single one
@ -884,7 +879,9 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
""" """
Edits the given message to change its text or media. Edits the given message to change its text or media.
Args: See also `Message.edit() <telethon.tl.custom.message.Message.edit>`.
Arguments
entity (`entity` | `Message <telethon.tl.custom.message.Message>`): entity (`entity` | `Message <telethon.tl.custom.message.Message>`):
From which chat to edit the message. This can also be From which chat to edit the message. This can also be
the message to be edited, and the entity will be inferred the message to be edited, and the entity will be inferred
@ -925,38 +922,28 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
you have signed in as a bot. You can also pass your own you have signed in as a bot. You can also pass your own
:tl:`ReplyMarkup` here. :tl:`ReplyMarkup` here.
Examples: Returns
The edited `telethon.tl.custom.message.Message`, unless
`entity` was a :tl:`InputBotInlineMessageID` in which
case this method returns a boolean.
>>> client = ... Raises
>>> message = client.send_message('username', 'hello')
>>>
>>> client.edit_message('username', message, 'hello!')
>>> # or
>>> client.edit_message('username', message.id, 'Hello')
>>> # or
>>> client.edit_message(message, 'Hello!')
Raises:
``MessageAuthorRequiredError`` if you're not the author of the ``MessageAuthorRequiredError`` if you're not the author of the
message but tried editing it anyway. message but tried editing it anyway.
``MessageNotModifiedError`` if the contents of the message were ``MessageNotModifiedError`` if the contents of the message were
not modified at all. not modified at all.
Returns: Example
The edited `telethon.tl.custom.message.Message`, unless
`entity` was a :tl:`InputBotInlineMessageID` in which
case this method returns a boolean.
Example:
.. code-block:: python .. code-block:: python
client.edit_message(message, 'New text') message = client.send_message(chat, 'hello')
client.edit_message(chat, message, 'hello!')
# or # or
message.edit('New text') client.edit_message(chat, message.id, 'hello!!')
# or # or
client.edit_message(chat, message_id, 'New text') client.edit_message(message, 'hello!!!')
""" """
if isinstance(entity, types.InputBotInlineMessageID): if isinstance(entity, types.InputBotInlineMessageID):
text = message text = message
@ -1002,7 +989,16 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
""" """
Deletes the given messages, optionally "for everyone". Deletes the given messages, optionally "for everyone".
Args: See also `Message.delete() <telethon.tl.custom.message.Message.delete>`.
.. warning::
This method does **not** validate that the message IDs belong
to the chat that you passed! It's possible for the method to
delete messages from different private chats and small group
chats at once, so make sure to pass the right IDs.
Arguments
entity (`entity`): entity (`entity`):
From who the message will be deleted. This can actually From who the message will be deleted. This can actually
be ``None`` for normal chats, but **must** be present be ``None`` for normal chats, but **must** be present
@ -1025,17 +1021,14 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
Disabling this has no effect on channels or megagroups, Disabling this has no effect on channels or megagroups,
since it will unconditionally delete the message for everyone. since it will unconditionally delete the message for everyone.
Returns: Returns
A list of :tl:`AffectedMessages`, each item being the result A list of :tl:`AffectedMessages`, each item being the result
for the delete calls of the messages in chunks of 100 each. for the delete calls of the messages in chunks of 100 each.
Example: Example
.. code-block:: python .. code-block:: python
client.delete_messages(chat, messages) client.delete_messages(chat, messages)
# or
message.delete()
""" """
if not utils.is_list_like(message_ids): if not utils.is_list_like(message_ids):
message_ids = (message_ids,) message_ids = (message_ids,)
@ -1074,7 +1067,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
If neither message nor maximum ID are provided, all messages will be If neither message nor maximum ID are provided, all messages will be
marked as read by assuming that ``max_id = 0``. marked as read by assuming that ``max_id = 0``.
Args: Arguments
entity (`entity`): entity (`entity`):
The chat where these messages are located. The chat where these messages are located.
@ -1092,8 +1085,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
If no message is provided, this will be the only action If no message is provided, this will be the only action
taken. taken.
Example: Example
.. code-block:: python .. code-block:: python
client.send_read_acknowledge(last_message) client.send_read_acknowledge(last_message)

View File

@ -34,7 +34,7 @@ class TelegramBaseClient(abc.ABC):
basic stuff like connecting, switching data center, etc, and basic stuff like connecting, switching data center, etc, and
leaves the `__call__` unimplemented. leaves the `__call__` unimplemented.
Args: Arguments
session (`str` | `telethon.sessions.abstract.Session`, `None`): session (`str` | `telethon.sessions.abstract.Session`, `None`):
The file name of the session file to be used if a string is The file name of the session file to be used if a string is
given (it may be a full path), or the Session instance to be given (it may be a full path), or the Session instance to be
@ -346,6 +346,18 @@ class TelegramBaseClient(abc.ABC):
def loop(self: 'TelegramClient') -> asyncio.AbstractEventLoop: def loop(self: 'TelegramClient') -> asyncio.AbstractEventLoop:
""" """
Property with the ``asyncio`` event loop used by this client. Property with the ``asyncio`` event loop used by this client.
Example
.. code-block:: python
# Download media in the background
task = client.loop_create_task(message.download_media())
# Do some work
...
# Join the task (wait for it to complete)
await task
""" """
return self._loop return self._loop
@ -353,6 +365,15 @@ class TelegramBaseClient(abc.ABC):
def disconnected(self: 'TelegramClient') -> asyncio.Future: def disconnected(self: 'TelegramClient') -> asyncio.Future:
""" """
Property with a ``Future`` that resolves upon disconnection. Property with a ``Future`` that resolves upon disconnection.
Example
.. code-block:: python
# Wait for a disconnection to occur
try:
await client.disconnected
except OSError:
print('Error on disconnect')
""" """
return self._sender.disconnected return self._sender.disconnected
@ -363,6 +384,14 @@ class TelegramBaseClient(abc.ABC):
async def connect(self: 'TelegramClient') -> None: async def connect(self: 'TelegramClient') -> None:
""" """
Connects to Telegram. Connects to Telegram.
Example
.. code-block:: python
try:
client.connect()
except OSError:
print('Failed to connect')
""" """
await self._sender.connect(self._connection( await self._sender.connect(self._connection(
self.session.server_address, self.session.server_address,
@ -385,6 +414,12 @@ class TelegramBaseClient(abc.ABC):
Returns ``True`` if the user has connected. Returns ``True`` if the user has connected.
This method is **not** asynchronous (don't use ``await`` on it). This method is **not** asynchronous (don't use ``await`` on it).
Example
.. code-block:: python
while client.is_connected():
await asyncio.sleep(1)
""" """
sender = getattr(self, '_sender', None) sender = getattr(self, '_sender', None)
return sender and sender.is_connected() return sender and sender.is_connected()
@ -397,8 +432,7 @@ class TelegramBaseClient(abc.ABC):
coroutine that you should await on your own code; otherwise coroutine that you should await on your own code; otherwise
the loop is ran until said coroutine completes. the loop is ran until said coroutine completes.
Example: Example
.. code-block:: python .. code-block:: python
# You don't need to use this if you used "with client" # You don't need to use this if you used "with client"

View File

@ -39,6 +39,15 @@ class UpdateMethods(UserMethods):
If the loop is already running, this method returns a coroutine If the loop is already running, this method returns a coroutine
that you should await on your own code. that you should await on your own code.
Example
.. code-block:: python
# Blocks the current task here until a disconnection occurs.
#
# You will still receive updates, since this prevents the
# script from exiting.
client.run_until_disconnected()
""" """
if self.loop.is_running(): if self.loop.is_running():
return self._run_until_disconnected() return self._run_until_disconnected()
@ -54,19 +63,22 @@ class UpdateMethods(UserMethods):
""" """
Decorator used to `add_event_handler` more conveniently. Decorator used to `add_event_handler` more conveniently.
>>> from telethon import TelegramClient, events
>>> client = TelegramClient(...)
>>>
>>> @client.on(events.NewMessage)
... async def handler(event):
... ...
...
>>>
Args: Arguments
event (`_EventBuilder` | `type`): event (`_EventBuilder` | `type`):
The event builder class or instance to be used, The event builder class or instance to be used,
for instance ``events.NewMessage``. for instance ``events.NewMessage``.
Example
.. code-block:: python
from telethon import TelegramClient, events
client = TelegramClient(...)
# Here we use client.on
@client.on(events.NewMessage)
async def handler(event):
...
""" """
def decorator(f): def decorator(f):
self.add_event_handler(f, event) self.add_event_handler(f, event)
@ -83,7 +95,7 @@ class UpdateMethods(UserMethods):
The callback will be called when the specified event occurs. The callback will be called when the specified event occurs.
Args: Arguments
callback (`callable`): callback (`callable`):
The callable function accepting one parameter to be used. The callable function accepting one parameter to be used.
@ -98,6 +110,17 @@ class UpdateMethods(UserMethods):
If left unspecified, `telethon.events.raw.Raw` (the If left unspecified, `telethon.events.raw.Raw` (the
:tl:`Update` objects with no further processing) will :tl:`Update` objects with no further processing) will
be passed instead. be passed instead.
Example
.. code-block:: python
from telethon import TelegramClient, events
client = TelegramClient(...)
async def handler(event):
...
client.add_event_handler(handler, events.NewMessage)
""" """
builders = events._get_handlers(callback) builders = events._get_handlers(callback)
if builders is not None: if builders is not None:
@ -121,6 +144,21 @@ class UpdateMethods(UserMethods):
If no event is given, all events for this callback are removed. If no event is given, all events for this callback are removed.
Returns how many callbacks were removed. Returns how many callbacks were removed.
Example
.. code-block:: python
@client.on(events.Raw)
@client.on(events.NewMessage)
async def handler(event):
...
# Removes only the "Raw" handling
# "handler" will still receive "events.NewMessage"
client.remove_event_handler(handler, events.Raw)
# "handler" will stop receiving anything
client.remove_event_handler(handler)
""" """
found = 0 found = 0
if event and not isinstance(event, type): if event and not isinstance(event, type):
@ -141,7 +179,19 @@ class UpdateMethods(UserMethods):
""" """
Lists all registered event handlers. Lists all registered event handlers.
Returns a list of pairs consisting of ``(callback, event)``. Returns
A list of pairs consisting of ``(callback, event)``.
Example
.. code-block:: python
@client.on(events.NewMessage(pattern='hello'))
async def on_greeting(event):
'''Greets someone'''
await event.reply('Hi')
for callback, event in client.list_event_handlers():
print(id(callback), type(event))
""" """
return [(callback, event) for event, callback in self._event_builders] return [(callback, event) for event, callback in self._event_builders]
@ -152,6 +202,11 @@ class UpdateMethods(UserMethods):
so that the updates it loads can by processed by your script. so that the updates it loads can by processed by your script.
This can also be used to forcibly fetch new updates if there are any. This can also be used to forcibly fetch new updates if there are any.
Example
.. code-block:: python
client.catch_up()
""" """
pts, date = self._state_cache[None] pts, date = self._state_cache[None]
if not pts: if not pts:

View File

@ -109,7 +109,17 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
""" """
Sends message with the given file to the specified entity. Sends message with the given file to the specified entity.
Args: .. note::
If the ``hachoir3`` package (``hachoir`` module) is installed,
it will be used to determine metadata from audio and video files.
If the ``pillow`` package is installed and you are sending a photo,
it will be resized to fit within the maximum dimensions allowed
by Telegram to avoid ``errors.PhotoInvalidDimensionsError``. This
cannot be done if you are sending :tl:`InputFile`, however.
Arguments
entity (`entity`): entity (`entity`):
Who will receive the file. Who will receive the file.
@ -220,21 +230,11 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
these to MP4 before sending if you want them to be streamable. these to MP4 before sending if you want them to be streamable.
Unsupported formats will result in ``VideoContentTypeError``. Unsupported formats will result in ``VideoContentTypeError``.
Notes: Returns
If the ``hachoir3`` package (``hachoir`` module) is installed,
it will be used to determine metadata from audio and video files.
If the `pillow` package is installed and you are sending a photo,
it will be resized to fit within the maximum dimensions allowed
by Telegram to avoid ``errors.PhotoInvalidDimensionsError``. This
cannot be done if you are sending :tl:`InputFile`, however.
Returns:
The `telethon.tl.custom.message.Message` (or messages) containing The `telethon.tl.custom.message.Message` (or messages) containing
the sent file, or messages if a list of them was passed. the sent file, or messages if a list of them was passed.
Example: Example
.. code-block:: python .. code-block:: python
# Normal files like photos # Normal files like photos
@ -422,7 +422,7 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
remotely in the Telegram servers, which can be later used on. This remotely in the Telegram servers, which can be later used on. This
will **not** upload the file to your own chat or any chat at all. will **not** upload the file to your own chat or any chat at all.
Args: Arguments
file (`str` | `bytes` | `file`): file (`str` | `bytes` | `file`):
The path of the file, byte array, or stream that will be sent. The path of the file, byte array, or stream that will be sent.
Note that if a byte array or a stream is given, a filename Note that if a byte array or a stream is given, a filename
@ -449,13 +449,12 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
A callback function accepting two parameters: A callback function accepting two parameters:
``(sent bytes, total)``. ``(sent bytes, total)``.
Returns: Returns
:tl:`InputFileBig` if the file size is larger than 10MB, :tl:`InputFileBig` if the file size is larger than 10MB,
`telethon.tl.custom.inputsizedfile.InputSizedFile` `telethon.tl.custom.inputsizedfile.InputSizedFile`
(subclass of :tl:`InputFile`) otherwise. (subclass of :tl:`InputFile`) otherwise.
Example: Example
.. code-block:: python .. code-block:: python
# Photos as photo and document # Photos as photo and document

View File

@ -108,14 +108,19 @@ class UserMethods(TelegramBaseClient):
If the user has not logged in yet, this method returns ``None``. If the user has not logged in yet, this method returns ``None``.
Args: Arguments
input_peer (`bool`, optional): input_peer (`bool`, optional):
Whether to return the :tl:`InputPeerUser` version or the normal Whether to return the :tl:`InputPeerUser` version or the normal
:tl:`User`. This can be useful if you just need to know the ID :tl:`User`. This can be useful if you just need to know the ID
of yourself. of yourself.
Returns: Returns
Your own :tl:`User`. Your own :tl:`User`.
Example
.. code-block:: python
print(client.get_me().username)
""" """
if input_peer and self._self_input_peer: if input_peer and self._self_input_peer:
return self._self_input_peer return self._self_input_peer
@ -137,6 +142,14 @@ class UserMethods(TelegramBaseClient):
async def is_bot(self: 'TelegramClient') -> bool: async def is_bot(self: 'TelegramClient') -> bool:
""" """
Return ``True`` if the signed-in user is a bot, ``False`` otherwise. Return ``True`` if the signed-in user is a bot, ``False`` otherwise.
Example
.. code-block:: python
if client.is_bot():
print('Beep')
else:
print('Hello')
""" """
if self._bot is None: if self._bot is None:
self._bot = (await self.get_me()).bot self._bot = (await self.get_me()).bot
@ -146,6 +159,14 @@ class UserMethods(TelegramBaseClient):
async def is_user_authorized(self: 'TelegramClient') -> bool: async def is_user_authorized(self: 'TelegramClient') -> bool:
""" """
Returns ``True`` if the user is authorized (i.e. has logged in). Returns ``True`` if the user is authorized (i.e. has logged in).
Example
.. code-block:: python
if not client.is_user_authorized():
client.send_code_request(phone)
code = input('enter code: ')
client.sign_in(phone, code)
""" """
if self._authorized is None: if self._authorized is None:
try: try:
@ -165,35 +186,35 @@ class UserMethods(TelegramBaseClient):
or :tl:`Channel`. You can also pass a list or iterable of entities, or :tl:`Channel`. You can also pass a list or iterable of entities,
and they will be efficiently fetched from the network. and they will be efficiently fetched from the network.
entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`): Arguments
If a username is given, **the username will be resolved** making entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`):
an API call every time. Resolving usernames is an expensive If a username is given, **the username will be resolved** making
operation and will start hitting flood waits around 50 usernames an API call every time. Resolving usernames is an expensive
in a short period of time. operation and will start hitting flood waits around 50 usernames
in a short period of time.
If you want to get the entity for a *cached* username, you should If you want to get the entity for a *cached* username, you should
first `get_input_entity(username) <get_input_entity>` which will first `get_input_entity(username) <get_input_entity>` which will
use the cache), and then use `get_entity` with the result of the use the cache), and then use `get_entity` with the result of the
previous call. previous call.
Similar limits apply to invite links, and you should use their Similar limits apply to invite links, and you should use their
ID instead. ID instead.
Using phone numbers (from people in your contact list), exact Using phone numbers (from people in your contact list), exact
names, integer IDs or :tl:`Peer` rely on a `get_input_entity` names, integer IDs or :tl:`Peer` rely on a `get_input_entity`
first, which in turn needs the entity to be in cache, unless first, which in turn needs the entity to be in cache, unless
a :tl:`InputPeer` was passed. a :tl:`InputPeer` was passed.
Unsupported types will raise ``TypeError``. Unsupported types will raise ``TypeError``.
If the entity can't be found, ``ValueError`` will be raised. If the entity can't be found, ``ValueError`` will be raised.
Returns: Returns
:tl:`User`, :tl:`Chat` or :tl:`Channel` corresponding to the :tl:`User`, :tl:`Chat` or :tl:`Channel` corresponding to the
input entity. A list will be returned if more than one was given. input entity. A list will be returned if more than one was given.
Example: Example
.. code-block:: python .. code-block:: python
from telethon import utils from telethon import utils
@ -284,57 +305,57 @@ class UserMethods(TelegramBaseClient):
first, but if you're going to use an entity often, consider making the first, but if you're going to use an entity often, consider making the
call: call:
>>> import asyncio Arguments
>>> rc = asyncio.get_event_loop().run_until_complete entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`):
>>> If a username or invite link is given, **the library will
>>> from telethon import TelegramClient use the cache**. This means that it's possible to be using
>>> client = TelegramClient(...) a username that *changed* or an old invite link (this only
>>> # If you're going to use "username" often in your code happens if an invite link for a small group chat is used
>>> # (make a lot of calls), consider getting its input entity after it was upgraded to a mega-group).
>>> # once, and then using the "user" everywhere instead.
>>> user = rc(client.get_input_entity('username'))
>>> # The same applies to IDs, chats or channels.
>>> chat = rc(client.get_input_entity(-123456789))
entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`): If the username or ID from the invite link is not found in
If a username or invite link is given, **the library will the cache, it will be fetched. The same rules apply to phone
use the cache**. This means that it's possible to be using numbers (``'+34 123456789'``) from people in your contact list.
a username that *changed* or an old invite link (this only
happens if an invite link for a small group chat is used
after it was upgraded to a mega-group).
If the username or ID from the invite link is not found in If an exact name is given, it must be in the cache too. This
the cache, it will be fetched. The same rules apply to phone is not reliable as different people can share the same name
numbers (``'+34 123456789'``) from people in your contact list. and which entity is returned is arbitrary, and should be used
only for quick tests.
If an exact name is given, it must be in the cache too. This If a positive integer ID is given, the entity will be searched
is not reliable as different people can share the same name in cached users, chats or channels, without making any call.
and which entity is returned is arbitrary, and should be used
only for quick tests.
If a positive integer ID is given, the entity will be searched If a negative integer ID is given, the entity will be searched
in cached users, chats or channels, without making any call. exactly as either a chat (prefixed with ``-``) or as a channel
(prefixed with ``-100``).
If a negative integer ID is given, the entity will be searched If a :tl:`Peer` is given, it will be searched exactly in the
exactly as either a chat (prefixed with ``-``) or as a channel cache as either a user, chat or channel.
(prefixed with ``-100``).
If a :tl:`Peer` is given, it will be searched exactly in the If the given object can be turned into an input entity directly,
cache as either a user, chat or channel. said operation will be done.
If the given object can be turned into an input entity directly, Unsupported types will raise ``TypeError``.
said operation will be done.
Unsupported types will raise ``TypeError``. If the entity can't be found, ``ValueError`` will be raised.
If the entity can't be found, ``ValueError`` will be raised. Returns
Returns:
:tl:`InputPeerUser`, :tl:`InputPeerChat` or :tl:`InputPeerChannel` :tl:`InputPeerUser`, :tl:`InputPeerChat` or :tl:`InputPeerChannel`
or :tl:`InputPeerSelf` if the parameter is ``'me'`` or ``'self'``. or :tl:`InputPeerSelf` if the parameter is ``'me'`` or ``'self'``.
If you need to get the ID of yourself, you should use If you need to get the ID of yourself, you should use
`get_me` with ``input_peer=True``) instead. `get_me` with ``input_peer=True``) instead.
Example
.. code-block:: python
# If you're going to use "username" often in your code
# (make a lot of calls), consider getting its input entity
# once, and then using the "user" everywhere instead.
user = client.get_input_entity('username')
# The same applies to IDs, chats or channels.
chat = client.get_input_entity(-123456789)
""" """
# Short-circuit if the input parameter directly maps to an InputPeer # Short-circuit if the input parameter directly maps to an InputPeer
try: try:
@ -411,6 +432,11 @@ class UserMethods(TelegramBaseClient):
If ``add_mark is False``, then a positive ID will be returned If ``add_mark is False``, then a positive ID will be returned
instead. By default, bot-API style IDs (signed) are returned. instead. By default, bot-API style IDs (signed) are returned.
Example
.. code-block:: python
print(client.get_peer_id('me'))
""" """
if isinstance(peer, int): if isinstance(peer, int):
return utils.get_peer_id(peer, add_mark=add_mark) return utils.get_peer_id(peer, add_mark=add_mark)

View File

@ -185,6 +185,7 @@ PHOTO_INVALID_DIMENSIONS,400,The photo dimensions are invalid (hint: `pip instal
PHOTO_SAVE_FILE_INVALID,400,The photo you tried to send cannot be saved by Telegram. A reason may be that it exceeds 10MB. Try resizing it locally PHOTO_SAVE_FILE_INVALID,400,The photo you tried to send cannot be saved by Telegram. A reason may be that it exceeds 10MB. Try resizing it locally
PHOTO_THUMB_URL_EMPTY,400,The URL used as a thumbnail appears to be empty or has caused another HTTP error PHOTO_THUMB_URL_EMPTY,400,The URL used as a thumbnail appears to be empty or has caused another HTTP error
PIN_RESTRICTED,400,You can't pin messages in private chats with other people PIN_RESTRICTED,400,You can't pin messages in private chats with other people
POLL_OPTION_DUPLICATE,400,A duplicate option was sent in the same poll
POLL_UNSUPPORTED,400,This layer does not support polls in the issued method POLL_UNSUPPORTED,400,This layer does not support polls in the issued method
PRIVACY_KEY_INVALID,400,The privacy key is invalid PRIVACY_KEY_INVALID,400,The privacy key is invalid
PTS_CHANGE_EMPTY,500,No PTS change PTS_CHANGE_EMPTY,500,No PTS change

1 name codes description
185 PHOTO_SAVE_FILE_INVALID 400 The photo you tried to send cannot be saved by Telegram. A reason may be that it exceeds 10MB. Try resizing it locally
186 PHOTO_THUMB_URL_EMPTY 400 The URL used as a thumbnail appears to be empty or has caused another HTTP error
187 PIN_RESTRICTED 400 You can't pin messages in private chats with other people
188 POLL_OPTION_DUPLICATE 400 A duplicate option was sent in the same poll
189 POLL_UNSUPPORTED 400 This layer does not support polls in the issued method
190 PRIVACY_KEY_INVALID 400 The privacy key is invalid
191 PTS_CHANGE_EMPTY 500 No PTS change

View File

@ -234,7 +234,7 @@ messages.sendEncrypted,user,CHAT_ID_INVALID DATA_INVALID ENCRYPTION_DECLINED MSG
messages.sendEncryptedFile,user,MSG_WAIT_FAILED messages.sendEncryptedFile,user,MSG_WAIT_FAILED
messages.sendEncryptedService,user,DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED USER_IS_BLOCKED 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 WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY messages.sendInlineBotResult,user,CHAT_SEND_INLINE_FORBIDDEN CHAT_WRITE_FORBIDDEN INLINE_RESULT_EXPIRED PEER_ID_INVALID QUERY_ID_EMPTY WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
messages.sendMedia,both,BOT_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID RANDOM_ID_DUPLICATE 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_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID POLL_OPTION_DUPLICATE RANDOM_ID_DUPLICATE 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 PEER_ID_INVALID RANDOM_ID_DUPLICATE REPLY_MARKUP_INVALID REPLY_MARKUP_TOO_LONG Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER 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 PEER_ID_INVALID RANDOM_ID_DUPLICATE REPLY_MARKUP_INVALID REPLY_MARKUP_TOO_LONG Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER
messages.sendMultiMedia,both, messages.sendMultiMedia,both,
messages.sendVote,user, messages.sendVote,user,

1 method usability errors
234 messages.sendEncryptedFile user MSG_WAIT_FAILED
235 messages.sendEncryptedService user DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED USER_IS_BLOCKED
236 messages.sendInlineBotResult user CHAT_SEND_INLINE_FORBIDDEN CHAT_WRITE_FORBIDDEN INLINE_RESULT_EXPIRED PEER_ID_INVALID QUERY_ID_EMPTY WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
237 messages.sendMedia both BOT_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID RANDOM_ID_DUPLICATE STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY BOT_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID POLL_OPTION_DUPLICATE RANDOM_ID_DUPLICATE STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
238 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 PEER_ID_INVALID RANDOM_ID_DUPLICATE REPLY_MARKUP_INVALID REPLY_MARKUP_TOO_LONG Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER
239 messages.sendMultiMedia both
240 messages.sendVote user