mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-11-16 05:40:45 +00:00
Rewrite the first part of the docs for asyncio
This commit is contained in:
@@ -69,7 +69,9 @@ Or we call `client.get_input_entity
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
peer = client.get_input_entity('someone')
|
||||
import asyncio
|
||||
loop = asyncio.get_event_loop()
|
||||
peer = loop.run_until_complete(client.get_input_entity('someone'))
|
||||
|
||||
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
|
||||
@@ -81,7 +83,7 @@ instead:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
entity = client.get_entity('someone')
|
||||
entity = loop.run_until_complete(client.get_entity('someone'))
|
||||
|
||||
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
|
||||
@@ -110,7 +112,9 @@ request we do:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result = client(SendMessageRequest(peer, 'Hello there!'))
|
||||
result = loop.run_until_complete(
|
||||
client(SendMessageRequest(peer, 'Hello there!'))
|
||||
)
|
||||
# __call__ is an alias for client.invoke(request). Both will work
|
||||
|
||||
Message sent! Of course, this is only an example. There are nearly 250
|
||||
@@ -119,19 +123,21 @@ as you wish. Remember to use the right types! To sum up:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result = client(SendMessageRequest(
|
||||
result = loop.run_until_complete(client(SendMessageRequest(
|
||||
client.get_input_entity('username'), 'Hello there!'
|
||||
))
|
||||
)))
|
||||
|
||||
|
||||
This can further be simplified to:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result = client(SendMessageRequest('username', 'Hello there!'))
|
||||
# Or even
|
||||
result = client(SendMessageRequest(PeerChannel(id), 'Hello there!'))
|
||||
async def main():
|
||||
result = await client(SendMessageRequest('username', 'Hello there!'))
|
||||
# Or even
|
||||
result = await client(SendMessageRequest(PeerChannel(id), 'Hello there!'))
|
||||
|
||||
loop.run_until_complete(main())
|
||||
|
||||
.. note::
|
||||
|
||||
|
||||
@@ -4,141 +4,46 @@
|
||||
Update Modes
|
||||
============
|
||||
|
||||
With ``asyncio``, the library has several tasks running in the background.
|
||||
One task is used for sending requests, another task is used to receive them,
|
||||
and a third one is used to handle updates.
|
||||
|
||||
The library can run in four distinguishable modes:
|
||||
To handle updates, you must keep your script running. You can do this in
|
||||
several ways. For instance, if you are *not* running ``asyncio``'s event
|
||||
loop, you should use `client.run_until_disconnected
|
||||
<telethon.client.updates.UpdateMethods.run_until_disconnected>`:
|
||||
|
||||
- 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.
|
||||
.. code-block:: python
|
||||
|
||||
Since this section is about updates, we'll describe the simplest way to
|
||||
work with them.
|
||||
import asyncio
|
||||
from telethon import TelegramClient
|
||||
|
||||
client = TelegramClient(...)
|
||||
...
|
||||
client.run_until_disconnected()
|
||||
|
||||
|
||||
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
|
||||
|
||||
def callback(update):
|
||||
print('I received', update)
|
||||
|
||||
client.add_event_handler(callback)
|
||||
# do more work here, or simply sleep!
|
||||
|
||||
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
|
||||
use :ref:`working-with-updates` but maybe use this for some other cases.
|
||||
|
||||
Now let's do something more interesting. Every time an user talks to us,
|
||||
let's reply to them with the same text reversed:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon.tl.types import UpdateShortMessage, PeerUser
|
||||
|
||||
def replier(update):
|
||||
if isinstance(update, UpdateShortMessage) and not update.out:
|
||||
client.send_message(PeerUser(update.user_id), update.message[::-1])
|
||||
Behind the scenes, this method is ``await``'ing on the `client.disconnected
|
||||
<telethon.client.telegrambaseclient.disconnected>` property, so the code above
|
||||
and the following are equivalent:
|
||||
|
||||
|
||||
client.add_event_handler(replier)
|
||||
input('Press enter to stop this!')
|
||||
client.disconnect()
|
||||
.. code-block:: python
|
||||
|
||||
We only ask you one thing: don't keep this running for too long, or your
|
||||
contacts will go mad.
|
||||
import asyncio
|
||||
from telethon import TelegramClient
|
||||
|
||||
client = TelegramClient(...)
|
||||
|
||||
async def main():
|
||||
await client.disconnected
|
||||
|
||||
asyncio.get_event_loop().run_until_complete(main())
|
||||
|
||||
|
||||
Spawning no worker at all
|
||||
*************************
|
||||
You could also run `client.disconnected
|
||||
<telethon.client.telegrambaseclient.disconnected>` until it completed.
|
||||
|
||||
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.
|
||||
|
||||
__ https://lonamiwebs.github.io/Telethon/types/update.html
|
||||
__ https://github.com/python-telegram-bot/python-telegram-bot/blob/4b3315db6feebafb94edcaa803df52bb49999ced/telegram/ext/updater.py#L460
|
||||
But if you don't want to ``await``, then you should know what you want
|
||||
to be doing instead! What matters is that you shouldn't let your script
|
||||
die. If you don't care about updates, you don't need any of this.
|
||||
|
||||
Reference in New Issue
Block a user