2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-08-22 18:07:21 +00:00

Some fixes to the documentation

This commit is contained in:
Dan 2022-04-24 11:56:07 +02:00
parent 394a9adc03
commit 70d5f22e0d
15 changed files with 76 additions and 193 deletions

View File

@ -21,4 +21,4 @@ help:
lhtml: # live html
sphinx-autobuild --host $(shell ifconfig | grep "inet " | grep -v 127.0.0.1 | cut -d\ -f2) \
--watch ../pyrogram -b html "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS)
--watch ../pyrogram --watch resources -b html "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS)

View File

@ -50,7 +50,7 @@ Enjoy the API
That was just a quick overview. In the next few pages of the introduction, we'll take a much more in-depth look of what
we have just done above.
If you are feeling eager to continue you can take a shortcut to :doc:`Calling Methods <../start/invoking>` and come back
If you are feeling eager to continue you can take a shortcut to :doc:`Invoking Methods <../start/invoking>` and come back
later to learn some more details.
.. _community: https://t.me/Pyrogram

View File

@ -82,8 +82,8 @@ after the session name, which will be ``my_bot.session`` for the example below.
.. note::
The API key (api_id and api_hash) and the bot_token is not needed anymore after a successful authorization.
This means you can now simply use:
The API key (api_id and api_hash) and the bot_token are not required anymore after a successful authorization.
This means you can now simply use the following:
.. code-block:: python

View File

@ -25,7 +25,7 @@ This error is raised every time a method call against Telegram's API was unsucce
from pyrogram.errors import RPCError
.. note::
.. warning::
Avoid catching this error everywhere, especially when no feedback is given (i.e. by logging/printing the full error
traceback), because it makes it impossible to understand what went wrong.
@ -81,9 +81,6 @@ In case Pyrogram does not know anything about a specific error yet, it raises a
for example, an unknown error with error code ``400``, will be raised as a ``BadRequest``. This way you can catch the
whole category of errors and be sure to also handle these unknown errors.
In case a whole class of errors is unknown (that is, an error code that is unknown), Pyrogram will raise a special
``520 UnknownError`` exception.
Errors with Values
------------------

View File

@ -14,7 +14,7 @@ and how to handle new incoming messages or other events in Pyrogram.
Defining Updates
----------------
As hinted already, updates are events that happen in your Telegram account (incoming messages, new members join,
Updates are events that happen in your Telegram account (incoming messages, new members join,
bot button presses, etc.), which are meant to notify you about a new specific state that has changed. These updates are
handled by registering one or more callback functions in your app using :doc:`Handlers <../api/handlers>`.

View File

@ -50,8 +50,8 @@ Here's some examples:
from pyrogram import Client
from pyrogram.raw import functions
with Client("my_account") as app:
app.send(
async with Client("my_account") as app:
await app.send(
functions.account.UpdateProfile(
first_name="First Name", last_name="Last Name",
about="New bio text"
@ -65,12 +65,12 @@ Here's some examples:
from pyrogram import Client
from pyrogram.raw import functions, types
with Client("my_account") as app:
async with Client("my_account") as app:
# Set online status
app.send(functions.account.UpdateStatus(offline=False))
await app.send(functions.account.UpdateStatus(offline=False))
# Set offline status
app.send(functions.account.UpdateStatus(offline=True))
await app.send(functions.account.UpdateStatus(offline=True))
- Get chat info:
@ -79,8 +79,8 @@ Here's some examples:
from pyrogram import Client
from pyrogram.raw import functions, types
with Client("my_account") as app:
r = app.send(
async with Client("my_account") as app:
r = await app.send(
functions.channels.GetFullChannel(
channel=app.resolve_peer("username")
)

View File

@ -18,16 +18,7 @@ settings. By default you will see something like the following:
Set Custom Values
-----------------
To set custom values, you can either make use of the ``config.ini`` file, this way:
.. code-block:: ini
[pyrogram]
app_version = 1.2.3
device_model = PC
system_version = Linux
Or, pass the arguments directly in the Client's constructor.
To set custom values, you can pass the arguments directly in the Client's constructor.
.. code-block:: python
@ -47,11 +38,6 @@ English).
With the following code we make Telegram know we want it to speak in Italian (it):
.. code-block:: ini
[pyrogram]
lang_code = it
.. code-block:: python
app = Client(

View File

@ -25,7 +25,7 @@ button:
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
app.send_message(
await app.send_message(
"username", # Change this to your username or id
"Pyrogram custom filter test",
reply_markup=InlineKeyboardMarkup(
@ -44,29 +44,6 @@ either ``True``, in case you want the update to pass the filter or ``False`` oth
In this example we are matching the query data to "pyrogram", which means that the filter will only allow callback
queries containing "pyrogram" as data:
.. code-block:: python
from pyrogram import filters
static_data_filter = filters.create(lambda _, __, query: query.data == "pyrogram")
The first two arguments of the callback function are unused here and because of this we named them using underscores.
The ``lambda`` operator in python is used to create small anonymous functions and is perfect for this example. The same
can be achieved with a normal function, but we don't really need it as it makes sense only inside the filter's scope:
.. code-block:: python
from pyrogram import filters
def func(_, __, query):
return query.data == "pyrogram"
static_data_filter = filters.create(func)
Asynchronous filters are also possible. Sadly, Python itself doesn't have an ``async lambda``, so we are left with
using a named function:
.. code-block:: python
from pyrogram import filters
@ -76,12 +53,15 @@ using a named function:
static_data_filter = filters.create(func)
The first two arguments of the callback function are unused here and because of this we named them using underscores.
Finally, the filter usage remains the same:
.. code-block:: python
@app.on_callback_query(static_data_filter)
def pyrogram_data(_, query):
async def pyrogram_data(_, query):
query.answer("it works!")
Filters with Arguments
@ -94,18 +74,6 @@ via named arguments.
This is how a dynamic custom filter looks like:
.. code-block:: python
from pyrogram import filters
def dynamic_data_filter(data):
return filters.create(
lambda flt, _, query: flt.data == query.data,
data=data # "data" kwarg is accessed with "flt.data" above
)
And its asynchronous variant:
.. code-block:: python
from pyrogram import filters
@ -122,7 +90,7 @@ And finally its usage:
.. code-block:: python
@app.on_callback_query(dynamic_data_filter("pyrogram"))
def pyrogram_data(_, query):
async def pyrogram_data(_, query):
query.answer("it works!")
@ -133,16 +101,6 @@ The missing piece we haven't covered yet is the second argument of a filter call
argument. This is a reference to the :obj:`~pyrogram.Client` instance that is running the filter and it is useful in
case you would like to make some API calls before deciding whether the filter should allow the update or not:
.. code-block:: python
def func(_, client, query):
# r = client.some_api_method()
# check response "r" and decide to return True or False
...
Asynchronous filters making API calls work fine as well. Just remember that you need to put ``async`` in front of
function definitions and ``await`` in front of method calls:
.. code-block:: python
async def func(_, client, query):

View File

@ -27,7 +27,7 @@ Consider the following code:
.. code-block:: python
me = app.get_users("me")
me = await 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

View File

@ -26,12 +26,12 @@ For example, take these two handlers:
.. code-block:: python
@app.on_message(filters.text | filters.sticker)
def text_or_sticker(client, message):
async def text_or_sticker(client, message):
print("Text or Sticker")
@app.on_message(filters.text)
def just_text(client, message):
async def just_text(client, message):
print("Just Text")
Here, ``just_text`` is never executed because ``text_or_sticker``, which has been registered first, already handles
@ -40,7 +40,7 @@ texts (``filters.text`` is shared and conflicting). To enable it, register the h
.. code-block:: python
@app.on_message(filters.text, group=1)
def just_text(client, message):
async def just_text(client, message):
print("Just Text")
Or, if you want ``just_text`` to be executed *before* ``text_or_sticker`` (note ``-1``, which is less than ``0``):
@ -48,7 +48,7 @@ Or, if you want ``just_text`` to be executed *before* ``text_or_sticker`` (note
.. code-block:: python
@app.on_message(filters.text, group=-1)
def just_text(client, message):
async def just_text(client, message):
print("Just Text")
With :meth:`~pyrogram.Client.add_handler` (without decorators) the same can be achieved with:
@ -68,17 +68,17 @@ continue to propagate the same update to the next groups until all the handlers
.. code-block:: python
@app.on_message(filters.private)
def _(client, message):
async def _(client, message):
print(0)
@app.on_message(filters.private, group=1)
def _(client, message):
async def _(client, message):
raise Exception("Unhandled exception!") # Simulate an unhandled exception
@app.on_message(filters.private, group=2)
def _(client, message):
async def _(client, message):
print(2)
All these handlers will handle the same kind of messages, that are, messages sent or received in private chats.
@ -110,18 +110,18 @@ Example with ``stop_propagation()``:
.. code-block:: python
@app.on_message(filters.private)
def _(client, message):
async def _(client, message):
print(0)
@app.on_message(filters.private, group=1)
def _(client, message):
async def _(client, message):
print(1)
message.stop_propagation()
@app.on_message(filters.private, group=2)
def _(client, message):
async def _(client, message):
print(2)
Example with ``raise StopPropagation``:
@ -131,18 +131,18 @@ Example with ``raise StopPropagation``:
from pyrogram import StopPropagation
@app.on_message(filters.private)
def _(client, message):
async def _(client, message):
print(0)
@app.on_message(filters.private, group=1)
def _(client, message):
async ef _(client, message):
print(1)
raise StopPropagation
@app.on_message(filters.private, group=2)
def _(client, message):
async def _(client, message):
print(2)
Each handler is registered in a different group, but the handler in group number 2 will never be executed because the
@ -178,19 +178,19 @@ Example with ``continue_propagation()``:
.. code-block:: python
@app.on_message(filters.private)
def _(client, message):
async def _(client, message):
print(0)
message.continue_propagation()
@app.on_message(filters.private)
def _(client, message):
async def _(client, message):
print(1)
message.continue_propagation()
@app.on_message(filters.private)
def _(client, message):
async def _(client, message):
print(2)
Example with ``raise ContinuePropagation``:
@ -200,19 +200,19 @@ Example with ``raise ContinuePropagation``:
from pyrogram import ContinuePropagation
@app.on_message(filters.private)
def _(client, message):
async def _(client, message):
print(0)
raise ContinuePropagation
@app.on_message(filters.private)
def _(client, message):
async def _(client, message):
print(1)
raise ContinuePropagation
@app.on_message(filters.private)
def _(client, message):
async def _(client, message):
print(2)
Three handlers are registered in the same group, and all of them will be executed because the propagation was continued

View File

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

View File

@ -33,7 +33,6 @@ after importing your modules, like this:
.. code-block:: text
myproject/
config.ini
handlers.py
main.py
@ -41,12 +40,12 @@ after importing your modules, like this:
.. code-block:: python
def echo(client, message):
message.reply(message.text)
async def echo(client, message):
await message.reply(message.text)
def echo_reversed(client, message):
message.reply(message.text[::-1])
async def echo_reversed(client, message):
await message.reply(message.text[::-1])
- ``main.py``
@ -84,7 +83,7 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
#. Create a new folder to store all the plugins (e.g.: "plugins", "handlers", ...).
#. Put your python files full of plugins inside. Organize them as you wish.
#. Enable plugins in your Client or via the *config.ini* file.
#. Enable plugins in your Client.
.. note::
@ -95,7 +94,6 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
myproject/
plugins/
handlers.py
config.ini
main.py
- ``plugins/handlers.py``
@ -106,31 +104,16 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
@Client.on_message(filters.text & filters.private)
def echo(client, message):
message.reply(message.text)
async def echo(client, message):
await message.reply(message.text)
@Client.on_message(filters.text & filters.private, group=1)
def echo_reversed(client, message):
message.reply(message.text[::-1])
- ``config.ini``
.. code-block:: ini
[plugins]
root = plugins
async def echo_reversed(client, message):
await message.reply(message.text[::-1])
- ``main.py``
.. code-block:: python
from pyrogram import Client
Client("my_account").run()
Alternatively, without using the *config.ini* file:
.. code-block:: python
from pyrogram import Client
@ -144,9 +127,9 @@ The first important thing to note is the new ``plugins`` folder. You can put *an
each file can contain *any decorated function* (handlers) with one limitation: within a single module (file) you must
use different names for each decorated function.
The second thing is telling Pyrogram where to look for your plugins: you can either use the *config.ini* file or
the Client parameter "plugins"; the *root* value must match the name of your plugins root folder. Your Pyrogram Client
instance will **automatically** scan the folder upon starting to search for valid handlers and register them for you.
The second thing is telling Pyrogram where to look for your plugins: you can use the Client parameter "plugins";
the *root* value must match the name of your plugins root folder. Your Pyrogram Client instance will **automatically**
scan the folder upon starting to search for valid handlers and register them for you.
Then you'll notice you can now use decorators. That's right, you can apply the usual decorators to your callback
functions in a static way, i.e. **without having the Client instance around**: simply use ``@Client`` (Client class)
@ -166,7 +149,7 @@ found inside each module will be, instead, loaded in the order they are defined,
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``
directives, either in the *config.ini* file or in the dictionary passed as Client argument. Here's how they work:
directives in the dictionary passed as Client argument. Here's how they work:
- If both ``include`` and ``exclude`` are omitted, all plugins are loaded as described above.
- If ``include`` is given, only the specified plugins will be loaded, in the order they are passed.
@ -208,15 +191,6 @@ also organized in subfolders:
- Load every handler from every module, namely *plugins0.py*, *plugins1.py* and *plugins2.py* in alphabetical order
(files) and definition order (handlers inside files):
Using *config.ini* file:
.. code-block:: ini
[plugins]
root = plugins
Using *Client*'s parameter:
.. code-block:: python
plugins = dict(root="plugins")
@ -225,18 +199,6 @@ also organized in subfolders:
- Load only handlers defined inside *plugins2.py* and *plugins0.py*, in this order:
Using *config.ini* file:
.. code-block:: ini
[plugins]
root = plugins
include =
subfolder2.plugins2
plugins0
Using *Client*'s parameter:
.. code-block:: python
plugins = dict(
@ -251,16 +213,6 @@ also organized in subfolders:
- Load everything except the handlers inside *plugins2.py*:
Using *config.ini* file:
.. code-block:: ini
[plugins]
root = plugins
exclude = subfolder2.plugins2
Using *Client*'s parameter:
.. code-block:: python
plugins = dict(
@ -272,16 +224,6 @@ also organized in subfolders:
- Load only *fn3*, *fn1* and *fn2* (in this order) from *plugins1.py*:
Using *config.ini* file:
.. code-block:: ini
[plugins]
root = plugins
include = subfolder1.plugins1 fn3 fn1 fn2
Using *Client*'s parameter:
.. code-block:: python
plugins = dict(
@ -306,8 +248,8 @@ updates) will be modified in such a way that a special ``handlers`` attribute po
.. code-block:: python
@Client.on_message(filters.text & filters.private)
def echo(client, message):
message.reply(message.text)
async def echo(client, message):
await message.reply(message.text)
print(echo)
print(echo.handlers)

View File

@ -9,8 +9,8 @@ Telegram's test servers without hassle. All you need to do is start a new sessio
from pyrogram import Client
with Client("my_account_test", test_mode=True) as app:
print(app.get_me())
async with Client("my_account_test", test_mode=True) as app:
print(await app.get_me())
.. note::

View File

@ -80,7 +80,7 @@ To strictly use this mode, pass :obj:`~pyrogram.enums.ParseMode.MARKDOWN` to the
from pyrogram import enums
app.send_message(
await app.send_message(
"me",
(
"**bold**, "
@ -134,7 +134,7 @@ To strictly use this mode, pass :obj:`~pyrogram.enums.HTML` to the *parse_mode*
from pyrogram import enums
app.send_message(
await app.send_message(
"me",
(
"<b>bold</b>, "
@ -179,7 +179,7 @@ This means you can combine together both syntaxes in the same text:
.. code-block:: python
app.send_message("me", "**bold**, <i>italic</i>")
await app.send_message("me", "**bold**, <i>italic</i>")
Result:
@ -192,8 +192,8 @@ If you don't like this behaviour you can always choose to only enable either Mar
from pyrogram import enums
app.send_message("me", "**bold**, <i>italic</i>", parse_mode=enums.ParseMode.MARKDOWN)
app.send_message("me", "**bold**, <i>italic</i>", parse_mode=enums.ParseMode.HTML)
await app.send_message("me", "**bold**, <i>italic</i>", parse_mode=enums.ParseMode.MARKDOWN)
await app.send_message("me", "**bold**, <i>italic</i>", parse_mode=enums.ParseMode.HTML)
Result:
@ -208,7 +208,7 @@ The text will be sent as-is.
from pyrogram import enums
app.send_message("me", "**bold**, <i>italic</i>", parse_mode=enums.ParseMode.DISABLED)
await app.send_message("me", "**bold**, <i>italic</i>", parse_mode=enums.ParseMode.DISABLED)
Result:

View File

@ -28,7 +28,7 @@ Let's start right away with a simple example:
@app.on_message(filters.sticker)
def my_handler(client, message):
async def my_handler(client, message):
print(message)
- or, without decorators. Here filters are passed as the second argument of the handler constructor; the first is the
@ -40,7 +40,7 @@ Let's start right away with a simple example:
from pyrogram.handlers import MessageHandler
def my_handler(client, message):
async def my_handler(client, message):
print(message)
@ -62,7 +62,7 @@ Here are some examples:
.. code-block:: python
@app.on_message(filters.text | filters.photo)
def my_handler(client, message):
async def my_handler(client, message):
print(message)
- Message is a **sticker** **and** is coming from a **channel or** a **private** chat.
@ -70,7 +70,7 @@ Here are some examples:
.. code-block:: python
@app.on_message(filters.sticker & (filters.channel | filters.private))
def my_handler(client, message):
async def my_handler(client, message):
print(message)
Advanced Filters
@ -84,7 +84,7 @@ can also accept arguments:
.. code-block:: python
@app.on_message(filters.command(["start", "help"]))
def my_handler(client, message):
async def my_handler(client, message):
print(message)
- Message is a **text** message or a media **caption** matching the given **regex** pattern.
@ -92,7 +92,7 @@ can also accept arguments:
.. code-block:: python
@app.on_message(filters.regex("pyrogram"))
def my_handler(client, message):
async def my_handler(client, message):
print(message)
More handlers using different filters can also live together.
@ -100,15 +100,15 @@ More handlers using different filters can also live together.
.. code-block:: python
@app.on_message(filters.command("start"))
def start_command(client, message):
async def start_command(client, message):
print("This is the /start command")
@app.on_message(filters.command("help"))
def help_command(client, message):
async def help_command(client, message):
print("This is the /help command")
@app.on_message(filters.chat("PyrogramChat"))
def from_pyrogramchat(client, message):
async def from_pyrogramchat(client, message):
print("New message in @PyrogramChat")