Plugins ======= Pyrogram embeds an **automatic** and lightweight plugin system that is meant to greatly simplify the organization of large projects and to provide a way for creating pluggable components that can be **easily shared** across different Pyrogram applications with **minimal boilerplate code**. Introduction ------------ Prior to the plugin system, pluggable handlers were already possible. For instance, if you wanted to modularize your applications, you had to do something like this... .. note:: This is an example application that replies in private chats with two messages: one containing the same text message you sent and the other containing the reversed text message (e.g.: "pyrogram" -> "pyrogram" and "margoryp"): .. code-block:: text myproject/ config.ini handlers.py main.py - ``handlers.py`` .. code-block:: python def echo(client, message): message.reply(message.text) def echo_reversed(client, message): message.reply(message.text[::-1]) - ``main.py`` .. code-block:: python from pyrogram import Client, MessageHandler, Filters from handlers import echo, echo_reversed app = Client("my_account") app.add_handler( MessageHandler( echo, Filters.text & Filters.private)) app.add_handler( MessageHandler( echo_reversed, Filters.text & Filters.private), group=1) app.run() ...which is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to manually ``import``, manually :meth:`add_handler ` and manually instantiate each :obj:`MessageHandler ` object because **you can't use those cool decorators** for your functions. So... What if you could? Creating Plugins ---------------- Setting up your Pyrogram project to accommodate plugins is as easy as creating a folder and putting your files full of handlers inside. .. note:: This is the same example application `as shown above <#introduction>`_, written using the plugin system. .. code-block:: text :emphasize-lines: 2, 3 myproject/ plugins/ handlers.py config.ini main.py - ``plugins/handlers.py`` .. code-block:: python :emphasize-lines: 4, 9 from pyrogram import Client, Filters @Client.on_message(Filters.text & Filters.private) def echo(client, message): message.reply(message.text) @Client.on_message(Filters.text & Filters.private, group=1) def echo_reversed(client, message): message.reply(message.text[::-1]) - ``main.py`` .. code-block:: python from pyrogram import Client Client("my_account").run() The first important thing to note is the ``plugins`` folder, whose name is default and can be changed easily by setting the ``plugins_dir`` parameter when creating a :obj:`Client `; you can put any python file in the plugins folder and each file can contain any decorated function (handlers). Your Pyrogram Client instance (in the ``main.py`` file) will **automatically** scan the folder upon creation 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) instead of the usual ``@app`` (Client instance) namespace and things will work just the same. The ``main.py`` script is now at its bare minimum and cleanest state.