Plugin Developer Guide#
This documentation helps to get started with creating user defined Freva
plugins. This section provides a minimal example to turn your existing data
analysis code into a Freva plugin. Detailed usage information can be found in the
API Reference.
A Minimal Example#
Definition of the base class that is used to implement user plugins.
The plugin API (Application Program Interface) is the central connection of a user plugin code and the Freva system infrastructure. The API enables the users to conveniently set up, run, and keep track of applied plugins. The reference below gives an overview of how to set up user defined plugins. For this purpose we assume that a plugin core (without Freva) already exists - for example as a command line interface tool (cli). Once such a cli has been set up a interface to Freva must be defined. This reference will introduce the possible definition options below.
Here we assume that the above mentioned cli code is stored in a directory
name /mnt/freva/plugins/new_plugin
furthermore the actual cli code can be
executed via:
cli/calculate -c 5 -n 6.4 --overwrite --name=Test
With help of this API a Freva plugin can be created in /mnt/freva/plugin/new_plugin/plugin.py
- class evaluation_system.api.plugin.PluginAbstract(*args, user: User | None = None, **kwargs)#
Base class that is used as a template for all Freva plugins. Any api wrapper class defining Freva plugins must inherit from this class.
- Parameters:
user (evaluation_system.model.user.User, default None) – Pre defined evaluation system user object, if None given (default) a new instance of a user object for the current user will be created.
- The following attributes are mandatory and have to be set:
- Whereas the following properties can be optionally set:
Example
In order to configure and call this cli, a Freva wrapper api class will have the be created in
/mnt/freva/plugins/new_plugin/plugin.py
. A minimal configuration example would look as follows:from evaluation_system.api import plugin, parameters class MyPlugin(plugin.PluginAbstract): __short_description__ = "Short plugin description" __long_description__ = "Optional longer description" __version__ = (2022, 1, 1) __parameters__ = parameters.ParameterDictionary( parameters.Integer( name="count", default=5, help=("This is an optional configurable " "int variable named number without " "default value and this description") ), parameters.Float( name="number", default=6.4, mandatory=True, help="Required float value without default" ), parameters.Bool( name="overwrite", default=True, help=("a boolean parameter " "with default value of false") ), parameters.String( name='name', default='Test',) ) def run_tool( self, config_dict: dict[str, str|int|bool] ) -> None: '''Definition of the tool that runs the cli. Parameters: ----------- config_dict: dict Plugin configuration stored in a dictionary ''' self.call( ( f"cli/calculate -c {config_dict['count']} " f"-n {config_dict['number']} --name={config_dict['name']}" ) ) print("MyPlugin was run with", config_dict)
Note
The actual configuration is defined by the
__parameters__
property, which is of typeevaluation_system.api.parameters.ParameterDictionary
.If you need to test it use the
EVALUATION_SYSTEM_PLUGINS
environment variable to point to the source directory and package. For example assuming you have the source code in/mnt/freva/plugins
and the package holding the class implementingevaluation_system.api.plugin
ismy_plugin.plugin
(i.e. its absolute file path is/mnt/freva/plugins/my_plugin/plugin_module.py
), you would tell the system how to find the plugin by issuing the following command (bash & co):export EVALUATION_SYSTEM_PLUGINS=/mnt/freva/plugins/my_plugin,plugin_module
Use a colon to separate multiple items:
export EVALUATION_SYSTEM_PLUGINS=/path1,plugin1:/path2,plugin2:/path3,plugin3
By telling the system where to find the packages it can find the
evaluation_system.api.plugin
implementations. The system just loads the packages and get to the classes using theclass.__subclasses__()
method. The reference speaks about weak references so it’s not clear if (and when) they get removed. We might have to change this in the future if it’s not enough. Another approach would be forcing self-registration of a class in the __metaclass__ attribute when the class is implemented.
Setting up your new plugin#
This section illustrates the steps that are necessary to turn existing
data analysis code into a Freva plugin.
Like above, we assume that the code is stored in a specific location for example
~/workspace/tracking_tool
. Also, let’s assume that the analysis tool is written
in the R script language.
Creating a new repository from a template#
We have created a template repository that helps you getting started with the Freva plugin development. Therefore we recommend you to use this repository. Use the following commands to turn this template repository into your new Freva plugin repository:
wget https://gitlab.dkrz.de/freva/plugins4freva/plugintemplate/-/archive/main/plugintemplate-main.zip
unzip plugintemplate-main.zip
mv plugintemplate-main freva_tracking
cd freva_tracking
git init --shared .
cp -r ~/workspace/tracking_tool src
git add .
You have now created a new Freva plugin repository. It is a good idea to use some kind of repository server, like gitlab, where you make your code accessible. Talk to your Freva admins to work out a good location for your code. Once you have agreed upon a location you should create a new repository on the server side using the web interface of your repository host system. Once created set the remote host address on the locally created repository (the one where you did a git init):
git remote set-url origin https://gitlab.com/path/to/the/remote/repo.git
Hint
If you are unfamiliar with git you can find plenty of online resources on the web. A good resource might be the official git tutorial page.
Installing dependencies#
Once the git repository has been set up and configured, all dependencies the tool
needs should be installed. Here we assume the analysis tool is based on a gnu-R
stack. Therefore gnu-R and certain libraries have to be part of the plugin
environment. This environment will be created using
anaconda.
To find out what dependencies you should be installing query the
anaconda search page.
Once you have found all packages that can be installed via anaconda you can add them
to the deployment/plugin-env.yaml
file. Simply add the entries that are needed
to the existing file.
channels:
- conda-forge
dependencies:
- conda
- r-base
- r-essentials
- r-ncdf4
- pip
- black
Probably there are package dependencies that cannot be installed via
anaconda and need to bee installed otherwise. To do so you can use
a simple command line interface in deployment/install_resources.py
and add the following command into the build
section of the Makefile
in the repository:
build:
python deployment/install_resources.py gnu-r ncdf4.helpers
To get an overview over the full functionality of the installation cli you can query the help.
python deployment/install_resources.py --help
After everything is setup you can build use the make
command to deploy the
plugin environment.
make all
Note
The Makefile
will use the conda
command. If anaconda is not available
by default on your system you can load the Freva environment, which ships
anaconda.
Afterwards you can refer to the Plugin API Reference and Parameter API Reference docs to create the wrapper file and finalize the creation of the plugin.