sopel.plugins.handlers#
Sopel’s plugin handlers.
New in version 7.0.
Between a plugin (or “module”) and Sopel’s core, Plugin Handlers are used. It
is an interface (defined by the AbstractPluginHandler abstract class),
that acts as a proxy between Sopel and the plugin, making a clear separation
between how the bot behaves and how the plugins work.
From the Sopel class, a plugin must be:
- loaded, using - load()
- setup (if required), using - setup()
- and eventually registered using - register()
Each subclass of AbstractPluginHandler must implement its methods in
order to be used in the application.
At the moment, three types of plugin are handled:
- PyModulePlugin: manages plugins that can be imported as Python module from a Python package, i.e. where- from package import nameworks
- PyFilePlugin: manages plugins that are Python files on the filesystem or Python directory (with an- __init__.pyfile inside), that cannot be directly imported and extra steps are necessary
- EntryPointPlugin: manages plugins that are declared by an entry point; it otherwise behaves like a- PyModulePlugin
All expose the same interface and thereby abstract the internal implementation away from the rest of the application.
Important
This is all relatively new. Its usage and documentation is for Sopel core development and advanced developers. It is subject to rapid changes between versions without much (or any) warning.
Do not build your plugin based on what is here, you do not need to.
- class sopel.plugins.handlers.AbstractPluginHandler#
- Base class for plugin handlers. - This abstract class defines the interface Sopel uses to configure, load, shutdown, etc. a Sopel plugin (or “module”). - It is through this interface that Sopel will interact with its plugins, whether internal (from - sopel.modules) or external (from the Python files in a directory, to- sopel_modules.*subpackages).- Sopel’s loader will create a “Plugin Handler” for each plugin it finds, to which it then delegates loading the plugin, listing its functions (commands, jobs, etc.), configuring it, and running any required actions on shutdown (either upon exiting Sopel or unloading that plugin). - abstract configure(settings)#
- Configure Sopel’s - settingsfor this plugin.- Parameters:
- settings ( - sopel.config.Config) – Sopel’s configuration
 - This method will be called by Sopel’s configuration wizard. 
 - abstract get_capability_requests() list[plugin_decorators.capability]#
- Retrieve the plugin’s list of capability requests. 
 - abstract get_label() str#
- Retrieve a display label for the plugin. - Returns:
- a human readable label for display purpose 
- Return type:
 - This method should, at least, return - <module_name> plugin.
 - abstract get_meta_description() PluginMetaDescription#
- Retrieve a meta description for the plugin. - Returns:
- Metadata about the plugin 
- Return type:
 - The expected keys are detailed in - PluginMetaDescription.
 - abstract get_version()#
- Retrieve the plugin’s version. - Returns:
- the plugin’s version string 
- Return type:
 
 - abstract has_configure() bool#
- Tell if the plugin has a configure action. - Returns:
- Trueif the plugin has a- configureaction,- Falseotherwise
- Return type:
 
 - abstract has_setup() bool#
- Tell if the plugin has a setup action. - Returns:
- Trueif the plugin has a setup,- Falseotherwise
- Return type:
 
 - abstract has_shutdown() bool#
- Tell if the plugin has a shutdown action. - Returns:
- Trueif the plugin has a- shutdownaction,- Falseotherwise
- Return type:
 
 - abstract is_loaded() bool#
- Tell if the plugin is loaded or not. - Returns:
- Trueif the plugin is loaded,- Falseotherwise
- Return type:
 - This must return - Trueif the- load()method has been called with success.
 - abstract load()#
- Load the plugin. - This method must be called first, in order to setup, register, shutdown, or configure the plugin later. 
 - abstract register(bot)#
- Register the plugin with the - bot.- Parameters:
- bot ( - sopel.bot.Sopel) – instance of Sopel
 
 - abstract reload()#
- Reload the plugin. - This method can be called once the plugin is already loaded. It will take care of reloading the plugin from its source. 
 - abstract setup(bot)#
- Run the plugin’s setup action. - Parameters:
- bot ( - sopel.bot.Sopel) – instance of Sopel
 
 - abstract shutdown(bot)#
- Run the plugin’s shutdown action. - Parameters:
- bot ( - sopel.bot.Sopel) – instance of Sopel
 
 - abstract unregister(bot)#
- Unregister the plugin from the - bot.- Parameters:
- bot ( - sopel.bot.Sopel) – instance of Sopel
 
 
- class sopel.plugins.handlers.EntryPointPlugin(entry_point)#
- Sopel plugin loaded from an entry point. - Parameters:
- entry_point – an entry point object 
 - This handler loads a Sopel plugin exposed by a package’s entry point. It expects to be able to load a module object from the entry point, and to work as a - PyModulePluginfrom that module.- By default, Sopel searches within the entry point group - sopel.plugins. To use that for their own plugins, developers must define an entry point either in their- setup.pyfile or their- setup.cfgfile:- # in setup.py file setup( name='my_plugin', version='1.0', entry_points={ 'sopel.plugins': [ 'custom = my_plugin.path.to.plugin', ], } ) - And this plugin can be loaded with: - >>> from importlib_metadata import entry_points >>> from sopel.plugins.handlers import EntryPointPlugin >>> plugin = [ ... EntryPointPlugin(ep) ... for ep in entry_points(group='sopel.plugins', name='custom') ... ][0] >>> plugin.load() >>> plugin.name 'custom' - In this example, the plugin - customis loaded from an entry point. Unlike the- PyModulePlugin, the name is not derived from the actual Python module, but from its entry point’s name.- See also - Sopel uses the - find_entry_point_plugins()function internally to search entry points.- Entry points are a standard packaging mechanism for Python, used by other applications (such as - pytest) for their plugins.- The - importlib_metadatabackport package is used for consistency across all of Sopel’s supported Python versions. Its API matches that of- importlib.metadatafrom Python 3.10 and up; Sopel will drop this external requirement when practical.- PLUGIN_TYPE = 'setup-entrypoint'#
- The plugin’s type. - Metadata for the plugin; this should be considered to be a constant and should not be modified at runtime. 
 - get_meta_description() PluginMetaDescription#
- Retrieve a meta description for the plugin. - Returns:
- Metadata about the plugin 
- Return type:
 - The expected keys are detailed in - PluginMetaDescription.- This implementation uses its entry point definition as the - sourcevalue:- { 'name': 'example', 'type': 'setup-entrypoint', 'label': 'example plugin', 'source': 'example = my_plugin.example', 'version': '3.1.2', } 
 - get_version() str | None#
- Retrieve the plugin’s version. - Returns:
- the plugin’s version string 
- Return type:
- Optional[str] 
 
 - load()#
- Load the plugin’s module using - importlib.import_module().- This method assumes the module is available through - sys.path.
 
- class sopel.plugins.handlers.PluginMetaDescription(*args, **kwargs)#
- Meta description of a plugin, as a dictionary. - This dictionary is expected to contain specific keys: - name: a short name for the plugin 
- label: a descriptive label for the plugin; see - get_label()
- type: the plugin’s type 
- source: the plugin’s source (filesystem path, python module/import path, etc.) 
- version: the plugin’s version string if available, otherwise - None
 
- class sopel.plugins.handlers.PyFilePlugin(filename)#
- Sopel plugin loaded from the filesystem outside of the Python path. - This plugin handler can be used to load a Sopel plugin from the filesystem, either a Python - .pyfile or a directory containing an- __init__.pyfile, and behaves like a- PyModulePlugin:- >>> from sopel.plugins.handlers import PyFilePlugin >>> plugin = PyFilePlugin('/home/sopel/.sopel/plugins/custom.py') >>> plugin.load() >>> plugin.name 'custom' - In this example, the plugin - customis loaded from its filename despite not being in the Python path.- PLUGIN_TYPE = 'python-file'#
- The plugin’s type. - Metadata for the plugin; this should be considered to be a constant and should not be modified at runtime. 
 - get_meta_description() PluginMetaDescription#
- Retrieve a meta description for the plugin. - Returns:
- Metadata about the plugin 
- Return type:
 - The expected keys are detailed in - PluginMetaDescription.- This implementation uses its source file’s path as the - sourcevalue:- { 'name': 'example', 'type': 'python-file', 'label': 'example plugin', 'source': '/home/username/.sopel/plugins/example.py', 'version': '3.1.2', } 
 - load()#
- Load the plugin’s module using - importlib.import_module().- This method assumes the module is available through - sys.path.
 - reload()#
- Reload the plugin. - Unlike - PyModulePlugin, it is not possible to use the- reloadfunction (either from imp or importlib), because the module might not be available through- sys.path.
 
- class sopel.plugins.handlers.PyModulePlugin(name, package=None)#
- Sopel plugin loaded from a Python module or package. - A - PyModulePluginrepresents a Sopel plugin that is a Python module (or package) that can be imported directly.- This: - >>> import sys >>> from sopel.plugins.handlers import PyModulePlugin >>> plugin = PyModulePlugin('xkcd', 'sopel.modules') >>> plugin.module_name 'sopel.modules.xkcd' >>> plugin.load() >>> plugin.module_name in sys.modules True - Is the same as this: - >>> import sys >>> from sopel.modules import xkcd >>> 'sopel.modules.xkcd' in sys.modules True - PLUGIN_TYPE = 'python-module'#
- The plugin’s type. - Metadata for the plugin; this should be considered to be a constant and should not be modified at runtime. 
 - configure(settings)#
- Configure Sopel’s - settingsfor this plugin.- Parameters:
- settings ( - sopel.config.Config) – Sopel’s configuration
 - This method will be called by Sopel’s configuration wizard. 
 - get_capability_requests() list[plugin_decorators.capability]#
- Retrieve the plugin’s list of capability requests. 
 - get_label()#
- Retrieve a display label for the plugin. - Returns:
- a human readable label for display purpose 
- Return type:
 - By default, this is - <name> plugin. If the plugin’s module has a docstring, its first line is used as the plugin’s label.
 - get_meta_description() PluginMetaDescription#
- Retrieve a meta description for the plugin. - Returns:
- Metadata about the plugin 
- Return type:
 - The expected keys are detailed in - PluginMetaDescription.- This implementation uses its module’s dotted import path as the - sourcevalue:- { 'name': 'example', 'type': 'python-module', 'label': 'example plugin', 'source': 'sopel_modules.example', 'version': '3.1.2', } 
 - get_version() str | None#
- Retrieve the plugin’s version. - Returns:
- the plugin’s version string 
- Return type:
- Optional[str] 
 
 - has_configure()#
- Tell if the plugin has a configure action. - Returns:
- Trueif the plugin has a- configureaction,- Falseotherwise
- Return type:
 - The plugin has a configure action if its module has a - configureattribute. This attribute is expected to be a callable.
 - has_setup()#
- Tell if the plugin has a setup action. - Returns:
- Trueif the plugin has a setup,- Falseotherwise
- Return type:
 - The plugin has a setup action if its module has a - setupattribute. This attribute is expected to be a callable.
 - has_shutdown()#
- Tell if the plugin has a shutdown action. - Returns:
- Trueif the plugin has a- shutdownaction,- Falseotherwise
- Return type:
 - The plugin has a shutdown action if its module has a - shutdownattribute. This attribute is expected to be a callable.
 - is_loaded()#
- Tell if the plugin is loaded or not. - Returns:
- Trueif the plugin is loaded,- Falseotherwise
- Return type:
 - This must return - Trueif the- load()method has been called with success.
 - load()#
- Load the plugin’s module using - importlib.import_module().- This method assumes the module is available through - sys.path.
 - register(bot: Sopel) None#
- Register the plugin with the - bot.- Parameters:
- bot ( - sopel.bot.Sopel) – instance of Sopel
 
 - reload()#
- Reload the plugin’s module using - importlib.reload().- This method assumes the plugin is already loaded. 
 - setup(bot)#
- Run the plugin’s setup action. - Parameters:
- bot ( - sopel.bot.Sopel) – instance of Sopel
 
 - shutdown(bot)#
- Run the plugin’s shutdown action. - Parameters:
- bot ( - sopel.bot.Sopel) – instance of Sopel
 
 - unregister(bot)#
- Unregister the plugin from the - bot.- Parameters:
- bot ( - sopel.bot.Sopel) – instance of Sopel