2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-09-01 14:55:12 +00:00

Various improvements

This commit is contained in:
Dan
2022-01-07 10:18:51 +01:00
parent 80d0966691
commit 8c8288412f
135 changed files with 842 additions and 1422 deletions

View File

@@ -1,9 +1,8 @@
Advanced Usage
==============
Pyrogram's API, which consists of well documented convenience :doc:`methods <../api/methods/index>` and facade
:doc:`types <../api/types/index>`, exists to provide a much easier interface to the undocumented and often confusing
Telegram API.
Pyrogram's API -- which consists of well documented :doc:`methods <../api/methods/index>` and
:doc:`types <../api/types/index>` -- exists to provide an easier interface to the more complex Telegram API.
In this section, you'll be shown the alternative way of communicating with Telegram using Pyrogram: the main "raw"
Telegram API with its functions and types.
@@ -21,25 +20,18 @@ Telegram Raw API
If you can't find a high-level method for your needs or if you want complete, low-level access to the whole
Telegram API, you have to use the raw :mod:`~pyrogram.raw.functions` and :mod:`~pyrogram.raw.types`.
As already hinted, raw functions and types can be really confusing, mainly because people don't realize soon enough they
accept *only* the right types and that all required parameters must be filled in. This section will therefore explain
some pitfalls to take into consideration when working with the raw API.
As already hinted, raw functions and types can be less convenient. This section will therefore explain some pitfalls to
take into consideration when working with the raw API.
.. hint::
.. tip::
Every available high-level methods in Pyrogram is built on top of these raw functions.
Nothing stops you from using the raw functions only, but they are rather complex and
:doc:`plenty of them <../api/methods/index>` are already re-implemented by providing a much simpler and cleaner
interface which is very similar to the Bot API (yet much more powerful).
If you think a raw function should be wrapped and added as a high-level method, feel free to ask in our Community_!
Every available high-level method in Pyrogram is built on top of these raw functions.
Invoking Functions
^^^^^^^^^^^^^^^^^^
------------------
Unlike the :doc:`methods <../api/methods/index>` found in Pyrogram's API, which can be called in the usual simple way,
functions to be invoked from the raw Telegram API have a different way of usage and are more complex.
functions to be invoked from the raw Telegram API have a different way of usage.
First of all, both :doc:`raw functions <../telegram/functions/index>` and :doc:`raw types <../telegram/types/index>`
live in their respective packages (and sub-packages): ``pyrogram.raw.functions``, ``pyrogram.raw.types``. They all exist
@@ -61,12 +53,12 @@ Here's some examples:
with Client("my_account") as app:
app.send(
functions.account.UpdateProfile(
first_name="Dan", last_name="Tès",
about="Bio written from Pyrogram"
first_name="First Name", last_name="Last Name",
about="New bio text"
)
)
- Disable links to your account when someone forwards your messages:
- Set online/offline status:
.. code-block:: python
@@ -74,14 +66,13 @@ Here's some examples:
from pyrogram.raw import functions, types
with Client("my_account") as app:
app.send(
functions.account.SetPrivacy(
key=types.PrivacyKeyForwards(),
rules=[types.InputPrivacyValueDisallowAll()]
)
)
# Set online status
app.send(functions.account.UpdateStatus(offline=False))
- Invite users to your channel/supergroup:
# Set offline status
app.send(functions.account.UpdateStatus(offline=True))
- Get chat info:
.. code-block:: python
@@ -89,21 +80,18 @@ Here's some examples:
from pyrogram.raw import functions, types
with Client("my_account") as app:
app.send(
functions.channels.InviteToChannel(
channel=app.resolve_peer(123456789), # ID or Username
users=[ # The users you want to invite
app.resolve_peer(23456789), # By ID
app.resolve_peer("username"), # By username
app.resolve_peer("+393281234567"), # By phone number
]
r = app.send(
functions.channels.GetFullChannel(
channel=app.resolve_peer("username")
)
)
print(r)
Chat IDs
^^^^^^^^
--------
The way Telegram works makes it impossible to directly send a message to a user or a chat by using their IDs only.
The way Telegram works makes it not possible to directly send a message to a user or a chat by using their IDs only.
Instead, a pair of ``id`` and ``access_hash`` wrapped in a so called ``InputPeer`` is always needed. Pyrogram allows
sending messages with IDs only thanks to cached access hashes.
@@ -112,18 +100,17 @@ Whenever an InputPeer is needed you must pass one of these:
- :class:`~pyrogram.raw.types.InputPeerUser` - Users
- :class:`~pyrogram.raw.types.InputPeerChat` - Basic Chats
- :class:`~pyrogram.raw.types.InputPeerChannel` - Either Channels or Supergroups
- :class:`~pyrogram.raw.types.InputPeerChannel` - Channels & Supergroups
But you don't necessarily have to manually instantiate each object because, luckily for you, Pyrogram already provides
But you don't necessarily have to manually instantiate each object because Pyrogram already provides
:meth:`~pyrogram.Client.resolve_peer` as a convenience utility method that returns the correct InputPeer
by accepting a peer ID only.
Another thing to take into consideration about chat IDs is the way they are represented: they are all integers and
all positive within their respective raw types.
Things are different when working with Pyrogram's API because having them in the same space can theoretically lead to
collisions, and that's why Pyrogram (as well as the official Bot API) uses a slightly different representation for each
kind of ID.
Things are different when working with Pyrogram's API because having them in the same space could lead to
collisions, and that's why Pyrogram uses a slightly different representation for each kind of ID.
For example, given the ID *123456789*, here's how Pyrogram can tell entities apart:

View File

@@ -1,50 +0,0 @@
Bots Interaction
================
Users can interact with other bots via plain text messages as well as inline queries.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
Inline Bots
-----------
- If a bot accepts inline queries, you can call it by using
:meth:`~pyrogram.Client.get_inline_bot_results` to get the list of its inline results for a query:
.. code-block:: python
# Get bot results for "Fuzz Universe" from the inline bot @vid
bot_results = app.get_inline_bot_results("vid", "Fuzz Universe")
.. figure:: https://i.imgur.com/IAqLs54.png
:width: 90%
:align: center
:figwidth: 60%
``get_inline_bot_results()`` is the equivalent action of writing ``@vid Fuzz Universe`` and getting the
results list.
- After you retrieved the bot results, you can use
:meth:`~pyrogram.Client.send_inline_bot_result` to send a chosen result to any chat:
.. code-block:: python
# Send the first result to your own chat
app.send_inline_bot_result(
"me",
bot_results.query_id,
bot_results.results[0].id
)
.. figure:: https://i.imgur.com/wwxr7B7.png
:width: 90%
:align: center
:figwidth: 60%
``send_inline_bot_result()`` is the equivalent action of choosing a result from the list and sending it
to a chat.

View File

@@ -1,24 +1,12 @@
Session Settings
================
Client Settings
===============
As you may probably know, Telegram allows users (and bots) having more than one session (authorizations) registered
in the system at the same time.
You can control the way your client appears in the Active Sessions menu of an official client by changing some client
settings. By default you will see something like the following:
Briefly explaining, sessions are simply new logins in your account. They can be reviewed in the settings of an official
app (or by invoking :class:`~pyrogram.api.functions.account.GetAuthorizations` with Pyrogram). They
store some useful information such as the client who's using them and from which country and IP address.
.. figure:: https://i.imgur.com/YaqtMLO.png
:width: 600
:align: center
**A Pyrogram session running on Linux, Python 3.7.**
That's how a session looks like on the Android app, showing the three main pieces of information.
- ``app_version``: **Pyrogram 0.13.0**
- ``device_model``: **CPython 3.7.2**
- ``system_version``: **Linux 4.15.0-23-generic**
- Device Model: ``CPython x.y.z``
- Application: ``Pyrogram x.y.z``
- System Version: ``Linux x.y.z``
.. contents:: Contents
:backlinks: none

View File

@@ -15,7 +15,7 @@ Introduction
------------
The idea behind using a configuration file is to help keeping your code free of private settings information such as
the API Key and Proxy, without having you to even deal with how to load such settings. The configuration file, usually
the API Key and Proxy, without having you to deal with how to load such settings. The configuration file, usually
referred as ``config.ini`` file, is automatically loaded from the root of your working directory; all you need to do is
fill in the necessary parts.
@@ -23,7 +23,7 @@ fill in the necessary parts.
The configuration file is optional, but recommended. If, for any reason, you prefer not to use it, there's always an
alternative way to configure Pyrogram via Client's parameters. Doing so, you can have full control on how to store
and load your settings (e.g.: from environment variables).
and load your settings.
Settings specified via Client's parameter have higher priority and will override any setting stored in the
configuration file.

View File

@@ -87,7 +87,7 @@ Finally, the filter usage remains the same:
Filters with Arguments
----------------------
A much cooler filter would be one that accepts "pyrogram" or any other string as argument at usage time.
A more flexible filter would be one that accepts "pyrogram" or any other string as argument at usage time.
A dynamic filter like this will make use of named arguments for the :meth:`~pyrogram.filters.create` method and the
first argument of the callback function, which is a reference to the filter object itself holding the extra data passed
via named arguments.

View File

@@ -2,7 +2,7 @@ Debugging
=========
When working with the API, chances are you'll stumble upon bugs, get stuck and start wondering how to continue. Nothing
to actually worry about -- that's normal -- and luckily for you, Pyrogram provides some commodities to help you in this.
to actually worry about since Pyrogram provides some commodities to help you in this.
.. contents:: Contents
:backlinks: none
@@ -27,8 +27,8 @@ Consider the following code:
.. code-block:: python
dan = app.get_users("haskell")
print(dan) # User
me = app.get_users("me")
print(me) # User
This will show a JSON representation of the object returned by :meth:`~pyrogram.Client.get_users`, which is a
:class:`~pyrogram.types.User` instance, in this case. The output on your terminal will be something similar to this:
@@ -36,9 +36,9 @@ This will show a JSON representation of the object returned by :meth:`~pyrogram.
.. code-block:: json
{
"_": "pyrogram.User",
"id": 23122162,
"is_self": false,
"_": "User",
"id": 123456789,
"is_self": true,
"is_contact": false,
"is_mutual_contact": false,
"is_deleted": false,
@@ -46,19 +46,13 @@ This will show a JSON representation of the object returned by :meth:`~pyrogram.
"is_verified": false,
"is_restricted": false,
"is_support": false,
"is_scam": false,
"first_name": "Dan",
"status": {
"_": "pyrogram.UserStatus",
"user_id": 23122162,
"recently": true
},
"username": "haskell",
"language_code": "en",
"first_name": "Pyrogram",
"photo": {
"_": "pyrogram.ChatPhoto",
"small_file_id": "AQADBAAD8tBgAQAEJjCxGgAEo5IBAAIC",
"big_file_id": "AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg"
"_": "ChatPhoto",
"small_file_id": "AbCdE...EdCbA",
"small_photo_unique_id": "VwXyZ...ZyXwV",
"big_file_id": "AbCdE...EdCbA",
"big_photo_unique_id": "VwXyZ...ZyXwV"
}
}
@@ -69,37 +63,23 @@ Accessing Attributes
--------------------
Even though you see a JSON output, it doesn't mean we are dealing with dictionaries; in fact, all Pyrogram types are
full-fledged Python objects and the correct way to access any attribute of them is by using the dot notation ``.``:
fully-fledged Python objects and the correct way to access any attribute of them is by using the dot notation ``.``:
.. code-block:: python
dan_photo = dan.photo
print(dan_photo) # ChatPhoto
photo = me.photo
print(photo) # ChatPhoto
.. code-block:: json
{
"_": "pyrogram.ChatPhoto",
"small_file_id": "AQADBAAD8tBgAQAEJjCxGgAEo5IBAAIC",
"big_file_id": "AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg"
"_": "ChatPhoto",
"small_file_id": "AbCdE...EdCbA",
"small_photo_unique_id": "VwXyZ...ZyXwV",
"big_file_id": "AbCdE...EdCbA",
"big_photo_unique_id": "VwXyZ...ZyXwV"
}
However, the bracket notation ``[]`` is also supported, but its usage is discouraged:
.. warning::
Bracket notation in Python is not commonly used for getting/setting object attributes. While it works for Pyrogram
objects, it might not work for anything else and you should not rely on this.
.. code-block:: python
dan_photo_big = dan["photo"]["big_file_id"]
print(dan_photo_big) # str
.. code-block:: text
AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg
Checking an Object's Type
-------------------------
@@ -111,8 +91,8 @@ error. The correct way to get the object type is by using the built-in function
.. code-block:: python
dan_status = dan.status
print(type(dan_status))
status = me.status
print(type(status))
.. code-block:: text
@@ -125,8 +105,8 @@ And to check if an object is an instance of a given class, you use the built-in
from pyrogram.types import UserStatus
dan_status = dan.status
print(isinstance(dan_status, UserStatus))
status = me.status
print(isinstance(status, UserStatus))
.. code-block:: text

View File

@@ -24,7 +24,6 @@ group. Dispatching groups hold one or more handlers and are processed sequential
For example, take these two handlers:
.. code-block:: python
:emphasize-lines: 1, 6
@app.on_message(filters.text | filters.sticker)
def text_or_sticker(client, message):

View File

@@ -1,10 +1,10 @@
MTProto vs. Bot API
===================
Pyrogram is a framework that acts as a fully-fledged Telegram client based on MTProto, and this very feature makes it
already superior to, what is usually called, the official Bot API, in many respects. This page will therefore show you
why Pyrogram might be a better choice for your project by comparing the two APIs, but first, let's make it clear what
actually is the MTProto and the Bot API.
Pyrogram is a framework written from the ground up that acts as a fully-fledged Telegram client based on the MTProto
API. This means that Pyrogram is able to execute any official client and bot API action and more. This page will
therefore show you why Pyrogram might be a better choice for your project by comparing the two APIs, but first, let's
make it clear what actually is the MTProto and the Bot API.
.. contents:: Contents
:backlinks: none
@@ -19,10 +19,11 @@ What is the MTProto API?
`MTProto`_, took alone, is the name of the custom-made, open and encrypted communication protocol created by Telegram
itself --- it's the only protocol used to exchange information between a client and the actual Telegram servers.
The MTProto **API** on the other hand, is what people, for convenience, call the main Telegram API as a whole. This API
is able to authorize both users and bots and is built on top of the MTProto encryption protocol by means of
`binary data serialized`_ in a specific way, as described by the `TL language`_, and delivered using UDP, TCP or even
HTTP as transport-layer protocol.
The MTProto API on the other hand, is what people for convenience call the main Telegram API in order to distinguish it
from the Bot API. The main Telegram API is able to authorize both users and bots and is built on top of the MTProto
encryption protocol by means of `binary data serialized`_ in a specific way, as described by the `TL language`_, and
delivered using UDP, TCP or even HTTP as transport-layer protocol. Clients that make use of Telegram's main API, such as
Pyrogram, implement all these details.
.. _MTProto: https://core.telegram.org/mtproto
.. _binary data serialized: https://core.telegram.org/mtproto/serialize
@@ -31,12 +32,12 @@ HTTP as transport-layer protocol.
What is the Bot API?
--------------------
The `Bot API`_ is an HTTP(S) interface for building normal bots using a sub-set of the main MTProto API. Bots are special
accounts that are authorized via tokens instead of phone numbers. The Bot API is built yet again on top of the main
Telegram API, but runs on an intermediate server application that in turn communicates with the actual Telegram servers
using MTProto.
The `Bot API`_ is an HTTP(S) interface for building normal bots using a sub-set of the main Telegram API. Bots are
special accounts that are authorized via tokens instead of phone numbers. The Bot API is built yet again on top of the
main Telegram API, but runs on an intermediate server application that in turn communicates with the actual Telegram
servers using MTProto.
.. figure:: https://i.imgur.com/WvwBoZo.png
.. figure:: //_static/img/mtproto-vs-bot-api.png
:align: center
.. _Bot API: https://core.telegram.org/bots/api
@@ -44,8 +45,8 @@ using MTProto.
Advantages of the MTProto API
-----------------------------
Here is a list of all the advantages in using MTProto-based libraries -- such as Pyrogram -- instead of the official
HTTP Bot API. Using Pyrogram you can:
Here is a non-exhaustive list of all the advantages in using MTProto-based libraries -- such as Pyrogram -- instead of
the official HTTP Bot API. Using Pyrogram you can:
.. hlist::
:columns: 1
@@ -69,7 +70,7 @@ HTTP Bot API. Using Pyrogram you can:
.. hlist::
:columns: 1
- :guilabel:`+` **Run multiple sessions at once, up to 10 per account (either bot or user)**
- :guilabel:`+` **Run multiple sessions at once (for both user and bot identities)**
- :guilabel:`--` The Bot API intermediate server will terminate any other session in case you try to use the same
bot again in a parallel connection.

View File

@@ -14,8 +14,8 @@ non-asynchronous contexts. For more detailed information, you can visit and lear
-----
Using ``apscheduler``
---------------------
Using apscheduler
-----------------
- Install with ``pip3 install apscheduler``
- Documentation: https://apscheduler.readthedocs.io

View File

@@ -24,8 +24,7 @@ If you want a nicely formatted, human readable JSON representation of any object
...
with app:
r = app.get_chat("haskell")
r = app.get_chat("me")
print(str(r))
.. tip::
@@ -48,7 +47,7 @@ as the process requires the package to be in scope.
...
with app:
r = app.get_chat("haskell")
r = app.get_chat("me")
print(repr(r))
print(eval(repr(r)) == r) # True

View File

@@ -1,9 +1,9 @@
Smart Plugins
=============
Pyrogram embeds a **smart**, lightweight yet powerful plugin system that is meant to further simplify the organization
of large projects and to provide a way for creating pluggable (modular) components that can be **easily shared** across
different Pyrogram applications with **minimal boilerplate code**.
Pyrogram embeds a smart, lightweight yet powerful plugin system that is meant to further simplify the organization
of large projects and to provide a way for creating pluggable (modular) components that can be easily shared across
different Pyrogram applications with minimal boilerplate code.
.. tip::
@@ -74,8 +74,8 @@ after importing your modules, like this:
This is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to
manually ``import``, manually :meth:`~pyrogram.Client.add_handler` and manually instantiate each
:class:`~pyrogram.handlers.MessageHandler` object because **you can't use those cool decorators** for your
functions. So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically.
:class:`~pyrogram.handlers.MessageHandler` object because you can't use decorators for your functions.
So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically.
Using Smart Plugins
-------------------
@@ -91,7 +91,6 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
This is the same example application as shown above, written using the Smart Plugin system.
.. code-block:: text
:emphasize-lines: 2, 3
myproject/
plugins/
@@ -102,7 +101,6 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
- ``plugins/handlers.py``
.. code-block:: python
:emphasize-lines: 4, 9
from pyrogram import Client, filters
@@ -164,7 +162,7 @@ found inside each module will be, instead, loaded in the order they are defined,
.. note::
Remember: there can be at most one handler, within a group, dealing with a specific update. Plugins with overlapping
filters included a second time will not work. Learn more at :doc:`More on Updates <more-on-updates>`.
filters included a second time will not work, by design. Learn more at :doc:`More on Updates <more-on-updates>`.
This default loading behaviour is usually enough, but sometimes you want to have more control on what to include (or
exclude) and in which exact order to load plugins. The way to do this is to make use of ``include`` and ``exclude``
@@ -300,32 +298,30 @@ In the previous section we've explained how to specify which plugins to load and
starts. Here we'll show, instead, how to unload and load again a previously registered plugin at runtime.
Each function decorated with the usual ``on_message`` decorator (or any other decorator that deals with Telegram
updates) will be modified in such a way that a special ``handler`` attribute pointing to a tuple of
updates) will be modified in such a way that a special ``handlers`` attribute pointing to a list of tuples of
*(handler: Handler, group: int)* is attached to the function object itself.
- ``plugins/handlers.py``
.. code-block:: python
:emphasize-lines: 5, 6
@Client.on_message(filters.text & filters.private)
def echo(client, message):
message.reply(message.text)
print(echo)
print(echo.handler)
print(echo.handlers)
- Printing ``echo`` will show something like ``<function echo at 0x10e3b6598>``.
- Printing ``echo.handler`` will reveal the handler, that is, a tuple containing the actual handler and the group it
was registered on ``(<MessageHandler object at 0x10e3abc50>, 0)``.
- Printing ``echo.handlers`` will reveal the handlers, that is, a list of tuples containing the actual handlers and
the groups they were registered on ``[(<MessageHandler object at 0x10e3abc50>, 0)]``.
Unloading
^^^^^^^^^
In order to unload a plugin, all you need to do is obtain a reference to it by importing the relevant module and call
:meth:`~pyrogram.Client.remove_handler` Client's method with your function's *handler* special attribute preceded by the
star ``*`` operator as argument. Example:
:meth:`~pyrogram.Client.remove_handler` Client's method with your function's *handler* instance:
- ``main.py``
@@ -333,16 +329,19 @@ star ``*`` operator as argument. Example:
from plugins.handlers import echo
...
handlers = echo.handlers
app.remove_handler(*echo.handler)
for h in handlers:
app.remove_handler(*h)
The star ``*`` operator is used to unpack the tuple into positional arguments so that *remove_handler* will receive
exactly what is needed. The same could have been achieved with:
.. code-block:: python
handler, group = echo.handler
handlers = echo.handlers
handler, group = handlers[0]
app.remove_handler(handler, group)
Loading
@@ -359,4 +358,7 @@ using :meth:`~pyrogram.Client.add_handler` instead. Example:
...
app.add_handler(*echo.handler)
handlers = echo.handlers
for h in handlers:
app.add_handler(*h)

View File

@@ -18,28 +18,18 @@ Persisting Sessions
In order to make a client reconnect successfully between restarts, that is, without having to start a new
authorization process from scratch each time, Pyrogram needs to store the generated session data somewhere.
Other useful data being stored is peers' cache. In short, peers are all those entities you can chat with, such as users
or bots, basic groups, but also channels and supergroups. Because of how Telegram works, a unique pair of **id** and
**access_hash** is needed to contact a peer. This, plus other useful info such as the peer type, is what is stored
inside a session storage.
So, if you ever wondered how is Pyrogram able to contact peers just by asking for their ids, it's because of this very
reason: the peer *id* is looked up in the internal database and the available *access_hash* is retrieved, which is then
used to correctly invoke API methods.
Different Storage Engines
-------------------------
Let's now talk about how Pyrogram actually stores all the relevant data. Pyrogram offers two different types of storage
engines: a **File Storage** and a **Memory Storage**. These engines are well integrated in the library and require a
minimal effort to set up. Here's how they work:
Pyrogram offers two different types of storage engines: a **File Storage** and a **Memory Storage**.
These engines are well integrated in the framework and require a minimal effort to set up. Here's how they work:
File Storage
^^^^^^^^^^^^
This is the most common storage engine. It is implemented by using **SQLite**, which will store the session and peers
details. The database will be saved to disk as a single portable file and is designed to efficiently store and retrieve
peers whenever they are needed.
This is the most common storage engine. It is implemented by using **SQLite**, which will store the session details.
The database will be saved to disk as a single portable file and is designed to efficiently store and retrieve
data whenever they are needed.
To use this type of engine, simply pass any name of your choice to the ``session_name`` parameter of the
:obj:`~pyrogram.Client` constructor, as usual:
@@ -68,8 +58,8 @@ session name "**:memory:**" to the ``session_name`` parameter of the :obj:`~pyro
with Client(":memory:") as app:
print(app.get_me())
This storage engine is still backed by SQLite, but the database exists purely in memory. This means that, once you stop a
client, the entire database is discarded and the session details used for logging in again will be lost forever.
This storage engine is still backed by SQLite, but the database exists purely in memory. This means that, once you stop
a client, the entire database is discarded and the session details used for logging in again will be lost forever.
Session Strings
---------------
@@ -84,8 +74,8 @@ In case you want to use an in-memory storage, but also want to keep access to th
with Client(":memory:") as app:
print(app.export_session_string())
...and save the resulting (quite long) string somewhere. You can use this string as session name the next time you want
to login using the same session; the storage used will still be completely in-memory:
...and save the resulting string. You can use this string as session name the next time you want to login
using the same session; the storage used will still be in-memory:
.. code-block:: python
@@ -96,11 +86,5 @@ to login using the same session; the storage used will still be completely in-me
with Client(session_string) as app:
print(app.get_me())
Session strings are useful when you want to run authorized Pyrogram clients on platforms like
`Heroku <https://www.heroku.com/>`_, where their ephemeral filesystems makes it much harder for a file-based storage
engine to properly work as intended.
But, why is the session string so long? Can't it be shorter? No, it can't. The session string already packs the bare
minimum data Pyrogram needs to successfully reconnect to an authorized session, and the 2048-bits auth key is the major
contributor to the overall length. Needless to say that this string, as well as any other session storage, represent
strictly personal data. Keep them safe.
Session strings are useful when you want to run authorized Pyrogram clients on platforms where their ephemeral
filesystems makes it harder for a file-based storage engine to properly work as intended.

View File

@@ -15,8 +15,7 @@ Telegram's test servers without hassle. All you need to do is start a new sessio
.. note::
If this is the first time you login into test servers, you will be asked to register your account first.
Don't worry about your contacts and chats, they will be kept untouched inside the production environment;
accounts authorized on test servers reside in a different, parallel instance of a Telegram database.
Accounts registered on test servers reside in a different, parallel instance of a Telegram server.
.. contents:: Contents
:backlinks: none
@@ -28,19 +27,15 @@ Telegram's test servers without hassle. All you need to do is start a new sessio
Test Mode in Official Apps
--------------------------
You can also login yourself into test servers using official desktop apps, such as Webogram and TDesktop:
You can also login yourself into test servers using official desktop apps, such as Telegram Web and Telegram Desktop:
- **Webogram**: Login here: https://web.telegram.org/?test=1
- **TDesktop**: Hold ``Alt+Shift`` and right click on "Add account", then choose "Test server".
- **Telegram Web**: Login here: https://web.telegram.org/?test=1
- **Telegram Desktop**: Hold ``Alt+Shift`` and right click on "Add account", then choose "Test server".
Test Numbers
------------
Beside normal numbers, the test environment allows you to login with reserved test numbers.
Valid phone numbers follow the pattern ``99966XYYYY``, where ``X`` is the DC number (1 to 3) and ``YYYY`` are random
numbers. Users with such numbers always get ``XXXXX`` as the confirmation code (the DC number, repeated five times).
.. important::
Do not store any important or private information in such test users' accounts; anyone can make use of the
simplified authorization mechanism and login at any time.
numbers. Users with such numbers always get ``XXXXX`` or ``XXXXXX`` as the confirmation code (the DC number, repeated
five or six times).

View File

@@ -14,7 +14,7 @@ Text Formatting
:class: strike-italic
Pyrogram uses a custom Markdown dialect for text formatting which adds some unique features that make writing styled
texts easier in both Markdown and HTML. You can send sophisticated text messages and media captions using a great
texts easier in both Markdown and HTML. You can send sophisticated text messages and media captions using a
variety of decorations that can also be nested in order to combine multiple styles together.
.. contents:: Contents
@@ -36,7 +36,7 @@ list of the basic styles currently supported by Pyrogram.
- :underline:`underline`
- spoiler
- `text URL <https://pyrogram.org>`_
- `user text mention <https://t.me/haskell>`_
- `user text mention <tg://user?id=123456789>`_
- ``inline fixed-width code``
- .. code-block:: text
@@ -66,9 +66,9 @@ To strictly use this mode, pass "markdown" to the *parse_mode* parameter when us
||spoiler||
[text URL](https://docs.pyrogram.org/)
[text URL](https://pyrogram.org/)
[text user mention](tg://user?id=23122162)
[text user mention](tg://user?id=123456789)
`inline fixed-width code`
@@ -83,14 +83,13 @@ To strictly use this mode, pass "markdown" to the *parse_mode* parameter when us
.. code-block:: python
app.send_message(
"haskell",
"me",
(
"**bold**, "
"__italic__, "
"--underline--, "
"~~strike~~, "
"||spoiler||, "
"[mention](tg://user?id=23122162), "
"[URL](https://pyrogram.org), "
"`code`, "
"```"
@@ -119,9 +118,9 @@ The following tags are currently supported:
<spoiler>spoiler</spoiler>
<a href="http://docs.pyrogram.org/">text URL</a>
<a href="https://pyrogram.org/">text URL</a>
<a href="tg://user?id=23122162">inline mention</a>
<a href="tg://user?id=123456789">inline mention</a>
<code>inline fixed-width code</code>
@@ -136,14 +135,13 @@ The following tags are currently supported:
.. code-block:: python
app.send_message(
"haskell",
"me",
(
"<b>bold</b>, "
"<i>italic</i>, "
"<u>underline</u>, "
"<s>strike</s>, "
"<spoiler>spoiler</spoiler>, "
"<a href=\"tg://user?id=23122162\">mention</a>, "
"<a href=\"https://pyrogram.org/\">URL</a>, "
"<code>code</code>\n\n"
"<pre>"
@@ -181,7 +179,7 @@ This means you can combine together both syntaxes in the same text:
.. code-block:: python
app.send_message("haskell", "**bold**, <i>italic</i>")
app.send_message("me", "**bold**, <i>italic</i>")
Result:
@@ -192,8 +190,8 @@ If you don't like this behaviour you can always choose to only enable either Mar
.. code-block::
app.send_message("haskell", "**bold**, <i>italic</i>", parse_mode="markdown")
app.send_message("haskell", "**bold**, <i>italic</i>", parse_mode="html")
app.send_message("me", "**bold**, <i>italic</i>", parse_mode="markdown")
app.send_message("me", "**bold**, <i>italic</i>", parse_mode="html")
Result:
@@ -206,7 +204,7 @@ as-is.
.. code-block:: python
app.send_message("haskell", "**bold**, <i>italic</i>", parse_mode=None)
app.send_message("me", "**bold**, <i>italic</i>", parse_mode=None)
Result:

View File

@@ -1,11 +1,11 @@
Fast Crypto
===========
Pyrogram's speed can be *dramatically* boosted up by TgCrypto_, a high-performance, easy-to-install Telegram Crypto
Library specifically written in C for Pyrogram [1]_ as a Python extension.
Pyrogram's speed can be boosted up by TgCrypto_, a high-performance, easy-to-install cryptography library specifically
written in C for Pyrogram as a Python extension.
TgCrypto is a replacement for the much slower PyAES and implements the crypto algorithms Telegram requires, namely
**AES-IGE 256 bit** (used in MTProto v2.0) and **AES-CTR 256 bit** (used for CDN encrypted files).
TgCrypto is a replacement for a slower Python-only alternative and implements the cryptographic algorithms Telegram
requires, namely: AES-256-IGE, AES-256-CTR and AES-256-CBC.
Installation
------------
@@ -14,10 +14,10 @@ Installation
$ pip3 install -U tgcrypto
.. note:: Being a C extension for Python, TgCrypto is an optional but *highly recommended* dependency; when TgCrypto is
not detected in your system, Pyrogram will automatically fall back to PyAES and will show you a warning.
.. note:: When TgCrypto is not detected in your system, Pyrogram will automatically fall back to a slower Python-only
implementation and will show you a warning.
The reason about being an optional package is that TgCrypto requires some extra system tools in order to be compiled.
The reason about being an optional package is that TgCrypto requires extra system tools in order to be compiled.
The errors you receive when trying to install TgCrypto are system dependent, but also descriptive enough to understand
what you should do next:
@@ -26,7 +26,4 @@ what you should do next:
- **Linux**: Install a proper C compiler (``gcc``, ``clang``) and the Python header files (``python3-dev``).
- **Termux**: Install ``clang`` package.
.. _TgCrypto: https://github.com/pyrogram/tgcrypto
.. [1] Although TgCrypto is intended for Pyrogram, it is shipped as a standalone package and can thus be used for
other Python projects too.
.. _TgCrypto: https://github.com/pyrogram/tgcrypto

View File

@@ -19,16 +19,15 @@ Single Filters
Let's start right away with a simple example:
- This example will show you how to **only** handle messages containing an :class:`~pyrogram.Audio` object and
- This example will show you how to **only** handle messages containing a :class:`~pyrogram.types.Sticker` object and
ignore any other message. Filters are passed as the first argument of the decorator:
.. code-block:: python
:emphasize-lines: 4
from pyrogram import filters
@app.on_message(filters.audio)
@app.on_message(filters.sticker)
def my_handler(client, message):
print(message)
@@ -36,7 +35,6 @@ Let's start right away with a simple example:
callback function itself:
.. code-block:: python
:emphasize-lines: 9
from pyrogram import filters
from pyrogram.handlers import MessageHandler
@@ -46,12 +44,12 @@ Let's start right away with a simple example:
print(message)
app.add_handler(MessageHandler(my_handler, filters.audio))
app.add_handler(MessageHandler(my_handler, filters.sticker))
Combining Filters
-----------------
Filters can also be used in a more advanced way by inverting and combining more filters together using bitwise
Filters can be used in a more advanced way by inverting and combining more filters together using bitwise
operators ``~``, ``&`` and ``|``:
- Use ``~`` to invert a filter (behaves like the ``not`` operator).

View File

@@ -1,8 +1,8 @@
Voice Calls
===========
Both private voice calls and group voice calls are currently supported by third-party libraries that integrate with
Pyrogram.
Both private voice calls and group voice calls are currently supported by third-party, external libraries that integrate
with Pyrogram.
Libraries
---------