Skip to content

Commit

Permalink
Several documentation enhancements and build warnings fixes
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
Lonami committed Jan 20, 2018
1 parent 4d4e81e commit b716c4f
Show file tree
Hide file tree
Showing 18 changed files with 180 additions and 141 deletions.
78 changes: 18 additions & 60 deletions docs/res/core.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,15 @@ <h1>Telethon API</h1>
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>
Expand All @@ -69,12 +76,12 @@ <h3 id="methods">Methods</h3>
<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
Expand Down Expand Up @@ -151,58 +158,9 @@ <h3 id="core">Core types</h3>
</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>
Expand Down
12 changes: 10 additions & 2 deletions readthedocs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 ------------------------------------------------
Expand Down Expand Up @@ -55,9 +60,12 @@
# 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.
Expand Down
18 changes: 14 additions & 4 deletions readthedocs/extra/advanced-usage/accessing-the-full-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions readthedocs/extra/basic/creating-a-client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`__
Expand Down
53 changes: 35 additions & 18 deletions readthedocs/extra/basic/entities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
****************

Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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.
35 changes: 28 additions & 7 deletions readthedocs/extra/basic/getting-started.rst
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -39,13 +37,36 @@ Basic Usage

.. code-block:: python
print(me.stringify())
# Getting information about yourself
print(client.get_me().stringify())
# Sending a message (you can use 'me' or 'self' to message yourself)
client.send_message('username', 'Hello World from Telethon!')
client.send_message('username', 'Hello! Talking to you 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.
10 changes: 7 additions & 3 deletions readthedocs/extra/basic/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
31 changes: 15 additions & 16 deletions readthedocs/extra/basic/telegram-client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
6 changes: 6 additions & 0 deletions readthedocs/extra/basic/working-with-updates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
Working with Updates
====================


.. note::

There are plans to make working with updates more friendly. Stay tuned!


.. contents::


Expand Down

0 comments on commit b716c4f

Please sign in to comment.