Skip to content

Commit c8e8fe0

Browse files
committed
Add Load/Unload Plugins at Runtime section in SmartPlugins.rst
1 parent 919894c commit c8e8fe0

File tree

1 file changed

+74
-8
lines changed

1 file changed

+74
-8
lines changed

docs/source/resources/SmartPlugins.rst

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ Introduction
1313
------------
1414

1515
Prior to the Smart Plugin system, pluggable handlers were already possible. For example, if you wanted to modularize
16-
your applications, you had to do something like this:
16+
your applications, you had to put your function definitions in separate files and register them inside your main script,
17+
like this:
1718

1819
.. note::
1920

@@ -66,15 +67,15 @@ your applications, you had to do something like this:
6667
This is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to
6768
manually ``import``, manually :meth:`add_handler <pyrogram.Client.add_handler>` and manually instantiate each
6869
:obj:`MessageHandler <pyrogram.MessageHandler>` object because **you can't use those cool decorators** for your
69-
functions. So... What if you could?
70+
functions. So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically.
7071

7172
Using Smart Plugins
7273
-------------------
7374

74-
Setting up your Pyrogram project to accommodate Smart Plugins is pretty straightforward:
75+
Setting up your Pyrogram project to accommodate Smart Plugins is straightforward:
7576

76-
#. Create a new folder to store all the plugins (e.g.: "plugins").
77-
#. Put your files full of plugins inside. Organize them as you wish.
77+
#. Create a new folder to store all the plugins (e.g.: "plugins", "handlers", ...).
78+
#. Put your python files full of plugins inside. Organize them as you wish.
7879
#. Enable plugins in your Client or via the *config.ini* file.
7980

8081
.. note::
@@ -160,7 +161,7 @@ found inside each module will be, instead, loaded in the order they are defined,
160161

161162
This default loading behaviour is usually enough, but sometimes you want to have more control on what to include (or
162163
exclude) and in which exact order to load plugins. The way to do this is to make use of ``include`` and ``exclude``
163-
keys, either in the *config.ini* or in the dictionary passed as Client argument. Here's how they work:
164+
keys, either in the *config.ini* file or in the dictionary passed as Client argument. Here's how they work:
164165

165166
- If both ``include`` and ``exclude`` are omitted, all plugins are loaded as described above.
166167
- If ``include`` is given, only the specified plugins will be loaded, in the order they are passed.
@@ -169,7 +170,7 @@ keys, either in the *config.ini* or in the dictionary passed as Client argument.
169170
The ``include`` and ``exclude`` value is a **list of strings**. Each string containing the path of the module relative
170171
to the plugins root folder, in Python notation (dots instead of slashes).
171172

172-
E.g.: ``subfolder.module`` refers to ``plugins/subfolder/module.py`` (root="plugins").
173+
E.g.: ``subfolder.module`` refers to ``plugins/subfolder/module.py``, with ``root="plugins"`.
173174
174175
You can also choose the order in which the single handlers inside a module are loaded, thus overriding the default
175176
top-to-bottom loading policy. You can do this by appending the name of the functions to the module path, each one
@@ -290,4 +291,69 @@ also organized in subfolders:
290291
Load/Unload Plugins at Runtime
291292
------------------------------
292293

293-
TODO
294+
In the `previous section <#specifying-the-plugins-to-include>`_ we've explained how to specify which plugins to load and
295+
which to ignore before your Client starts. Here we'll show, instead, how to unload and load again a previously
296+
registered plugins at runtime.
297+
298+
Each function decorated with the usual ``on_message`` decorator (or any other decorator that deals with Telegram updates
299+
) will be modified in such a way that, when you reference them later on, they will be actually pointing to a tuple of
300+
*(handler: Handler, group: int)*. The actual callback function is therefore stored inside the handler's *callback*
301+
attribute. Here's an example:
302+
303+
- ``plugins/handlers.py``
304+
305+
.. code-block:: python
306+
:emphasize-lines: 5, 6
307+
308+
@Client.on_message(Filters.text & Filters.private)
309+
def echo(client, message):
310+
message.reply(message.text)
311+
312+
print(echo)
313+
print(echo[0].callback)
314+
315+
- Printing ``echo`` will show something like ``(<MessageHandler object at 0x10e3abc50>, 0)``.
316+
317+
- Printing ``echo[0].callback``, that is, the *callback* attribute of the first eleent of the tuple, which is an
318+
Handler, will reveal the actual callback ``<function echo at 0x10e3b6598>``.
319+
320+
Unloading
321+
^^^^^^^^^
322+
323+
In order to unload a plugin, or any other handler, all you need to do is obtain a reference to it (by importing the
324+
relevant module) and call :meth:`remove_handler <pyrogram.Client.remove_handler>` Client's method with your function
325+
name preceded by the star ``*`` operator as argument. Example:
326+
327+
- ``main.py``
328+
329+
.. code-block:: python
330+
331+
from plugins.handlers import echo
332+
333+
...
334+
335+
app.remove_handler(*echo)
336+
337+
The star ``*`` operator is used to unpack the tuple into positional arguments so that *remove_handler* will receive
338+
exactly what is needed. The same could have been achieved with:
339+
340+
.. code-block:: python
341+
342+
handler, group = echo
343+
app.remove_handler(handler, group)
344+
345+
Loading
346+
^^^^^^^
347+
348+
Similarly to the unloading process, in order to load again a previously unloaded plugin you do the same, but this time
349+
using :meth:`add_handler <pyrogram.Client.add_handler>` instead. Example:
350+
351+
- ``main.py``
352+
353+
.. code-block:: python
354+
355+
from plugins.handlers import echo
356+
357+
...
358+
359+
app.add_handler(*echo)

0 commit comments

Comments
 (0)