Plugins

This section describes how plugins can be developed as stand-alone packages in order to extend the functionality of Kadi4Mat without having to touch the main application code. As currently all first-party plugins are part of the main application package, all existing examples can be found in the kadi.plugins module. This also includes code not implemented as a separate plugin, but still using the plugin infrastructure.

Plugin infrastructure

The plugin infrastructure in Kadi4Mat builds upon pluggy, a simple and flexible plugin system. It allows implementing different plugin interface functions, called hook specifications, which a plugin can choose to implement. Each hook will be called in certain places in the application, which will invoke all corresponding implementations of that hook.

In order for the main application to find a plugin, the plugin has to register itself using the kadi_plugins entry point, as also done for all first-party plugins in the pyproject.toml file. Each plugin needs to specify a unique name and the module that contains all hook implementations, according to the plugin’s corresponding build system configuration:

[project]
dependencies = [
    "kadi>=X,<Y",
]

[project.entry-points.kadi_plugins]
example = "kadi_plugin_example.plugin"
[options]
install_requires =
    kadi>=X,<Y

[options.entry_points]
kadi_plugins =
    example = kadi_plugin_example.plugin
from setuptools import setup

setup(
    install_requires=[
        "kadi>=X,<Y",
    ],
    entry_points={
        "kadi_plugins": [
            "example=kadi_plugin_example.plugin",
        ],
    },
)

In this example, the plugin is called example, while the hook implementations are loaded via the kadi_plugin_example.plugin module of a package called kadi_plugin_example.

Note

Whenever performing changes in the entry points while developing, it may be necessary to reinstall the application and/or any plugin packages in order to fully propagate the changes.

As shown in the build system configuration snippets above, plugins can also specify the supported version range of Kadi4Mat via a corresponding dependency. Doing so is generally recommended, as hook specifications as well as internal functionality of Kadi4Mat that a plugin might use are subject to change between releases.

Plugin hooks

Plugin hooks can be implemented by using the hookimpl decorator. The name of the decorated function must correspond to the respective plugin hook. Plugin configurations, specified via the PLUGIN_CONFIG configuration value, can be loaded by using the get_plugin_config function (see also how to install plugins). An example implementation could look like the following:

from kadi.lib.plugins.core import get_plugin_config
from kadi.plugins import hookimpl

@hookimpl
def kadi_example_plugin_hook():
    # Load the configuration of the "example" plugin, if applicable.
    config = get_plugin_config("example")
    # Validate the configuration or do something else with it.

To see a list of all currently existing hook specifications, please refer to the API reference.