Installable plugins¶
There are two ways to add datasets, processes, and workflows to an instance, and they complement each other:
plugins_dir— drop files into the instance's local plugins folder. Ideal for instance-specific customisation, one-off datasets, or overriding a built-in. No packaging. See Extensibility and Adding custom datasets.- Installable packages — package a plugin and publish it, so any instance can
uv addit and OCS discovers it automatically (#118). Ideal for a reusable plugin shared across countries or organisations, versioned independently.
This guide covers the installable-package option. It is purely additive — plugins_dir
keeps working exactly as before, and still takes precedence (see Precedence).
Package layout¶
An importable package can ship any combination of the three extension points — datasets,
processes, and workflows are all auto-discovered when the package is installed. datasets/
and processes/ hold importable Python, so each needs an __init__.py (workflows/ is plain
JSON and does not):
osc_example_plugin/
__init__.py
datasets/
__init__.py
example.py # your BaseDatasetPlugin subclass
example.yaml # dataset templates
processes/ # optional: @process-decorated callables
__init__.py
my_process.py
workflows/ # optional: openEO UDP JSON graphs
my_workflow.json
The layout mirrors plugins_dir, so migrating a plugins_dir-based plugin to a distributable
package is mostly moving the files into a package and adding the entry point below.
Declare the entry point¶
In the package's pyproject.toml, point an entry point
in the open_climate_service.plugins group at the top-level package:
Declare open-climate-service as a dependency, but do not pin its VCS source — the consuming
instance decides which OCS revision to run:
The ingestion.plugin in a dataset template uses the class's full dotted path (not a
plugins_dir-relative one), since the package is installed on PYTHONPATH:
Install and discover¶
An operator installs the package — nothing else, no plugins_dir wiring:
OCS auto-discovers every installed package in the open_climate_service.plugins group and loads
its datasets/*.yaml templates, its processes/ (@process-decorated callables), and its
workflows/*.json (openEO UDPs). The ingestion plugin class is importable by dotted path because
the package is installed. The datasets then appear in /datasets and can be ingested like any
built-in.
Precedence¶
Templates are merged in increasing order of precedence, per extension point:
built-in → installed plugins → instance plugins_dir
So plugins_dir always wins on an id conflict — an operator can drop a YAML into their local
plugins/datasets/ to override an installed plugin's dataset. Overrides are logged at load time.
Naming convention¶
- Distribution name:
osc-<name>-plugin - Import package:
osc_<name>_plugin
For example, osc-senorge-plugin / osc_senorge_plugin.
Reference implementation¶
The seNorge plugin is the reference
implementation: it ships the seNorge 2018 datasets (source + derived) and the ingestion plugin, and
is consumed by the Norway instance via uv add.