Plugin System Architecture¶
Niamoto discovers plugins, validates config with Pydantic, then calls the matching runtime hook.
Discovery And Override Rules¶
PluginLoader.load_plugins_with_cascade(project_path) scans three locations in this order:
project/plugins~/.niamoto/pluginsbundled plugins under
src/niamoto/core/plugins
The first plugin name wins. A project plugin can override a user or bundled plugin with the same registered name.
from pathlib import Path
from niamoto.core.plugins.plugin_loader import PluginLoader
loader = PluginLoader()
loader.load_plugins_with_cascade(Path("/path/to/project"))
Registry¶
Each plugin registers itself with @register("name", PluginType.X). Niamoto stores that class in PluginRegistry and looks it up by name and type.
from niamoto.core.plugins.base import PluginType
from niamoto.core.plugins.registry import PluginRegistry
widget_class = PluginRegistry.get_plugin("bar_plot", PluginType.WIDGET)
Plugin Types¶
Type |
Base class |
Typical config surface |
Runtime hook |
|---|---|---|---|
Loader |
|
|
|
Transformer |
|
|
|
Widget |
|
|
|
Exporter |
|
|
|
Deployer |
|
|
async deploy / unpublish methods |
Config Models¶
Most plugins expose two pieces of validation:
config_modelvalidates the full config entry, usuallyplugin + paramsparam_schemaexposes typed params for GUI forms and runtime validation
Niamoto uses BasePluginParams, PluginConfig, WidgetConfig, and TargetConfig as the shared building blocks.
Transform Config Shape¶
Transform groups live in a top-level list. Each widget entry points at one transformer plugin.
- group_by: plots
sources:
- name: occurrences
data: occurrences
grouping: plots
relation:
plugin: direct_reference
key: plot_id
widgets_data:
dbh_distribution:
plugin: binned_distribution
source: occurrences
params:
field: dbh
bins: [10, 20, 30, 40, 50]
Export Config Shape¶
Export targets live under exports:. Widgets belong inside groups[*].widgets.
exports:
- name: web_pages
exporter: html_page_exporter
params:
template_dir: templates
output_dir: exports/web
groups:
- group_by: plots
widgets:
- plugin: info_grid
title: Plot summary
data_source: general_info
params:
items:
- label: Elevation
source: elevation
Widget Runtime¶
Niamoto validates each widget entry as a WidgetConfig, instantiates the plugin, validates params with that widget’s param_schema, then calls render(data, params).
The widget config stores:
plugindata_sourcetitledescriptionparamslayout
title and description live at the widget level, not inside params.
Exporter Runtime¶
ExporterService validates export.yml as an ExportConfig, loads the exporter plugin, and calls:
exporter.export(target_config=target, repository=self.db, group_filter=group_filter)
A custom exporter therefore needs to accept target_config, repository, and the optional group_filter.
Deployers¶
Deployers sit after export generation. The CLI and GUI register deployer plugins such as github, netlify, cloudflare, vercel, render, and ssh. You configure them in deploy.yml or with niamoto deploy.
Project Layout¶
project/
plugins/
loaders/
transformers/
widgets/
exporters/
deployers/
config/
import.yml
transform.yml
export.yml
deploy.yml