mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-08-09 13:29:47 +00:00
Merge branch 'v2'
v2 is still not complete. A lot of cleanup still needs to be done. In particular, entities still need some care. However, most of it is there, and keeping up with two branches is annoying. This also lets me close a lot of issues to reduce noise and focus on the important ones. Closes #354 (input entities have been reworked). Closes #902 (sessions were overhauled). Closes #1125, #3253, #1589, #1634, #3150, #3668 (updates are reworked, gaps are properly handled now). Closes #1169 (2.0 is now merged). Closes #1311 (proper usage should not trigger this issue on the reworked connection code). Closes #1327 (there have been some stringify changes). Closes #1330 (gaps are now detected). Closes #1366 (sessions are now async). Closes #1476, #1484 (asyncio open connection is no longer used). Closes #1529 (commonmark is now used). Closes #1721 (update gaps are now properly handled). Closes #1724 (a gap that fixes this will eventually trigger). Closes #3006 (force_sms is gone). Closes #3041 (a clean implementation to get difference now exists). Closes #3049 (commonmark is now used). Closes #3111 (to_dict has changed). Closes #3117 (SMS is no longer an option). Closes #3171 (connectivity bug is unlikely to be a bug in the library). Closes #3206 (Telethon cannot really fix broken SSL). Closes #3214, #3257, #3661 (not enough information). Closes #3215 (this had already been fixed). Closes #3230, #3674 (entities were reworked). Closes #3234, #3238, #3245, #3258, #3264 (the layer has been updated). Closes #3242 (bot-API file IDs have been removed). Closes #3244 (the error is now documented). Closes #3249 (errors have been reworked).
This commit is contained in:
@@ -58,84 +58,6 @@ What are asyncio basics?
|
||||
loop.run_until_complete(main())
|
||||
|
||||
|
||||
What does telethon.sync do?
|
||||
===========================
|
||||
|
||||
The moment you import any of these:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon import sync, ...
|
||||
# or
|
||||
from telethon.sync import ...
|
||||
# or
|
||||
import telethon.sync
|
||||
|
||||
The ``sync`` module rewrites most ``async def``
|
||||
methods in Telethon to something similar to this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def new_method():
|
||||
result = original_method()
|
||||
if loop.is_running():
|
||||
# the loop is already running, return the await-able to the user
|
||||
return result
|
||||
else:
|
||||
# the loop is not running yet, so we can run it for the user
|
||||
return loop.run_until_complete(result)
|
||||
|
||||
|
||||
That means you can do this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
print(client.get_me().username)
|
||||
|
||||
Instead of this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
me = client.loop.run_until_complete(client.get_me())
|
||||
print(me.username)
|
||||
|
||||
# or, using asyncio's default loop (it's the same)
|
||||
import asyncio
|
||||
loop = asyncio.get_event_loop() # == client.loop
|
||||
me = loop.run_until_complete(client.get_me())
|
||||
print(me.username)
|
||||
|
||||
|
||||
As you can see, it's a lot of boilerplate and noise having to type
|
||||
``run_until_complete`` all the time, so you can let the magic module
|
||||
to rewrite it for you. But notice the comment above: it won't run
|
||||
the loop if it's already running, because it can't. That means this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async def main():
|
||||
# 3. the loop is running here
|
||||
print(
|
||||
client.get_me() # 4. this will return a coroutine!
|
||||
.username # 5. this fails, coroutines don't have usernames
|
||||
)
|
||||
|
||||
loop.run_until_complete( # 2. run the loop and the ``main()`` coroutine
|
||||
main() # 1. calling ``async def`` "returns" a coroutine
|
||||
)
|
||||
|
||||
|
||||
Will fail. So if you're inside an ``async def``, then the loop is
|
||||
running, and if the loop is running, you must ``await`` things yourself:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async def main():
|
||||
print((await client.get_me()).username)
|
||||
|
||||
loop.run_until_complete(main())
|
||||
|
||||
|
||||
What are async, await and coroutines?
|
||||
=====================================
|
||||
|
||||
@@ -275,7 +197,7 @@ in it. So if you want to run *other* code, create tasks for it:
|
||||
|
||||
loop.create_task(clock())
|
||||
...
|
||||
client.run_until_disconnected()
|
||||
await client.run_until_disconnected()
|
||||
|
||||
This creates a task for a clock that prints the time every second.
|
||||
You don't need to use `client.run_until_disconnected()
|
||||
@@ -344,19 +266,6 @@ When you use a library, you're not limited to use only its methods. You can
|
||||
combine all the libraries you want. People seem to forget this simple fact!
|
||||
|
||||
|
||||
Why does client.start() work outside async?
|
||||
===========================================
|
||||
|
||||
Because it's so common that it's really convenient to offer said
|
||||
functionality by default. This means you can set up all your event
|
||||
handlers and start the client without worrying about loops at all.
|
||||
|
||||
Using the client in a ``with`` block, `start
|
||||
<telethon.client.auth.AuthMethods.start>`, `run_until_disconnected
|
||||
<telethon.client.updates.UpdateMethods.run_until_disconnected>`, and
|
||||
`disconnect <telethon.client.telegrambaseclient.TelegramBaseClient.disconnect>`
|
||||
all support this.
|
||||
|
||||
Where can I read more?
|
||||
======================
|
||||
|
||||
|
@@ -74,7 +74,7 @@ Or we call `client.get_input_entity()
|
||||
async def main():
|
||||
peer = await client.get_input_entity('someone')
|
||||
|
||||
client.loop.run_until_complete(main())
|
||||
asyncio.run(main())
|
||||
|
||||
.. note::
|
||||
|
||||
|
@@ -73,10 +73,10 @@ You can import these ``from telethon.sessions``. For example, using the
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon.sync import TelegramClient
|
||||
from telethon import TelegramClient
|
||||
from telethon.sessions import StringSession
|
||||
|
||||
with TelegramClient(StringSession(string), api_id, api_hash) as client:
|
||||
async with TelegramClient(StringSession(string), api_id, api_hash) as client:
|
||||
... # use the client
|
||||
|
||||
# Save the string session as a string; you should decide how
|
||||
@@ -129,10 +129,10 @@ The easiest way to generate a string session is as follows:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon.sync import TelegramClient
|
||||
from telethon import TelegramClient
|
||||
from telethon.sessions import StringSession
|
||||
|
||||
with TelegramClient(StringSession(), api_id, api_hash) as client:
|
||||
async with TelegramClient(StringSession(), api_id, api_hash) as client:
|
||||
print(client.session.save())
|
||||
|
||||
|
||||
@@ -156,8 +156,8 @@ you can save it in a variable directly:
|
||||
.. code-block:: python
|
||||
|
||||
string = '1aaNk8EX-YRfwoRsebUkugFvht6DUPi_Q25UOCzOAqzc...'
|
||||
with TelegramClient(StringSession(string), api_id, api_hash) as client:
|
||||
client.loop.run_until_complete(client.send_message('me', 'Hi'))
|
||||
async with TelegramClient(StringSession(string), api_id, api_hash).start() as client:
|
||||
await client.send_message('me', 'Hi')
|
||||
|
||||
|
||||
These strings are really convenient for using in places like Heroku since
|
||||
|
Reference in New Issue
Block a user