mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-08-08 21:10:29 +00:00
Completely overhaul the documentation
This commit is contained in:
3216
readthedocs/misc/changelog.rst
Normal file
3216
readthedocs/misc/changelog.rst
Normal file
File diff suppressed because it is too large
Load Diff
187
readthedocs/misc/compatibility-and-convenience.rst
Normal file
187
readthedocs/misc/compatibility-and-convenience.rst
Normal file
@@ -0,0 +1,187 @@
|
||||
.. _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.
|
65
readthedocs/misc/wall-of-shame.rst
Normal file
65
readthedocs/misc/wall-of-shame.rst
Normal file
@@ -0,0 +1,65 @@
|
||||
=============
|
||||
Wall of Shame
|
||||
=============
|
||||
|
||||
|
||||
This project has an
|
||||
`issues <https://github.com/LonamiWebs/Telethon/issues>`__ section for
|
||||
you to file **issues** whenever you encounter any when working with the
|
||||
library. Said section is **not** for issues on *your* program but rather
|
||||
issues with Telethon itself.
|
||||
|
||||
If you have not made the effort to 1. read through the docs and 2.
|
||||
`look for the method you need <https://lonamiwebs.github.io/Telethon/>`__,
|
||||
you will end up on the `Wall of
|
||||
Shame <https://github.com/LonamiWebs/Telethon/issues?q=is%3Aissue+label%3ARTFM+is%3Aclosed>`__,
|
||||
i.e. all issues labeled
|
||||
`"RTFM" <http://www.urbandictionary.com/define.php?term=RTFM>`__:
|
||||
|
||||
**rtfm**
|
||||
Literally "Read The F--king Manual"; a term showing the
|
||||
frustration of being bothered with questions so trivial that the asker
|
||||
could have quickly figured out the answer on their own with minimal
|
||||
effort, usually by reading readily-available documents. People who
|
||||
say"RTFM!" might be considered rude, but the true rude ones are the
|
||||
annoying people who take absolutely no self-responibility and expect to
|
||||
have all the answers handed to them personally.
|
||||
|
||||
*"Damn, that's the twelveth time that somebody posted this question
|
||||
to the messageboard today! RTFM, already!"*
|
||||
|
||||
*by Bill M. July 27, 2004*
|
||||
|
||||
If you have indeed read the docs, and have tried looking for the method,
|
||||
and yet you didn't find what you need, **that's fine**. Telegram's API
|
||||
can have some obscure names at times, and for this reason, there is a
|
||||
`"question"
|
||||
label <https://github.com/LonamiWebs/Telethon/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20label%3Aquestion%20>`__
|
||||
with questions that are okay to ask. Just state what you've tried so
|
||||
that we know you've made an effort, or you'll go to the Wall of Shame.
|
||||
|
||||
Of course, if the issue you're going to open is not even a question but
|
||||
a real issue with the library (thankfully, most of the issues have been
|
||||
that!), you won't end up here. Don't worry.
|
||||
|
||||
Current winner
|
||||
--------------
|
||||
|
||||
The current winner is `issue
|
||||
213 <https://github.com/LonamiWebs/Telethon/issues/213>`__:
|
||||
|
||||
**Issue:**
|
||||
|
||||
.. figure:: https://user-images.githubusercontent.com/6297805/29822978-9a9a6ef0-8ccd-11e7-9ec5-934ea0f57681.jpg
|
||||
|
||||
:alt: Winner issue
|
||||
|
||||
Winner issue
|
||||
|
||||
**Answer:**
|
||||
|
||||
.. figure:: https://user-images.githubusercontent.com/6297805/29822983-9d523402-8ccd-11e7-9fb1-5783740ee366.jpg
|
||||
|
||||
:alt: Winner issue answer
|
||||
|
||||
Winner issue answer
|
Reference in New Issue
Block a user