@@ -13,7 +13,8 @@ Introduction
1313------------
1414
1515Prior 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
6768manually ``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
7172Using 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
161162This default loading behaviour is usually enough, but sometimes you want to have more control on what to include (or
162163exclude) 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.
169170The ``include `` and ``exclude `` value is a **list of strings **. Each string containing the path of the module relative
170171to 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
174175You can also choose the order in which the single handlers inside a module are loaded, thus overriding the default
175176top-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