Liara supports plugins to extend the functionality. Plugins are discovered by being available in the
liara.plugins namespace. For more details, see:
In practice this means you can provide a plugin by placing it in the
liara.plugins namespace. A plugin must export at least one method named
register, with no parameters. Here’s an example of a minimal plugin:
def register(): pass
Of course, a completely empty plugin doesn’t provide any functionality. To hook into Liara, you can connect event handlers to signals. See below for more details.
Additionally, plugins can be loaded directly from a folder by specifying the
plugin_directories configuration option. In this case, each
.py file in that directory containing a
register method will be loaded as a plugin.
Liara uses signals as the extension mechanism. Signals are provided by Blinker. All signals are defined in the
liara.signals module. You can think of a signal as a callback mechanism – it calls back into the function registered to the signal (possibly multiple of them, i.e. if each plugin registers with the same signal. In that case the order of execution is undefined.)
A signal handler is a function which must accept parameters as defined in the documentation, with an extra first sender parameter. I.e. for
content_added, which has one documented parameter of type
Node, the function signature would be:
def on_content_added(sender, node: liara.nodes.Node): pass
Signals pass parameters by name, so you must match the names in the documentation. Using
on_content_added(sender, nd) for example would not work. You can however use
**kwargs to capture all parameters.
The first parameter is always the sender of the signal, but is not further specified (it could be a wrapper or proxy for instance of the class you would expect to make the call), so you should always rely on the named, documented parameters.
Always make sure to use top-level module functions for signal handlers. Locally defined functions (i.e. within
register()) will get garbage collected, as signals only weakly reference the receiver.
Extending the command line#
The command line is special as it needs to get extended at a very early stage – before it’s shown to the user for the first time. To extend the command line, you must use the
commandline_prepared signal. liara uses Click as the command line parser, but you cannot import liara’s command line module directly in your module as that would lead to circular includes. The recommendation is to put the commands directly into the registration method as following:
from liara.signals import commandline_prepared import click def register(): commandline_prepared.connect(_register_cli) def _register_cli(sender, cli): from liara.cmdline import pass_environment @cli.command() @pass_environment def my_new_command(env): print(env.liara)
Note the use of
@pass_environment. This requests Click to pass the Liara command line environment as the first parameter, which contains the Liara instance. See
Environment for more details.