Update docs
This commit is contained in:
parent
5f087e5f82
commit
303712f599
2
compiler/docs/template/bound-methods.rst
vendored
2
compiler/docs/template/bound-methods.rst
vendored
@ -15,7 +15,7 @@ some of the required arguments.
|
|||||||
|
|
||||||
@app.on_message()
|
@app.on_message()
|
||||||
def hello(client, message)
|
def hello(client, message)
|
||||||
message.reply("hi")
|
message.reply_text("hi")
|
||||||
|
|
||||||
|
|
||||||
app.run()
|
app.run()
|
||||||
|
4
compiler/docs/template/types.rst
vendored
4
compiler/docs/template/types.rst
vendored
@ -1,12 +1,12 @@
|
|||||||
Available Types
|
Available Types
|
||||||
===============
|
===============
|
||||||
|
|
||||||
This page is about Pyrogram types. All types listed here are accessible through the main package directly.
|
This page is about Pyrogram types. All types listed here are accessible through ``types`` package.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 1
|
:emphasize-lines: 1
|
||||||
|
|
||||||
from pyrogram import User, Message, ...
|
from pyrogram.types import User, Message, ...
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ Handlers are used to instruct Pyrogram about which kind of updates you'd like to
|
|||||||
For a much more convenient way of registering callback functions have a look at :doc:`Decorators <decorators>` instead.
|
For a much more convenient way of registering callback functions have a look at :doc:`Decorators <decorators>` instead.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:emphasize-lines: 1, 10
|
:emphasize-lines: 2, 11
|
||||||
|
|
||||||
from pyrogram import Client
|
from pyrogram import Client
|
||||||
from pyrogram.handlers import MessageHandler
|
from pyrogram.handlers import MessageHandler
|
||||||
|
@ -40,12 +40,12 @@ Pyrogram is always evolving, although new releases on PyPI are published only wh
|
|||||||
doesn't mean you can't try new features right now!
|
doesn't mean you can't try new features right now!
|
||||||
|
|
||||||
In case you'd like to try out the latest Pyrogram features, the `GitHub repo`_ is always kept updated with new changes;
|
In case you'd like to try out the latest Pyrogram features, the `GitHub repo`_ is always kept updated with new changes;
|
||||||
you can install the development version straight from the ``develop`` branch using this command (note "develop.zip" in
|
you can install the development version straight from the ``master`` branch using this command (note "master.zip" in
|
||||||
the link):
|
the link):
|
||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: text
|
||||||
|
|
||||||
$ pip3 install -U https://github.com/pyrogram/pyrogram/archive/develop.zip
|
$ pip3 install -U https://github.com/pyrogram/pyrogram/archive/master.zip
|
||||||
|
|
||||||
Verifying
|
Verifying
|
||||||
---------
|
---------
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
Quick Start
|
Quick Start
|
||||||
===========
|
===========
|
||||||
|
|
||||||
The next few steps serve as a quick start for all new Pyrogrammers that want to see Pyrogram in action as fast as
|
The next few steps serve as a quick start for all new :term:`Pyrogrammers <Pyrogrammer>` that want to see Pyrogram in
|
||||||
possible. Let's go!
|
action as fast as possible. Let's go!
|
||||||
|
|
||||||
Get Pyrogram Real Fast
|
Get Pyrogram Real Fast
|
||||||
----------------------
|
----------------------
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Error Handling
|
Error Handling
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Errors are inevitable when working with the API, and they must be correctly handled with ``try..except`` blocks in order
|
Errors are inevitable when working with the API, and they can be correctly handled with ``try...except`` blocks in order
|
||||||
to control the behaviour of your application. Pyrogram errors all live inside the ``errors`` package:
|
to control the behaviour of your application. Pyrogram errors all live inside the ``errors`` package:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
@ -11,7 +11,8 @@ like send_audio(), send_document(), send_location(), etc...
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from pyrogram import Client, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
|
from pyrogram import Client
|
||||||
|
from pyrogram.types import ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
|
||||||
|
|
||||||
# Create a client using your bot token
|
# Create a client using your bot token
|
||||||
app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||||
|
@ -3,19 +3,19 @@ echobot
|
|||||||
|
|
||||||
This simple echo bot replies to every private text message.
|
This simple echo bot replies to every private text message.
|
||||||
|
|
||||||
It uses the @on_message decorator to register a MessageHandler and applies two filters on it:
|
It uses the ``@on_message`` decorator to register a ``MessageHandler`` and applies two filters on it:
|
||||||
Filters.text and Filters.private to make sure it will reply to private text messages only.
|
``filters.text`` and ``filters.private`` to make sure it will reply to private text messages only.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from pyrogram import Client, Filters
|
from pyrogram import Client, filters
|
||||||
|
|
||||||
app = Client("my_account")
|
app = Client("my_account")
|
||||||
|
|
||||||
|
|
||||||
@app.on_message(Filters.text & Filters.private)
|
@app.on_message(filters.text & filters.private)
|
||||||
def echo(client, message):
|
def echo(client, message):
|
||||||
message.reply(message.text)
|
message.reply_text(message.text)
|
||||||
|
|
||||||
|
|
||||||
app.run() # Automatically start() and idle()
|
app.run() # Automatically start() and idle()
|
@ -8,9 +8,9 @@ It uses the @on_inline_query decorator to register an InlineQueryHandler.
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from pyrogram import (
|
from pyrogram import Client
|
||||||
Client, InlineQueryResultArticle, InputTextMessageContent, InlineKeyboardMarkup, InlineKeyboardButton
|
from pyrogram.types import (InlineQueryResultArticle, InputTextMessageContent,
|
||||||
)
|
InlineKeyboardMarkup, InlineKeyboardButton)
|
||||||
|
|
||||||
app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||||
|
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
welcomebot
|
welcomebot
|
||||||
==========
|
==========
|
||||||
|
|
||||||
This is the Welcome Bot in @PyrogramChat.
|
This example uses the ``emoji`` module to easily add emoji in your text messages and ``filters``
|
||||||
|
|
||||||
It uses the Emoji module to easily add emojis in your text messages and Filters
|
|
||||||
to make it only work for specific messages in a specific chat.
|
to make it only work for specific messages in a specific chat.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from pyrogram import Client, Emoji, Filters
|
from pyrogram import Client, emoji, filters
|
||||||
|
|
||||||
TARGET = "PyrogramChat" # Target chat. Can also be a list of multiple chat ids/usernames
|
TARGET = "PyrogramChat" # Target chat. Can also be a list of multiple chat ids/usernames
|
||||||
MENTION = "[{}](tg://user?id={})" # User mention markup
|
MENTION = "[{}](tg://user?id={})" # User mention markup
|
||||||
@ -18,16 +16,16 @@ to make it only work for specific messages in a specific chat.
|
|||||||
|
|
||||||
|
|
||||||
# Filter in only new_chat_members updates generated in TARGET chat
|
# Filter in only new_chat_members updates generated in TARGET chat
|
||||||
@app.on_message(Filters.chat(TARGET) & Filters.new_chat_members)
|
@app.on_message(filters.chat(TARGET) & filters.new_chat_members)
|
||||||
def welcome(client, message):
|
def welcome(client, message):
|
||||||
# Build the new members list (with mentions) by using their first_name
|
# Build the new members list (with mentions) by using their first_name
|
||||||
new_members = [MENTION.format(i.first_name, i.id) for i in message.new_chat_members]
|
new_members = [u.mention for u in message.new_chat_members]
|
||||||
|
|
||||||
# Build the welcome message by using an emoji and the list we built above
|
# Build the welcome message by using an emoji and the list we built above
|
||||||
text = MESSAGE.format(Emoji.SPARKLES, ", ".join(new_members))
|
text = MESSAGE.format(emoji.SPARKLES, ", ".join(new_members))
|
||||||
|
|
||||||
# Send the welcome message, without the web page preview
|
# Send the welcome message, without the web page preview
|
||||||
message.reply(text, disable_web_page_preview=True)
|
message.reply_text(text, disable_web_page_preview=True)
|
||||||
|
|
||||||
|
|
||||||
app.run() # Automatically start() and idle()
|
app.run() # Automatically start() and idle()
|
@ -14,8 +14,7 @@ account; we are now aiming towards the core of the library. It's time to start p
|
|||||||
Basic Usage
|
Basic Usage
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Making API method calls with Pyrogram is very simple. Here's a basic example we are going to examine step by step and
|
Making API method calls with Pyrogram is very simple. Here's a basic example we are going to examine step by step:
|
||||||
then expand to explain what happens underneath:
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
@ -56,9 +55,9 @@ Basic step-by-step
|
|||||||
Context Manager
|
Context Manager
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
The ``with`` statement starts a context manager, which is used as a shortcut to automatically call
|
The ``with`` statement starts a context manager used as a shortcut to automatically call :meth:`~pyrogram.Client.start`
|
||||||
:meth:`~pyrogram.Client.start` and :meth:`~pyrogram.Client.stop`, which are methods required for Pyrogram to work
|
and :meth:`~pyrogram.Client.stop`, which are methods required for Pyrogram to work properly. The context manager does
|
||||||
properly. The context manager does also gracefully stop the client, even in case of unhandled exceptions in your code.
|
also gracefully stop the client, even in case of unhandled exceptions in your code.
|
||||||
|
|
||||||
This is how Pyrogram looks without the context manager:
|
This is how Pyrogram looks without the context manager:
|
||||||
|
|
||||||
@ -111,8 +110,8 @@ Asynchronous step-by-step
|
|||||||
async with app:
|
async with app:
|
||||||
await app.send_message("me", "Hi!")
|
await app.send_message("me", "Hi!")
|
||||||
|
|
||||||
#. Finally, we tell Python to schedule our ``main()`` async function, which in turn will execute Pyrogram's code. Using
|
#. Finally, we tell Python to schedule our ``main()`` async function, which in turn will execute Pyrogram's methods.
|
||||||
:meth:`~pyrogram.Client.run` this way is a friendly alternative for the much more verbose
|
Using :meth:`~pyrogram.Client.run` this way is a friendly alternative for the much more verbose
|
||||||
``asyncio.get_event_loop().run_until_complete(main())``:
|
``asyncio.get_event_loop().run_until_complete(main())``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
@ -26,8 +26,8 @@ Registering a Handler
|
|||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
To explain how handlers work let's examine the one which will be in charge for handling :class:`~pyrogram.types.Message`
|
To explain how handlers work let's examine the one which will be in charge for handling :class:`~pyrogram.types.Message`
|
||||||
updates coming from all around your chats. Every other handler shares the same setup logic; you should not have
|
updates coming from all around your chats. Every other kind of handler shares the same setup logic and you should not
|
||||||
troubles settings them up once you learn from this section.
|
have troubles settings them up once you learn from this section.
|
||||||
|
|
||||||
Using Decorators
|
Using Decorators
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
@ -98,3 +98,9 @@ The same about asynchronous handlers applies for :meth:`~pyrogram.Client.add_han
|
|||||||
|
|
||||||
async def my_function(client, message):
|
async def my_function(client, message):
|
||||||
await message.forward("me")
|
await message.forward("me")
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
From now on, you'll see examples using synchronous code (i.e.: without ``async`` and ``await``, unless when actually
|
||||||
|
relevant). This is done to keep snippets concise and more readable. Once you get the idea behind a feature, you can
|
||||||
|
easily turn examples asynchronous later on.
|
||||||
|
@ -2,7 +2,8 @@ Creating Filters
|
|||||||
================
|
================
|
||||||
|
|
||||||
Pyrogram already provides lots of built-in :class:`~pyrogram.filters` to work with, but in case you can't find a
|
Pyrogram already provides lots of built-in :class:`~pyrogram.filters` to work with, but in case you can't find a
|
||||||
specific one for your needs or want to build a custom filter by yourself you can use :meth:`~pyrogram.filters.create`.
|
specific one for your needs or want to build a custom filter by yourself you can use
|
||||||
|
:meth:`filters.create() <pyrogram.filters.create>`.
|
||||||
|
|
||||||
.. contents:: Contents
|
.. contents:: Contents
|
||||||
:backlinks: none
|
:backlinks: none
|
||||||
@ -37,29 +38,45 @@ Basic Filters
|
|||||||
|
|
||||||
For this basic filter we will be using only the first parameter of :meth:`~pyrogram.filters.create`.
|
For this basic filter we will be using only the first parameter of :meth:`~pyrogram.filters.create`.
|
||||||
|
|
||||||
The code below creates a simple filter for hardcoded, static callback data. This filter will only allow callback queries
|
The heart of a filter is its callback function, which accepts three arguments *(self, client, update)* and returns
|
||||||
containing "pyrogram" as data, that is, the function *func* you pass returns True in case the callback query data
|
either ``True``, in case you want the update to pass the filter or ``False`` otherwise.
|
||||||
equals to ``"pyrogram"``.
|
|
||||||
|
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
|
.. code-block:: python
|
||||||
|
|
||||||
from pyrogram import filters
|
from pyrogram import filters
|
||||||
|
|
||||||
static_data_filter = filters.create(lambda _, query: query.data == "pyrogram")
|
static_data_filter = filters.create(lambda _, __, query: query.data == "pyrogram")
|
||||||
|
|
||||||
The ``lambda`` operator in python is used to create small anonymous functions and is perfect for this example, the same
|
The first two arguments of the callback function are unused here and because of this we named them using underscores.
|
||||||
could be achieved with a normal function, but we don't really need it as it makes sense only inside the filter's scope:
|
|
||||||
|
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
|
.. code-block:: python
|
||||||
|
|
||||||
from pyrogram import filters
|
from pyrogram import filters
|
||||||
|
|
||||||
def func(_, query):
|
def func(_, __, query):
|
||||||
return query.data == "pyrogram"
|
return query.data == "pyrogram"
|
||||||
|
|
||||||
static_data_filter = filters.create(func)
|
static_data_filter = filters.create(func)
|
||||||
|
|
||||||
The filter usage remains the same:
|
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
|
||||||
|
|
||||||
|
async def func(_, __, query):
|
||||||
|
return query.data == "pyrogram"
|
||||||
|
|
||||||
|
static_data_filter = filters.create(func)
|
||||||
|
|
||||||
|
Finally, the filter usage remains the same:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
@ -70,8 +87,10 @@ The filter usage remains the same:
|
|||||||
Filters with Arguments
|
Filters with Arguments
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
A much cooler filter would be one that accepts "pyrogram" or any other data as argument at usage time.
|
A much cooler 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.
|
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.
|
||||||
|
|
||||||
This is how a dynamic custom filter looks like:
|
This is how a dynamic custom filter looks like:
|
||||||
|
|
||||||
@ -81,14 +100,52 @@ This is how a dynamic custom filter looks like:
|
|||||||
|
|
||||||
def dynamic_data_filter(data):
|
def dynamic_data_filter(data):
|
||||||
return filters.create(
|
return filters.create(
|
||||||
lambda flt, query: flt.data == query.data,
|
lambda flt, _, query: flt.data == query.data,
|
||||||
data=data # "data" kwarg is accessed with "flt.data" above
|
data=data # "data" kwarg is accessed with "flt.data" above
|
||||||
)
|
)
|
||||||
|
|
||||||
And its usage:
|
And its asynchronous variant:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from pyrogram import filters
|
||||||
|
|
||||||
|
def dynamic_data_filter(data):
|
||||||
|
async def func(flt, _, query):
|
||||||
|
return flt.data == query.data
|
||||||
|
|
||||||
|
# "data" kwarg is accessed with "flt.data" above
|
||||||
|
return filters.create(func, data=data)
|
||||||
|
|
||||||
|
And finally its usage:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
@app.on_callback_query(dynamic_data_filter("pyrogram"))
|
@app.on_callback_query(dynamic_data_filter("pyrogram"))
|
||||||
def pyrogram_data(_, query):
|
def pyrogram_data(_, query):
|
||||||
query.answer("it works!")
|
query.answer("it works!")
|
||||||
|
|
||||||
|
|
||||||
|
Method Calls Inside Filters
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
The missing piece we haven't covered yet is the second argument of a filter callback function, namely, the ``client``
|
||||||
|
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):
|
||||||
|
# r = await client.some_api_method()
|
||||||
|
# check response "r" and decide to return True or False
|
||||||
|
...
|
@ -58,7 +58,7 @@ class Client(Methods, Scaffold):
|
|||||||
session_name (``str``):
|
session_name (``str``):
|
||||||
Pass a string of your choice to give a name to the client session, e.g.: "*my_account*". This name will be
|
Pass a string of your choice to give a name to the client session, e.g.: "*my_account*". This name will be
|
||||||
used to save a file on disk that stores details needed to reconnect without asking again for credentials.
|
used to save a file on disk that stores details needed to reconnect without asking again for credentials.
|
||||||
Alternatively, if you don't want a file to be saved on disk, pass the special name "**:memory:**" to start
|
Alternatively, if you don't want a file to be saved on disk, pass the special name ``":memory:"`` to start
|
||||||
an in-memory session that will be discarded as soon as you stop the Client. In order to reconnect again
|
an in-memory session that will be discarded as soon as you stop the Client. In order to reconnect again
|
||||||
using a memory storage without having to login again, you can use
|
using a memory storage without having to login again, you can use
|
||||||
:meth:`~pyrogram.Client.export_session_string` before stopping the client to get a session string you can
|
:meth:`~pyrogram.Client.export_session_string` before stopping the client to get a session string you can
|
||||||
|
Loading…
Reference in New Issue
Block a user