Several documentation enhancements and build warnings fixes

- Made the documentation even more friendly towards newbies.
- Eased the usage of methods like get history which now set
  a default empty message for message actions and vice versa.
- Fixed some docstring documentations too.
- Updated the old normal docs/ to link back and forth RTD.
- Fixed the version of the documentation, now auto-loaded.
This commit is contained in:
Lonami Exo 2018-01-20 11:47:17 +01:00
parent 4d4e81e609
commit b716c4fe67
18 changed files with 180 additions and 141 deletions

View File

@ -44,8 +44,15 @@
page aims to provide easy access to all the available methods, their
definition and parameters.</p>
<p>Although this documentation was generated for <i>Telethon</i>, it may
be useful for any other Telegram library out there.</p>
<p>Please note that when you see this:</p>
<pre>---functions---
users.getUsers#0d91a548 id:Vector&lt;InputUser&gt; = Vector&lt;User&gt;</pre>
<p>This is <b>not</b> Python code. It's the "TL definition". It's
an easy-to-read line that gives a quick overview on the parameters
and its result. You don't need to worry about this. See
<a href="http://telethon.readthedocs.io/en/latest/extra/developing/understanding-the-type-language.html">here</a>
for more details on it.</p>
<h3>Index</h3>
<ul>
@ -69,12 +76,12 @@
<p>Currently there are <b>{method_count} methods</b> available for the layer
{layer}. The complete list can be seen <a href="methods/index.html">here</a>.
<br /><br />
Methods, also known as <i>requests</i>, are used to interact with
the Telegram API itself and are invoked with a call to <code>.invoke()</code>.
<b>Only these</b> can be passed to <code>.invoke()</code>! You cannot
<code>.invoke()</code> types or constructors, only requests. After this,
Telegram will return a <code>result</code>, which may be, for instance,
a bunch of messages, some dialogs, users, etc.</p>
Methods, also known as <i>requests</i>, are used to interact with the
Telegram API itself and are invoked through <code>client(Request(...))</code>.
<b>Only these</b> can be used like that! You cannot invoke types or
constructors, only requests. After this, Telegram will return a
<code>result</code>, which may be, for instance, a bunch of messages,
some dialogs, users, etc.</p>
<h3 id="types">Types</h3>
<p>Currently there are <b>{type_count} types</b>. You can see the full
@ -151,58 +158,9 @@
</ul>
<h3 id="example">Full example</h3>
<p>The following example demonstrates:</p>
<ol>
<li>How to create a <code>TelegramClient</code>.</li>
<li>Connecting to the Telegram servers and authorizing an user.</li>
<li>Retrieving a list of chats (<i>dialogs</i>).</li>
<li>Invoking a request without the built-in methods.</li>
</ol>
<pre><span class="sh3">#!/usr/bin/python3</span>
<span class="sh4">from</span> telethon <span class="sh4">import</span> TelegramClient
<span class="sh4">from</span> telethon.tl.functions.messages <span class="sh4">import</span> GetHistoryRequest
<span class="sh3"># <b>(1)</b> Use your own values here</span>
api_id = <span class="sh1">12345</span>
api_hash = <span class="sh2">'0123456789abcdef0123456789abcdef'</span>
phone = <span class="sh2">'+34600000000'</span>
<span class="sh3"># <b>(2)</b> Create the client and connect</span>
client = TelegramClient(<span class="sh2">'username'</span>, api_id, api_hash)
client.connect()
<span class="sh3"># Ensure you're authorized</span>
if not client.is_user_authorized():
client.send_code_request(phone)
client.sign_in(phone, input(<span class="sh2">'Enter the code: '</span>))
<span class="sh3"># <b>(3)</b> Using built-in methods</span>
dialogs, entities = client.get_dialogs(<span class="sh1">10</span>)
entity = entities[<span class="sh1">0</span>]
<span class="sh3"># <b>(4)</b> !! Invoking a request manually !!</span>
result = <b>client</b>(GetHistoryRequest(
entity,
limit=<span class="sh1">20</span>,
offset_date=<span class="sh1">None</span>,
offset_id=<span class="sh1">0</span>,
max_id=<span class="sh1">0</span>,
min_id=<span class="sh1">0</span>,
add_offset=<span class="sh1">0</span>
))
<span class="sh3"># Now you have access to the first 20 messages</span>
messages = result.messages</pre>
<p>As it can be seen, manually calling requests with
<code>client(request)</code> (or using the old way, by calling
<code>client.invoke(request)</code>) is way more verbose than using the
built-in methods (such as <code>client.get_dialogs()</code>).</p>
<p>However, and
given that there are so many methods available, it's impossible to provide
a nice interface to things that may change over time. To get full access,
however, you're still able to invoke these methods manually.</p>
<p>Documentation for this is now
<a href="http://telethon.readthedocs.io/en/latest/extra/advanced-usage/accessing-the-full-api.html">here</a>.
</p>
</div>
</div>

View File

@ -20,6 +20,11 @@
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import os
import re
root = os.path.abspath(os.path.join(__file__, os.path.pardir, os.path.pardir))
# -- General configuration ------------------------------------------------
@ -55,9 +60,12 @@ author = 'Lonami'
# built documents.
#
# The short X.Y version.
version = '0.15'
with open(os.path.join(root, 'telethon', 'version.py')) as f:
version = re.search(r"^__version__\s+=\s+'(.*)'$",
f.read(), flags=re.MULTILINE).group(1)
# The full version, including alpha/beta/rc tags.
release = '0.15.5'
release = version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -14,8 +14,10 @@ through a sorted list of everything you can do.
.. note::
Removing the hand crafted documentation for methods is still
a work in progress!
The reason to keep both https://lonamiwebs.github.io/Telethon and this
documentation alive is that the former allows instant search results
as you type, and a "Copy import" button. If you like namespaces, you
can also do ``from telethon.tl import types, functions``. Both work.
You should also refer to the documentation to see what the objects
@ -39,8 +41,8 @@ If you're going to use a lot of these, you may do:
.. code-block:: python
import telethon.tl.functions as tl
# We now have access to 'tl.messages.SendMessageRequest'
from telethon.tl import types, functions
# We now have access to 'functions.messages.SendMessageRequest'
We see that this request must take at least two parameters, a ``peer``
of type `InputPeer`__, and a ``message`` which is just a Python
@ -82,6 +84,14 @@ every time its used, simply call ``.get_input_peer``:
from telethon import utils
peer = utils.get_input_user(entity)
.. note::
Since ``v0.16.2`` this is further simplified. The ``Request`` itself
will call ``client.get_input_entity()`` for you when required, but
it's good to remember what's happening.
After this small parenthesis about ``.get_entity`` versus
``.get_input_entity``, we have everything we need. To ``.invoke()`` our
request we do:

View File

@ -93,6 +93,8 @@ method also accepts a ``phone=`` and ``bot_token`` parameters.
You can use either, as both will work. Determining which
is just a matter of taste, and how much control you need.
Remember that you can get yourself at any time with ``client.get_me()``.
.. note::
If you want to use a **proxy**, you have to `install PySocks`__

View File

@ -10,21 +10,6 @@ The library widely uses the concept of "entities". An entity will refer
to any ``User``, ``Chat`` or ``Channel`` object that the API may return
in response to certain methods, such as ``GetUsersRequest``.
To save bandwidth, the API also makes use of their "input" versions.
The input version of an entity (e.g. ``InputPeerUser``, ``InputChat``,
etc.) only contains the minimum required information that's required
for Telegram to be able to identify who you're referring to: their ID
and hash. This ID/hash pair is unique per user, so if you use the pair
given by another user **or bot** it will **not** work.
To save *even more* bandwidth, the API also makes use of the ``Peer``
versions, which just have an ID. This serves to identify them, but
peers alone are not enough to use them. You need to know their hash
before you can "use them".
Luckily, the library tries to simplify this mess the best it can.
Getting entities
****************
@ -58,8 +43,8 @@ you're able to just do this:
my_channel = client.get_entity(PeerChannel(some_id))
All methods in the :ref:`telegram-client` call ``.get_entity()`` to further
save you from the hassle of doing so manually, so doing things like
All methods in the :ref:`telegram-client` call ``.get_input_entity()`` to
further save you from the hassle of doing so manually, so doing things like
``client.send_message('lonami', 'hi!')`` is possible.
Every entity the library "sees" (in any response to any call) will by
@ -72,7 +57,27 @@ made to obtain the required information.
Entities vs. Input Entities
***************************
As we mentioned before, API calls don't need to know the whole information
.. note::
Don't worry if you don't understand this section, just remember some
of the details listed here are important. When you're calling a method,
don't call ``.get_entity()`` before, just use the username or phone,
or the entity retrieved by other means like ``.get_dialogs()``.
To save bandwidth, the API also makes use of their "input" versions.
The input version of an entity (e.g. ``InputPeerUser``, ``InputChat``,
etc.) only contains the minimum required information that's required
for Telegram to be able to identify who you're referring to: their ID
and hash. This ID/hash pair is unique per user, so if you use the pair
given by another user **or bot** it will **not** work.
To save *even more* bandwidth, the API also makes use of the ``Peer``
versions, which just have an ID. This serves to identify them, but
peers alone are not enough to use them. You need to know their hash
before you can "use them".
As we just mentioned, API calls don't need to know the whole information
about the entities, only their ID and hash. For this reason, another method,
``.get_input_entity()`` is available. This will always use the cache while
possible, making zero API calls most of the time. When a request is made,
@ -85,3 +90,15 @@ the most recent information about said entity, but invoking requests don't
need this information, just the ``InputPeer``. Only use ``.get_entity()``
if you need to get actual information, like the username, name, title, etc.
of the entity.
To further simplify the workflow, since the version ``0.16.2`` of the
library, the raw requests you make to the API are also able to call
``.get_input_entity`` wherever needed, so you can even do things like:
.. code-block:: python
client(SendMessageRequest('username', 'hello'))
The library will call the ``.resolve()`` method of the request, which will
resolve ``'username'`` with the appropriated ``InputPeer``. Don't worry if
you don't get this yet, but remember some of the details here are important.

View File

@ -1,7 +1,5 @@
.. Telethon documentation master file, created by
sphinx-quickstart on Fri Nov 17 15:36:11 2017.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
.. _getting-started:
===============
Getting Started
@ -39,13 +37,36 @@ Basic Usage
.. code-block:: python
print(me.stringify())
# Getting information about yourself
print(client.get_me().stringify())
client.send_message('username', 'Hello! Talking to you from Telethon')
# Sending a message (you can use 'me' or 'self' to message yourself)
client.send_message('username', 'Hello World from Telethon!')
# Sending a file
client.send_file('username', '/home/myself/Pictures/holidays.jpg')
client.download_profile_photo(me)
# Retrieving messages from a chat
from telethon import utils
for message in client.get_message_history('username', limit=10):
print(utils.get_display_name(message.sender), message.message)
# Listing all the dialogs (conversations you have open)
for dialog in client.get_dialogs(limit=10):
print(utils.get_display_name(dialog.entity), dialog.draft.message)
# Downloading profile photos (default path is the working directory)
client.download_profile_photo('username')
# Once you have a message with .media (if message.media)
# you can download it using client.download_media():
messages = client.get_message_history('username')
client.download_media(messages[0])
**More details**: :ref:`telegram-client`
----------
You can continue by clicking on the "More details" link below each
snippet of code or the "Next" button at the bottom of the page.

View File

@ -29,7 +29,9 @@ You can also install the library directly from GitHub or a fork:
$ cd Telethon/
# pip install -Ue .
If you don't have root access, simply pass the ``--user`` flag to the pip command.
If you don't have root access, simply pass the ``--user`` flag to the pip
command. If you want to install a specific branch, append ``@branch`` to
the end of the first install command.
Manual Installation
@ -49,7 +51,8 @@ Manual Installation
5. Done!
To generate the documentation, ``cd docs`` and then ``python3 generate.py``.
To generate the `method documentation`__, ``cd docs`` and then
``python3 generate.py`` (if some pages render bad do it twice).
Optional dependencies
@ -62,5 +65,6 @@ will also work without it.
__ https://github.com/ricmoo/pyaes
__ https://pypi.python.org/pypi/pyaes
__ https://github.com/sybrenstuvel/python-rsa/
__ https://github.com/sybrenstuvel/python-rsa
__ https://pypi.python.org/pypi/rsa/3.4.2
__ https://lonamiwebs.github.io/Telethon

View File

@ -43,30 +43,29 @@ how the library refers to either of these:
lonami = client.get_entity('lonami')
The so called "entities" are another important whole concept on its own,
and you should
Note that saving and using these entities will be more important when
Accessing the Full API. For now, this is a good way to get information
about an user or chat.
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.
Other common methods for quick scripts are also available:
Many other common methods for quick scripts are also available:
.. code-block:: python
# Sending a message (use an entity/username/etc)
client.send_message('TheAyyBot', 'ayy')
# Note that you can use 'me' or 'self' to message yourself
client.send_message('username', 'Hello World from Telethon!')
# Sending a photo, or a file
client.send_file(myself, '/path/to/the/file.jpg', force_document=True)
client.send_file('username', '/home/myself/Pictures/holidays.jpg')
# Downloading someone's profile photo. File is saved to 'where'
where = client.download_profile_photo(someone)
# The utils package has some goodies, like .get_display_name()
from telethon import utils
for message in client.get_message_history('username', limit=10):
print(utils.get_display_name(message.sender), message.message)
# Retrieving the message history
messages = client.get_message_history(someone)
# Dialogs are the conversations you have open
for dialog in client.get_dialogs(limit=10):
print(utils.get_display_name(dialog.entity), dialog.draft.message)
# Downloading the media from a specific message
# You can specify either a directory, a filename, or nothing at all
where = client.download_media(message, '/path/to/output')
# Default path is the working directory
client.download_profile_photo('username')
# Call .disconnect() when you're done
client.disconnect()

View File

@ -4,6 +4,12 @@
Working with Updates
====================
.. note::
There are plans to make working with updates more friendly. Stay tuned!
.. contents::

View File

@ -3,6 +3,11 @@ Bots
====
.. note::
These examples assume you have read :ref:`accessing-the-full-api`.
Talking to Inline Bots
**********************

View File

@ -3,6 +3,11 @@ Working with Chats and Channels
===============================
.. note::
These examples assume you have read :ref:`accessing-the-full-api`.
Joining a chat or channel
*************************

View File

@ -3,6 +3,11 @@ Working with messages
=====================
.. note::
These examples assume you have read :ref:`accessing-the-full-api`.
Forwarding messages
*******************

View File

@ -10,8 +10,12 @@ Welcome to Telethon's documentation!
Pure Python 3 Telegram client library.
Official Site `here <https://lonamiwebs.github.io/Telethon>`_.
Please follow the links below to get you started, and remember
to read the :ref:`changelog` when you upgrade!
Please follow the links on the index below to navigate from here,
or use the menu on the left. Remember to read the :ref:`changelog`
when you upgrade!
.. important::
If you're new here, you want to read :ref:`getting-started`.
What is this?
@ -85,19 +89,20 @@ heavy job for you, so you can focus on developing an application.
extra/developing/telegram-api-in-other-languages.rst
.. _Wall-of-shame:
.. _More:
.. toctree::
:maxdepth: 2
:caption: Wall of Shame
:caption: More
extra/changelog
extra/wall-of-shame.rst
.. toctree::
:caption: Telethon modules
telethon
modules
Indices and tables

View File

@ -42,6 +42,13 @@ telethon\.utils module
:undoc-members:
:show-inheritance:
telethon\.session module
------------------------
.. automodule:: telethon.session
:members:
:undoc-members:
:show-inheritance:
telethon\.cryto package
------------------------
@ -58,21 +65,21 @@ telethon\.errors package
telethon.errors
telethon\.extensions package
------------------------
----------------------------
.. toctree::
telethon.extensions
telethon\.network package
------------------------
-------------------------
.. toctree::
telethon.network
telethon\.tl package
------------------------
--------------------
.. toctree::

View File

@ -7,14 +7,6 @@ telethon\.tl package
telethon.tl.custom
telethon\.tl\.entity\_database module
-------------------------------------
.. automodule:: telethon.tl.entity_database
:members:
:undoc-members:
:show-inheritance:
telethon\.tl\.gzip\_packed module
---------------------------------
@ -31,14 +23,6 @@ telethon\.tl\.message\_container module
:undoc-members:
:show-inheritance:
telethon\.tl\.session module
----------------------------
.. automodule:: telethon.tl.session
:members:
:undoc-members:
:show-inheritance:
telethon\.tl\.tl\_message module
--------------------------------

View File

@ -406,7 +406,7 @@ class TelegramClient(TelegramBareClient):
def log_out(self):
"""
Logs out Telegram and deletes the current *.session file.
Logs out Telegram and deletes the current ``*.session`` file.
Returns:
True if the operation was successful.
@ -742,6 +742,10 @@ class TelegramClient(TelegramBareClient):
# Add a few extra attributes to the Message to make it friendlier.
messages.total = total_messages
for m in messages:
# To make messages more friendly, always add message
# to service messages, and action to normal messages.
m.message = getattr(m, 'message', None)
m.action = getattr(m, 'action', None)
m.sender = (None if not m.from_id else
entities[utils.get_peer_id(m.from_id)])

View File

@ -24,10 +24,7 @@ class Dialog:
self.unread_count = dialog.unread_count
self.unread_mentions_count = dialog.unread_mentions_count
if dialog.draft:
self.draft = Draft(client, dialog.peer, dialog.draft)
else:
self.draft = None
self.draft = Draft(client, dialog.peer, dialog.draft)
def send_message(self, *args, **kwargs):
"""

View File

@ -1,16 +1,18 @@
from ..functions.messages import SaveDraftRequest
from ..types import UpdateDraftMessage
from ..types import UpdateDraftMessage, DraftMessage
class Draft:
"""
Custom class that encapsulates a draft on the Telegram servers, providing
an abstraction to change the message conveniently. The library will return
instances of this class when calling `client.get_drafts()`.
instances of this class when calling ``client.get_drafts()``.
"""
def __init__(self, client, peer, draft):
self._client = client
self._peer = peer
if not draft:
draft = DraftMessage('', None, None, None, None)
self.text = draft.message
self.date = draft.date