Remove duplicated docstrings

This commit is contained in:
Lonami Exo 2021-09-11 15:28:24 +02:00
parent f86339ab17
commit 66ef553adc
4 changed files with 0 additions and 583 deletions

View File

@ -195,43 +195,6 @@ async def download_profile_photo(
file: 'hints.FileLike' = None, file: 'hints.FileLike' = None,
*, *,
download_big: bool = True) -> typing.Optional[str]: download_big: bool = True) -> typing.Optional[str]:
"""
Downloads the profile photo from the given user, chat or channel.
Arguments
entity (`entity`):
From who the photo will be downloaded.
.. note::
This method expects the full entity (which has the data
to download the photo), not an input variant.
It's possible that sometimes you can't fetch the entity
from its input (since you can get errors like
``ChannelPrivateError``) but you already have it through
another call, like getting a forwarded message from it.
file (`str` | `file`, optional):
The output file path, directory, or stream-like object.
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``).
download_big (`bool`, optional):
Whether to use the big version of the available photos.
Returns
`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.
Example
.. code-block:: python
# Download your own profile photo
path = await client.download_profile_photo('me')
print(path)
"""
# hex(crc32(x.encode('ascii'))) for x in # hex(crc32(x.encode('ascii'))) for x in
# ('User', 'Chat', 'UserFull', 'ChatFull') # ('User', 'Chat', 'UserFull', 'ChatFull')
ENTITIES = (0x2da17977, 0xc5af5d94, 0x1f4661b9, 0xd49a2697) ENTITIES = (0x2da17977, 0xc5af5d94, 0x1f4661b9, 0xd49a2697)
@ -307,73 +270,6 @@ async def download_media(
*, *,
thumb: 'typing.Union[int, types.TypePhotoSize]' = None, thumb: 'typing.Union[int, types.TypePhotoSize]' = None,
progress_callback: 'hints.ProgressCallback' = None) -> typing.Optional[typing.Union[str, bytes]]: progress_callback: 'hints.ProgressCallback' = None) -> typing.Optional[typing.Union[str, bytes]]:
"""
Downloads the given media from a message object.
Note that if the download is too slow, you should consider installing
``cryptg`` (through ``pip install cryptg``) so that decrypting the
received data is done in C instead of Python (much faster).
See also `Message.download_media() <telethon.tl.custom.message.Message.download_media>`.
Arguments
message (`Message <telethon.tl.custom.message.Message>` | :tl:`Media`):
The media or message containing the media that will be downloaded.
file (`str` | `file`, optional):
The output file path, directory, or stream-like object.
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``).
progress_callback (`callable`, optional):
A callback function accepting two parameters:
``(received bytes, total)``.
thumb (`int` | :tl:`PhotoSize`, optional):
Which thumbnail size from the document or photo to download,
instead of downloading the document or photo itself.
If it's specified but the file does not have a thumbnail,
this method will return `None`.
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, which work the same as
they do in Python's `list`.
You can also pass the :tl:`PhotoSize` instance to use.
Alternatively, the thumb size type `str` may be used.
In short, use ``thumb=0`` if you want the smallest thumbnail
and ``thumb=-1`` if you want the largest thumbnail.
.. note::
The largest thumbnail may be a video instead of a photo,
as they are available since layer 116 and are bigger than
any of the photos.
Returns
`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.
Example
.. code-block:: python
path = await client.download_media(message)
await client.download_media(message, filename)
# or
path = await message.download_media()
await message.download_media(filename)
# Printing download progress
def callback(current, total):
print('Downloaded', current, 'out of', total,
'bytes: {:.2%}'.format(current / total))
await client.download_media(message, progress_callback=callback)
"""
# Downloading large documents may be slow enough to require a new file reference # Downloading large documents may be slow enough to require a new file reference
# to be obtained mid-download. Store (input chat, message id) so that the message # to be obtained mid-download. Store (input chat, message id) so that the message
# can be re-fetched. # can be re-fetched.
@ -428,58 +324,6 @@ async def download_file(
dc_id: int = None, dc_id: int = None,
key: bytes = None, key: bytes = None,
iv: bytes = None) -> typing.Optional[bytes]: iv: bytes = None) -> typing.Optional[bytes]:
"""
Low-level method to download files from their input location.
.. note::
Generally, you should instead use `download_media`.
This method is intended to be a bit more low-level.
Arguments
input_location (:tl:`InputFileLocation`):
The file location from which the file will be downloaded.
See `telethon.utils.get_input_location` source for a complete
list of supported types.
file (`str` | `file`, optional):
The output file path, directory, or stream-like object.
If the path exists and is a file, it will be overwritten.
If the file path is `None` or `bytes`, then the result
will be saved in memory and returned as `bytes`.
part_size_kb (`int`, optional):
Chunk size when downloading files. The larger, the less
requests will be made (up to 512KB maximum).
file_size (`int`, optional):
The file size that is about to be downloaded, if known.
Only used if ``progress_callback`` is specified.
progress_callback (`callable`, optional):
A callback function accepting two parameters:
``(downloaded bytes, total)``. Note that the
``total`` is the provided ``file_size``.
dc_id (`int`, optional):
The data center the library should connect to in order
to download the file. You shouldn't worry about this.
key ('bytes', optional):
In case of an encrypted upload (secret chats) a key is supplied
iv ('bytes', optional):
In case of an encrypted upload (secret chats) an iv is supplied
Example
.. code-block:: python
# Download a file and print its header
data = await client.download_file(input_file, bytes)
print(data[:16])
"""
return await self._download_file( return await self._download_file(
input_location, input_location,
file, file,
@ -563,89 +407,6 @@ def iter_download(
file_size: int = None, file_size: int = None,
dc_id: int = None dc_id: int = None
): ):
"""
Iterates over a file download, yielding chunks of the file.
This method can be used to stream files in a more convenient
way, since it offers more control (pausing, resuming, etc.)
.. note::
Using a value for `offset` or `stride` which is not a multiple
of the minimum allowed `request_size`, or if `chunk_size` is
different from `request_size`, the library will need to do a
bit more work to fetch the data in the way you intend it to.
You normally shouldn't worry about this.
Arguments
file (`hints.FileLike`):
The file of which contents you want to iterate over.
offset (`int`, optional):
The offset in bytes into the file from where the
download should start. For example, if a file is
1024KB long and you just want the last 512KB, you
would use ``offset=512 * 1024``.
stride (`int`, optional):
The stride of each chunk (how much the offset should
advance between reading each chunk). This parameter
should only be used for more advanced use cases.
It must be bigger than or equal to the `chunk_size`.
limit (`int`, optional):
The limit for how many *chunks* will be yielded at most.
chunk_size (`int`, optional):
The maximum size of the chunks that will be yielded.
Note that the last chunk may be less than this value.
By default, it equals to `request_size`.
request_size (`int`, optional):
How many bytes will be requested to Telegram when more
data is required. By default, as many bytes as possible
are requested. If you would like to request data in
smaller sizes, adjust this parameter.
Note that values outside the valid range will be clamped,
and the final value will also be a multiple of the minimum
allowed size.
file_size (`int`, optional):
If the file size is known beforehand, you should set
this parameter to said value. Depending on the type of
the input file passed, this may be set automatically.
dc_id (`int`, optional):
The data center the library should connect to in order
to download the file. You shouldn't worry about this.
Yields
`bytes` objects representing the chunks of the file if the
right conditions are met, or `memoryview` objects instead.
Example
.. code-block:: python
# Streaming `media` to an output file
# After the iteration ends, the sender is cleaned up
with open('photo.jpg', 'wb') as fd:
async for chunk in client.iter_download(media):
fd.write(chunk)
# Fetching only the header of a file (32 bytes)
# You should manually close the iterator in this case.
#
# "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 = await stream.__anext__() # "manual" version of `async for`
await stream.close()
assert len(header) == 32
"""
return self._iter_download( return self._iter_download(
file, file,
offset=offset, offset=offset,

View File

@ -10,38 +10,6 @@ if typing.TYPE_CHECKING:
def get_parse_mode(self: 'TelegramClient'): def get_parse_mode(self: 'TelegramClient'):
"""
This property is the default parse mode used when sending messages.
Defaults to `telethon.extensions.markdown`. It will always
be either `None` or an object with ``parse`` and ``unparse``
methods.
When setting a different value it should be one of:
* Object with ``parse`` and ``unparse`` methods.
* A ``callable`` to act as the parse method.
* A `str` indicating the ``parse_mode``. For Markdown ``'md'``
or ``'markdown'`` may be used. For HTML, ``'htm'`` or ``'html'``
may be used.
The ``parse`` method should be a function accepting a single
parameter, the text to parse, and returning a tuple consisting
of ``(parsed message str, [MessageEntity instances])``.
The ``unparse`` method should be the inverse of ``parse`` such
that ``assert text == unparse(*parse(text))``.
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
def set_parse_mode(self: 'TelegramClient', mode: str): def set_parse_mode(self: 'TelegramClient', mode: str):

View File

@ -30,74 +30,14 @@ async def _run_until_disconnected(self: 'TelegramClient'):
await self.disconnect() await self.disconnect()
async def set_receive_updates(self: 'TelegramClient', receive_updates): async def set_receive_updates(self: 'TelegramClient', receive_updates):
"""
Change the value of `receive_updates`.
This is an `async` method, because in order for Telegram to start
sending updates again, a request must be made.
"""
self._no_updates = not receive_updates self._no_updates = not receive_updates
if receive_updates: if receive_updates:
await self(functions.updates.GetStateRequest()) await self(functions.updates.GetStateRequest())
async def run_until_disconnected(self: 'TelegramClient'): async def run_until_disconnected(self: 'TelegramClient'):
"""
Runs the event loop until the library is disconnected.
It also notifies Telegram that we want to receive updates
as described in https://core.telegram.org/api/updates.
Manual disconnections can be made by calling `disconnect()
<telethon.client.telegrambaseclient.TelegramBaseClient.disconnect>`
or sending a ``KeyboardInterrupt`` (e.g. by pressing ``Ctrl+C`` on
the console window running the script).
If a disconnection error occurs (i.e. the library fails to reconnect
automatically), said error will be raised through here, so you have a
chance to ``except`` it on your own code.
If the loop is already running, this method returns a coroutine
that you should await on your own code.
.. note::
If you want to handle ``KeyboardInterrupt`` in your code,
simply run the event loop in your code too in any way, such as
``loop.run_forever()`` or ``await client.disconnected`` (e.g.
``loop.run_until_complete(client.disconnected)``).
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.
await client.run_until_disconnected()
"""
return await self._run_until_disconnected() return await self._run_until_disconnected()
def on(self: 'TelegramClient', event: EventBuilder): def on(self: 'TelegramClient', event: EventBuilder):
"""
Decorator used to `add_event_handler` more conveniently.
Arguments
event (`_EventBuilder` | `type`):
The event builder class or instance to be used,
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)
return f return f
@ -108,38 +48,6 @@ def add_event_handler(
self: 'TelegramClient', self: 'TelegramClient',
callback: Callback, callback: Callback,
event: EventBuilder = None): event: EventBuilder = None):
"""
Registers a new event handler callback.
The callback will be called when the specified event occurs.
Arguments
callback (`callable`):
The callable function accepting one parameter to be used.
Note that if you have used `telethon.events.register` in
the callback, ``event`` will be ignored, and instead the
events you previously registered will be used.
event (`_EventBuilder` | `type`, optional):
The event builder class or instance to be used,
for instance ``events.NewMessage``.
If left unspecified, `telethon.events.raw.Raw` (the
:tl:`Update` objects with no further processing) will
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:
for event in builders: for event in builders:
@ -157,27 +65,6 @@ def remove_event_handler(
self: 'TelegramClient', self: 'TelegramClient',
callback: Callback, callback: Callback,
event: EventBuilder = None) -> int: event: EventBuilder = None) -> int:
"""
Inverse operation of `add_event_handler()`.
If no event is given, all events for this callback are 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):
event = type(event) event = type(event)
@ -194,38 +81,9 @@ def remove_event_handler(
def list_event_handlers(self: 'TelegramClient')\ def list_event_handlers(self: 'TelegramClient')\
-> 'typing.Sequence[typing.Tuple[Callback, EventBuilder]]': -> 'typing.Sequence[typing.Tuple[Callback, EventBuilder]]':
"""
Lists all registered event handlers.
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]
async def catch_up(self: 'TelegramClient'): async def catch_up(self: 'TelegramClient'):
"""
"Catches up" on the missed updates while the client was offline.
You should call this method after registering the event handlers
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.
Example
.. code-block:: python
await client.catch_up()
"""
pts, date = self._state_cache[None] pts, date = self._state_cache[None]
if not pts: if not pts:
return return

View File

@ -129,26 +129,6 @@ async def call(self: 'TelegramClient', sender, request, ordered=False, flood_sle
async def get_me(self: 'TelegramClient', input_peer: bool = False) \ async def get_me(self: 'TelegramClient', input_peer: bool = False) \
-> 'typing.Union[types.User, types.InputPeerUser]': -> 'typing.Union[types.User, types.InputPeerUser]':
"""
Gets "me", the current :tl:`User` who is logged in.
If the user has not logged in yet, this method returns `None`.
Arguments
input_peer (`bool`, optional):
Whether to return the :tl:`InputPeerUser` version or the normal
:tl:`User`. This can be useful if you just need to know the ID
of yourself.
Returns
Your own :tl:`User`.
Example
.. code-block:: python
me = await client.get_me()
print(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
@ -176,34 +156,12 @@ def _self_id(self: 'TelegramClient') -> typing.Optional[int]:
return self._self_input_peer.user_id if self._self_input_peer else None return self._self_input_peer.user_id if self._self_input_peer else None
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.
Example
.. code-block:: python
if await 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
return self._bot return self._bot
async def is_user_authorized(self: 'TelegramClient') -> bool: async def is_user_authorized(self: 'TelegramClient') -> bool:
"""
Returns `True` if the user is authorized (logged in).
Example
.. code-block:: python
if not await client.is_user_authorized():
await client.send_code_request(phone)
code = input('enter code: ')
await client.sign_in(phone, code)
"""
if self._authorized is None: if self._authorized is None:
try: try:
# Any request that requires authorization will work # Any request that requires authorization will work
@ -217,59 +175,6 @@ async def is_user_authorized(self: 'TelegramClient') -> bool:
async def get_entity( async def get_entity(
self: 'TelegramClient', self: 'TelegramClient',
entity: 'hints.EntitiesLike') -> 'hints.Entity': entity: 'hints.EntitiesLike') -> 'hints.Entity':
"""
Turns the given entity into a valid Telegram :tl:`User`, :tl:`Chat`
or :tl:`Channel`. You can also pass a list or iterable of entities,
and they will be efficiently fetched from the network.
Arguments
entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`):
If a username is given, **the username will be resolved** making
an API call every time. Resolving usernames is an expensive
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
first `get_input_entity(username) <get_input_entity>` which will
use the cache), and then use `get_entity` with the result of the
previous call.
Similar limits apply to invite links, and you should use their
ID instead.
Using phone numbers (from people in your contact list), exact
names, integer IDs or :tl:`Peer` rely on a `get_input_entity`
first, which in turn needs the entity to be in cache, unless
a :tl:`InputPeer` was passed.
Unsupported types will raise ``TypeError``.
If the entity can't be found, ``ValueError`` will be raised.
Returns
:tl:`User`, :tl:`Chat` or :tl:`Channel` corresponding to the
input entity. A list will be returned if more than one was given.
Example
.. code-block:: python
from telethon import utils
me = await client.get_entity('me')
print(utils.get_display_name(me))
chat = await client.get_input_entity('username')
async for message in client.iter_messages(chat):
...
# Note that you could have used the username directly, but it's
# good to use get_input_entity if you will reuse it a lot.
async for message in client.iter_messages('username'):
...
# Note that for this to work the phone number must be in your contacts
some_id = await client.get_peer_id('+34123456789')
"""
single = not utils.is_list_like(entity) single = not utils.is_list_like(entity)
if single: if single:
entity = (entity,) entity = (entity,)
@ -340,67 +245,6 @@ async def get_entity(
async def get_input_entity( async def get_input_entity(
self: 'TelegramClient', self: 'TelegramClient',
peer: 'hints.EntityLike') -> 'types.TypeInputPeer': peer: 'hints.EntityLike') -> 'types.TypeInputPeer':
"""
Turns the given entity into its input entity version.
Most requests use this kind of :tl:`InputPeer`, so this is the most
suitable call to make for those cases. **Generally you should let the
library do its job** and don't worry about getting the input entity
first, but if you're going to use an entity often, consider making the
call:
Arguments
entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`):
If a username or invite link is given, **the library will
use the cache**. This means that it's possible to be using
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
the cache, it will be fetched. The same rules apply to phone
numbers (``'+34 123456789'``) from people in your contact list.
If an exact name is given, it must be in the cache too. This
is not reliable as different people can share the same name
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
in cached users, chats or channels, without making any call.
If a negative integer ID is given, the entity will be searched
exactly as either a chat (prefixed with ``-``) or as a channel
(prefixed with ``-100``).
If a :tl:`Peer` is given, it will be searched exactly in the
cache as either a user, chat or channel.
If the given object can be turned into an input entity directly,
said operation will be done.
Unsupported types will raise ``TypeError``.
If the entity can't be found, ``ValueError`` will be raised.
Returns
:tl:`InputPeerUser`, :tl:`InputPeerChat` or :tl:`InputPeerChannel`
or :tl:`InputPeerSelf` if the parameter is ``'me'`` or ``'self'``.
If you need to get the ID of yourself, you should use
`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 = await client.get_input_entity('username')
# The same applies to IDs, chats or channels.
chat = await 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:
return utils.get_input_peer(peer) return utils.get_input_peer(peer)
@ -472,20 +316,6 @@ async def get_peer_id(
self: 'TelegramClient', self: 'TelegramClient',
peer: 'hints.EntityLike', peer: 'hints.EntityLike',
add_mark: bool = True) -> int: add_mark: bool = True) -> int:
"""
Gets the ID for the given entity.
This method needs to be ``async`` because `peer` supports usernames,
invite-links, phone numbers (from people in your contact list), etc.
If ``add_mark is False``, then a positive ID will be returned
instead. By default, bot-API style IDs (signed) are returned.
Example
.. code-block:: python
print(await 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)