mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-08-03 11:40:11 +03:00
Fix asyncio docs
This commit is contained in:
parent
aba478789c
commit
85089353f2
|
@ -67,7 +67,7 @@ Or we call ``.get_input_entity()``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
peer = client.get_input_entity('someone')
|
peer = await client.get_input_entity('someone')
|
||||||
|
|
||||||
When you're going to invoke an API method, most require you to pass an
|
When you're going to invoke an API method, most require you to pass an
|
||||||
:tl:`InputUser`, :tl:`InputChat`, or so on, this is why using
|
:tl:`InputUser`, :tl:`InputChat`, or so on, this is why using
|
||||||
|
@ -78,7 +78,7 @@ If you also need to have information about the whole user, use
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
entity = client.get_entity('someone')
|
entity = await client.get_entity('someone')
|
||||||
|
|
||||||
In the later case, when you use the entity, the library will cast it to
|
In the later case, when you use the entity, the library will cast it to
|
||||||
its "input" version for you. If you already have the complete user and
|
its "input" version for you. If you already have the complete user and
|
||||||
|
@ -104,7 +104,7 @@ request we do:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
result = client(SendMessageRequest(peer, 'Hello there!'))
|
result = await client(SendMessageRequest(peer, 'Hello there!'))
|
||||||
# __call__ is an alias for client.invoke(request). Both will work
|
# __call__ is an alias for client.invoke(request). Both will work
|
||||||
|
|
||||||
Message sent! Of course, this is only an example. There are nearly 250
|
Message sent! Of course, this is only an example. There are nearly 250
|
||||||
|
@ -113,7 +113,8 @@ as you wish. Remember to use the right types! To sum up:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
result = client(SendMessageRequest(
|
async def method():
|
||||||
|
result = await client(SendMessageRequest(
|
||||||
client.get_input_entity('username'), 'Hello there!'
|
client.get_input_entity('username'), 'Hello there!'
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@ -122,9 +123,9 @@ This can further be simplified to:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
result = client(SendMessageRequest('username', 'Hello there!'))
|
result = await client(SendMessageRequest('username', 'Hello there!'))
|
||||||
# Or even
|
# Or even
|
||||||
result = client(SendMessageRequest(PeerChannel(id), 'Hello there!'))
|
result = await client(SendMessageRequest(PeerChannel(id), 'Hello there!'))
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
|
@ -4,41 +4,23 @@
|
||||||
Update Modes
|
Update Modes
|
||||||
============
|
============
|
||||||
|
|
||||||
|
Using ``asyncio`` simplifies the way you can work with updates. The library
|
||||||
|
will always ensure the future of a loop that will poll updates for you, so
|
||||||
|
you can do other things in the mean time.
|
||||||
|
|
||||||
The library can run in four distinguishable modes:
|
Once you have your client ready, the next thing you want to do is to add a
|
||||||
|
method that will be called when an `Update`__ arrives:
|
||||||
- With no extra threads at all.
|
|
||||||
- With an extra thread that receives everything as soon as possible (default).
|
|
||||||
- With several worker threads that run your update handlers.
|
|
||||||
- A mix of the above.
|
|
||||||
|
|
||||||
Since this section is about updates, we'll describe the simplest way to
|
|
||||||
work with them.
|
|
||||||
|
|
||||||
|
|
||||||
Using multiple workers
|
|
||||||
**********************
|
|
||||||
|
|
||||||
When you create your client, simply pass a number to the
|
|
||||||
``update_workers`` parameter:
|
|
||||||
|
|
||||||
``client = TelegramClient('session', api_id, api_hash, update_workers=2)``
|
|
||||||
|
|
||||||
You can set any amount of workers you want. The more you put, the more
|
|
||||||
update handlers that can be called "at the same time". One or two should
|
|
||||||
suffice most of the time, since setting more will not make things run
|
|
||||||
faster most of the times (actually, it could slow things down).
|
|
||||||
|
|
||||||
The next thing you want to do is to add a method that will be called when
|
|
||||||
an `Update`__ arrives:
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def callback(update):
|
import asyncio
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
async def callback(update):
|
||||||
print('I received', update)
|
print('I received', update)
|
||||||
|
|
||||||
client.add_event_handler(callback)
|
loop.run_until_complete(client.add_event_handler(callback))
|
||||||
# do more work here, or simply sleep!
|
loop.run_forever() # this blocks forever, don't let the script end!
|
||||||
|
|
||||||
That's it! This is the old way to listen for raw updates, with no further
|
That's it! This is the old way to listen for raw updates, with no further
|
||||||
processing. If this feels annoying for you, remember that you can always
|
processing. If this feels annoying for you, remember that you can always
|
||||||
|
@ -51,94 +33,18 @@ let's reply to them with the same text reversed:
|
||||||
|
|
||||||
from telethon.tl.types import UpdateShortMessage, PeerUser
|
from telethon.tl.types import UpdateShortMessage, PeerUser
|
||||||
|
|
||||||
def replier(update):
|
async def replier(update):
|
||||||
if isinstance(update, UpdateShortMessage) and not update.out:
|
if isinstance(update, UpdateShortMessage) and not update.out:
|
||||||
client.send_message(PeerUser(update.user_id), update.message[::-1])
|
await client.send_message(PeerUser(update.user_id), update.message[::-1])
|
||||||
|
|
||||||
|
|
||||||
client.add_event_handler(replier)
|
loop.run_until_complete(client.add_event_handler(replier))
|
||||||
input('Press enter to stop this!')
|
loop.run_forever()
|
||||||
client.disconnect()
|
|
||||||
|
|
||||||
We only ask you one thing: don't keep this running for too long, or your
|
We only ask you one thing: don't keep this running for too long, or your
|
||||||
contacts will go mad.
|
contacts will go mad.
|
||||||
|
|
||||||
|
|
||||||
Spawning no worker at all
|
|
||||||
*************************
|
|
||||||
|
|
||||||
All the workers do is loop forever and poll updates from a queue that is
|
|
||||||
filled from the ``ReadThread``, responsible for reading every item off
|
|
||||||
the network. If you only need a worker and the ``MainThread`` would be
|
|
||||||
doing no other job, this is the preferred way. You can easily do the same
|
|
||||||
as the workers like so:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
update = client.updates.poll()
|
|
||||||
if not update:
|
|
||||||
continue
|
|
||||||
|
|
||||||
print('I received', update)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
break
|
|
||||||
|
|
||||||
client.disconnect()
|
|
||||||
|
|
||||||
Note that ``poll`` accepts a ``timeout=`` parameter, and it will return
|
|
||||||
``None`` if other thread got the update before you could or if the timeout
|
|
||||||
expired, so it's important to check ``if not update``.
|
|
||||||
|
|
||||||
This can coexist with the rest of ``N`` workers, or you can set it to ``0``
|
|
||||||
additional workers:
|
|
||||||
|
|
||||||
``client = TelegramClient('session', api_id, api_hash, update_workers=0)``
|
|
||||||
|
|
||||||
You **must** set it to ``0`` (or higher), as it defaults to ``None`` and that
|
|
||||||
has a different meaning. ``None`` workers means updates won't be processed
|
|
||||||
*at all*, so you must set it to some integer value if you want
|
|
||||||
``client.updates.poll()`` to work.
|
|
||||||
|
|
||||||
|
|
||||||
Using the main thread instead the ``ReadThread``
|
|
||||||
************************************************
|
|
||||||
|
|
||||||
If you have no work to do on the ``MainThread`` and you were planning to have
|
|
||||||
a ``while True: sleep(1)``, don't do that. Instead, don't spawn the secondary
|
|
||||||
``ReadThread`` at all like so:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
client = TelegramClient(
|
|
||||||
...
|
|
||||||
spawn_read_thread=False
|
|
||||||
)
|
|
||||||
|
|
||||||
And then ``.idle()`` from the ``MainThread``:
|
|
||||||
|
|
||||||
``client.idle()``
|
|
||||||
|
|
||||||
You can stop it with :kbd:`Control+C`, and you can configure the signals
|
|
||||||
to be used in a similar fashion to `Python Telegram Bot`__.
|
|
||||||
|
|
||||||
As a complete example:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def callback(update):
|
|
||||||
print('I received', update)
|
|
||||||
|
|
||||||
client = TelegramClient('session', api_id, api_hash,
|
|
||||||
update_workers=1, spawn_read_thread=False)
|
|
||||||
|
|
||||||
client.connect()
|
|
||||||
client.add_event_handler(callback)
|
|
||||||
client.idle() # ends with Ctrl+C
|
|
||||||
|
|
||||||
|
|
||||||
This is the preferred way to use if you're simply going to listen for updates.
|
This is the preferred way to use if you're simply going to listen for updates.
|
||||||
|
|
||||||
__ https://lonamiwebs.github.io/Telethon/types/update.html
|
__ https://lonamiwebs.github.io/Telethon/types/update.html
|
||||||
__ https://github.com/python-telegram-bot/python-telegram-bot/blob/4b3315db6feebafb94edcaa803df52bb49999ced/telegram/ext/updater.py#L460
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ As a full example:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
async def main():
|
||||||
client = TelegramClient('anon', api_id, api_hash)
|
client = TelegramClient('anon', api_id, api_hash)
|
||||||
assert await client.connect()
|
assert await client.connect()
|
||||||
if not client.is_user_authorized():
|
if not client.is_user_authorized():
|
||||||
|
@ -95,6 +96,7 @@ All of this, however, can be done through a call to ``.start()``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
async def main():
|
||||||
client = TelegramClient('anon', api_id, api_hash)
|
client = TelegramClient('anon', api_id, api_hash)
|
||||||
await client.start()
|
await client.start()
|
||||||
|
|
||||||
|
@ -159,7 +161,7 @@ account, calling :meth:`telethon.TelegramClient.sign_in` will raise a
|
||||||
import getpass
|
import getpass
|
||||||
from telethon.errors import SessionPasswordNeededError
|
from telethon.errors import SessionPasswordNeededError
|
||||||
|
|
||||||
client.sign_in(phone)
|
await client.sign_in(phone)
|
||||||
try:
|
try:
|
||||||
await client.sign_in(code=input('Enter code: '))
|
await client.sign_in(code=input('Enter code: '))
|
||||||
except SessionPasswordNeededError:
|
except SessionPasswordNeededError:
|
||||||
|
|
|
@ -38,7 +38,7 @@ Getting entities
|
||||||
|
|
||||||
Through the use of the :ref:`sessions`, the library will automatically
|
Through the use of the :ref:`sessions`, the library will automatically
|
||||||
remember the ID and hash pair, along with some extra information, so
|
remember the ID and hash pair, along with some extra information, so
|
||||||
you're able to just do this:
|
you're able to just do this (inside an ``async def``):
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
|
|
@ -19,15 +19,19 @@ Creating a client
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
from telethon import TelegramClient
|
from telethon import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
# These example values won't work. You must get your own api_id and
|
# These example values won't work. You must get your own api_id and
|
||||||
# api_hash from https://my.telegram.org, under API Development.
|
# api_hash from https://my.telegram.org, under API Development.
|
||||||
api_id = 12345
|
api_id = 12345
|
||||||
api_hash = '0123456789abcdef0123456789abcdef'
|
api_hash = '0123456789abcdef0123456789abcdef'
|
||||||
|
|
||||||
client = TelegramClient('session_name', api_id, api_hash)
|
client = TelegramClient('session_name', api_id, api_hash)
|
||||||
await client.start()
|
loop.run_until_complete(client.start())
|
||||||
|
|
||||||
**More details**: :ref:`creating-a-client`
|
**More details**: :ref:`creating-a-client`
|
||||||
|
|
||||||
|
@ -37,6 +41,8 @@ Basic Usage
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
# You should write all this inside of an async def.
|
||||||
|
#
|
||||||
# Getting information about yourself
|
# Getting information about yourself
|
||||||
print((await client.get_me()).stringify())
|
print((await client.get_me()).stringify())
|
||||||
|
|
||||||
|
@ -76,9 +82,6 @@ Handling Updates
|
||||||
import asyncio
|
import asyncio
|
||||||
from telethon import events
|
from telethon import events
|
||||||
|
|
||||||
# We need to have some worker running
|
|
||||||
client.updates.workers = 1
|
|
||||||
|
|
||||||
@client.on(events.NewMessage(incoming=True, pattern='(?i)hi'))
|
@client.on(events.NewMessage(incoming=True, pattern='(?i)hi'))
|
||||||
async def handler(event):
|
async def handler(event):
|
||||||
await event.reply('Hello!')
|
await event.reply('Hello!')
|
||||||
|
|
|
@ -32,7 +32,7 @@ need of manually importing the requests you need.
|
||||||
|
|
||||||
For instance, retrieving your own user can be done in a single line:
|
For instance, retrieving your own user can be done in a single line:
|
||||||
|
|
||||||
``myself = client.get_me()``
|
``myself = await client.get_me()``
|
||||||
|
|
||||||
Internally, this method has sent a request to Telegram, who replied with
|
Internally, this method has sent a request to Telegram, who replied with
|
||||||
the information about your own user, and then the desired information
|
the information about your own user, and then the desired information
|
||||||
|
@ -53,7 +53,8 @@ The so called "entities" are another important whole concept on its own,
|
||||||
but for now you don't need to worry about it. Simply know that they are
|
but for now you don't need to worry about it. Simply know that they are
|
||||||
a good way to get information about an user, chat or channel.
|
a good way to get information about an user, chat or channel.
|
||||||
|
|
||||||
Many other common methods for quick scripts are also available:
|
Many other common methods for quick scripts are also available.
|
||||||
|
Note that you should be writing this inside of an ``async def``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
|
|
@ -31,27 +31,32 @@ Getting Started
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
from telethon import TelegramClient, events
|
from telethon import TelegramClient, events
|
||||||
|
|
||||||
client = TelegramClient(..., update_workers=1, spawn_read_thread=False)
|
client = TelegramClient(...)
|
||||||
await client.start()
|
loop.run_until_complete(client.start())
|
||||||
|
|
||||||
@client.on(events.NewMessage)
|
@client.on(events.NewMessage)
|
||||||
async def my_event_handler(event):
|
async def my_event_handler(event):
|
||||||
if 'hello' in event.raw_text:
|
if 'hello' in event.raw_text:
|
||||||
await event.reply('hi!')
|
await event.reply('hi!')
|
||||||
|
|
||||||
asyncio.get_event_loop().run_forever()
|
loop.run_forever()
|
||||||
|
|
||||||
|
|
||||||
Not much, but there might be some things unclear. What does this code do?
|
Not much, but there might be some things unclear. What does this code do?
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
from telethon import TelegramClient, events
|
from telethon import TelegramClient, events
|
||||||
|
|
||||||
client = TelegramClient(..., update_workers=1, spawn_read_thread=False)
|
client = TelegramClient(...)
|
||||||
await client.start()
|
loop.run_until_complete(client.start())
|
||||||
|
|
||||||
|
|
||||||
This is normal initialization (of course, pass session name, API ID and hash).
|
This is normal initialization (of course, pass session name, API ID and hash).
|
||||||
|
@ -78,7 +83,7 @@ message, we ``reply`` to the event with a ``'hi!'`` message.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
asyncio.get_event_loop().run_forever()
|
loop.run_forever()
|
||||||
|
|
||||||
|
|
||||||
Finally, this tells the script that we're done with our code, and want
|
Finally, this tells the script that we're done with our code, and want
|
||||||
|
|
|
@ -256,7 +256,9 @@ class TelegramClient(TelegramBareClient):
|
||||||
also taking into consideration that 2FA may be enabled in the account.
|
also taking into consideration that 2FA may be enabled in the account.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
>>> client = await TelegramClient(session, api_id, api_hash).start(phone)
|
>>> import asyncio
|
||||||
|
>>> rc = asyncio.get_event_loop().run_until_complete
|
||||||
|
>>> client = rc(TelegramClient(session, api_id, api_hash).start(phone))
|
||||||
Please enter the code you received: 12345
|
Please enter the code you received: 12345
|
||||||
Please enter your password: *******
|
Please enter your password: *******
|
||||||
(You are now logged in)
|
(You are now logged in)
|
||||||
|
@ -945,6 +947,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
>>> import asyncio
|
||||||
>>> async def main():
|
>>> async def main():
|
||||||
... client = await TelegramClient(...).start()
|
... client = await TelegramClient(...).start()
|
||||||
... message = await client.send_message('username', 'hello')
|
... message = await client.send_message('username', 'hello')
|
||||||
|
@ -955,7 +958,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
... # or
|
... # or
|
||||||
... await client.edit_message(message, 'Hello!')
|
... await client.edit_message(message, 'Hello!')
|
||||||
...
|
...
|
||||||
>>> loop = ...
|
>>> loop = asyncio.get_event_loop()
|
||||||
>>> loop.run_until_complete(main())
|
>>> loop.run_until_complete(main())
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user