mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-12-04 23:33:46 +03:00
188 lines
6.1 KiB
ReStructuredText
188 lines
6.1 KiB
ReStructuredText
.. _compatibility-and-convenience:
|
|
|
|
=============================
|
|
Compatibility and Convenience
|
|
=============================
|
|
|
|
Telethon is an `asyncio` library. Compatibility is an important concern,
|
|
and while it can't always be kept and mistakes happens, the :ref:`changelog`
|
|
is there to tell you when these important changes happen.
|
|
|
|
.. contents::
|
|
|
|
|
|
Compatibility
|
|
=============
|
|
|
|
Some decisions when developing will inevitable be proven wrong in the future.
|
|
One of these decisions was using threads. Now that Python 3.4 is reaching EOL
|
|
and using `asyncio` is usable as of Python 3.5 it makes sense for a library
|
|
like Telethon to make a good use of it.
|
|
|
|
If you have old code, **just use old versions** of the library! There is
|
|
nothing wrong with that other than not getting new updates or fixes, but
|
|
using a fixed version with ``pip install telethon==0.19.1.6`` is easy
|
|
enough to do.
|
|
|
|
You might want to consider using `Virtual Environments
|
|
<https://docs.python.org/3/tutorial/venv.html>`_ in your projects.
|
|
|
|
There's no point in maintaining a synchronous version because the whole point
|
|
is that people don't have time to upgrade, and there has been several changes
|
|
and clean-ups. Using an older version is the right way to go.
|
|
|
|
Sometimes, other small decisions are made. These all will be reflected in the
|
|
:ref:`changelog` which you should read when upgrading.
|
|
|
|
If you want to jump the `asyncio` boat, here are some of the things you will
|
|
need to start migrating really old code:
|
|
|
|
.. code-block:: python
|
|
|
|
# 1. Import the client from telethon.sync
|
|
from telethon.sync import TelegramClient
|
|
|
|
# 2. Change this monster...
|
|
try:
|
|
assert client.connect()
|
|
if not client.is_user_authorized():
|
|
client.send_code_request(phone_number)
|
|
me = client.sign_in(phone_number, input('Enter code: '))
|
|
|
|
... # REST OF YOUR CODE
|
|
finally:
|
|
client.disconnect()
|
|
|
|
# ...for this:
|
|
with client:
|
|
... # REST OF YOUR CODE
|
|
|
|
# 3. client.idle() no longer exists.
|
|
# Change this...
|
|
client.idle()
|
|
# ...to this:
|
|
client.run_until_disconnected()
|
|
|
|
# 4. client.add_update_handler no longer exists.
|
|
# Change this...
|
|
client.add_update_handler(handler)
|
|
# ...to this:
|
|
client.add_event_handler(handler)
|
|
|
|
|
|
In addition, all the update handlers must be ``async def``, and you need
|
|
to ``await`` method calls that rely on network requests, such as getting
|
|
the chat or sender. If you don't use updates, you're done!
|
|
|
|
|
|
Convenience
|
|
===========
|
|
|
|
.. note::
|
|
|
|
The entire documentation assumes you have done one of the following:
|
|
|
|
.. code-block:: python
|
|
|
|
from telethon import TelegramClient, sync
|
|
# or
|
|
from telethon.sync import TelegramClient
|
|
|
|
This makes the examples shorter and easier to think about.
|
|
|
|
For quick scripts that don't need updates, it's a lot more convenient to
|
|
forget about `asyncio` and just work with sequential code. This can prove
|
|
to be a powerful hybrid for running under the Python REPL too.
|
|
|
|
.. code-block:: python
|
|
|
|
from telethon.sync import TelegramClient
|
|
# ^~~~~ note this part; it will manage the asyncio loop for you
|
|
|
|
with TelegramClient(...) as client:
|
|
print(client.get_me().username)
|
|
# ^ notice the lack of await, or loop.run_until_complete().
|
|
# Since there is no loop running, this is done behind the scenes.
|
|
#
|
|
message = client.send_message('me', 'Hi!')
|
|
import time
|
|
time.sleep(5)
|
|
message.delete()
|
|
|
|
# You can also have an hybrid between a synchronous
|
|
# part and asynchronous event handlers.
|
|
#
|
|
from telethon import events
|
|
@client.on(events.NewMessage(pattern='(?i)hi|hello'))
|
|
async def handler(event):
|
|
await event.reply('hey')
|
|
|
|
client.run_until_disconnected()
|
|
|
|
|
|
Some methods, such as ``with``, ``start``, ``disconnect`` and
|
|
``run_until_disconnected`` work both in synchronous and asynchronous
|
|
contexts by default for convenience, and to avoid the little overhead
|
|
it has when using methods like sending a message, getting messages, etc.
|
|
This keeps the best of both worlds as a sane default.
|
|
|
|
.. note::
|
|
|
|
As a rule of thumb, if you're inside an ``async def`` and you need
|
|
the client, you need to ``await`` calls to the API. If you call other
|
|
functions that also need API calls, make them ``async def`` and ``await``
|
|
them too. Otherwise, there is no need to do so with this mode.
|
|
|
|
Speed
|
|
=====
|
|
|
|
When you're ready to micro-optimize your application, or if you simply
|
|
don't need to call any non-basic methods from a synchronous context,
|
|
just get rid of ``telethon.sync`` and work inside an ``async def``:
|
|
|
|
.. code-block:: python
|
|
|
|
import asyncio
|
|
from telethon import TelegramClient, events
|
|
|
|
async def main():
|
|
async with TelegramClient(...) as client:
|
|
print((await client.get_me()).username)
|
|
# ^_____________________^ notice these parenthesis
|
|
# You want to ``await`` the call, not the username.
|
|
#
|
|
message = await client.send_message('me', 'Hi!')
|
|
await asyncio.sleep(5)
|
|
await message.delete()
|
|
|
|
@client.on(events.NewMessage(pattern='(?i)hi|hello'))
|
|
async def handler(event):
|
|
await event.reply('hey')
|
|
|
|
await client.run_until_disconnected()
|
|
|
|
loop = asyncio.get_event_loop()
|
|
loop.run_until_complete(main())
|
|
|
|
|
|
The ``telethon.sync`` magic module simply wraps every method behind:
|
|
|
|
.. code-block:: python
|
|
|
|
loop = asyncio.get_event_loop()
|
|
loop.run_until_complete(main())
|
|
|
|
So that you don't have to write it yourself every time. That's the
|
|
overhead you pay if you import it, and what you save if you don't.
|
|
|
|
Learning
|
|
========
|
|
|
|
You know the library uses `asyncio` everywhere, and you want to learn
|
|
how to do things right. Even though `asyncio` is its own topic, the
|
|
documentation wants you to learn how to use Telethon correctly, and for
|
|
that, you need to use `asyncio` correctly too. For this reason, there
|
|
is a section called :ref:`mastering-asyncio` that will introduce you to
|
|
the `asyncio` world, with links to more resources for learning how to
|
|
use it. Feel free to check that section out once you have read the rest.
|