spaCR plugin SDK¶
The plugin SDK lets a separately installed Python package add assays,
importers, analysis utilities, settings panels, model-zoo entries and report
sections without editing spaCR. Plugins use Python package entry points, so
spaCR discovers them at startup and keeps them available to both the Qt
application and spacr-run.
The current SDK API is 1.0. Only the major version controls
compatibility: a plugin declaring API 1.x works with spaCR’s 1.x SDK.
A malformed or failing plugin is isolated and reported by
spacr-plugins doctor; it cannot replace a built-in module or prevent spaCR
from starting.
Minimal plugin¶
Declare the entry point in the plugin package’s pyproject.toml:
[project.entry-points."spacr.plugins"]
my_assays = "my_spacr_plugin:plugin"
Then expose a manifest:
from spacr.plugins import AppContribution, SpacrPlugin
plugin = SpacrPlugin(
name="My laboratory assays",
version="0.1.0",
api_version="1.0",
apps=(
AppContribution(
key="organelle_contact",
name="Organelle Contact",
description="Measure contact sites from a processed plate.",
kind="assay",
section="results",
stage="alpha",
entrypoint="my_spacr_plugin.pipeline:run",
defaults="my_spacr_plugin.pipeline:default_settings",
categories={
"Input": ("src", "table"),
"Detection": ("distance_px", "min_area"),
"Output": ("save_figures",),
},
tooltips={
"src": "Processed spaCR plate folder.",
"distance_px": "Maximum membrane-to-membrane distance.",
},
labels={"distance_px": "Contact distance (px)"},
docs_url="https://example.org/my-plugin/api/",
aliases=("contacts",),
validator="my_spacr_plugin.pipeline:validate",
drop_handler="my_spacr_plugin.qt:PlateDropHandler",
requires=("src — a processed spaCR plate",),
writes=("<src>/measurements/contact_sites.csv",),
),
),
)
The pipeline callable receives one settings dictionary. The defaults callable
must accept an optional settings dictionary and return a dictionary. A
validator returns spacr.validate.Problem objects (or equivalent
mappings). All processing still runs through spaCR’s worker, journal,
cancellation and reproducibility paths.
Settings and custom screens¶
The generic settings screen is preferred: declare categories, tooltips
and optional labels on spacr.plugins.AppContribution. The UI then
provides the normal Run/Stop controls, console, progress reporting, API links,
drag-and-drop fallback and remote-submit action.
For a layout the generic screen cannot express, set screen_factory to a
module:callable. The callable is invoked as factory(app_key=...) and
must return a PySide6.QtWidgets.QWidget. A custom drop_handler must be
a subclass of spacr.qt.dnd_handlers.DropHandler. icon may name a
spaCR semantic icon or an absolute image path; otherwise the normal puzzle
piece fallback is used.
Model providers¶
Add a spacr.plugins.ModelProviderContribution. Its zero-argument
callable returns an iterable of spacr.model_zoo.ModelEntry objects or
the mappings accepted by spaCR’s JSON model catalogue.
from spacr.plugins import ModelProviderContribution
ModelProviderContribution(
key="lab_models",
provider="my_spacr_plugin.models:catalogue",
)
Providers must be read-only during catalogue discovery. Downloads remain an
explicit Model Zoo action. A provider exception is shown by
spacr-plugins doctor and built-in models remain available.
Report sections¶
A spacr.plugins.ReportSectionContribution builder receives a
read-only spacr.plugins.ReportContext and returns a
spacr.report.Section:
from spacr.plugins import ReportSectionContribution
from spacr.report import Section
def build_contacts(context):
return Section(
key="organelle_contacts",
title="Organelle contacts",
body_html="<p>Contact-site results.</p>",
text_lines=["Contact-site results."],
)
contact_report = ReportSectionContribution(
key="organelle_contacts",
title="Organelle contacts",
builder="my_spacr_plugin.report:build_contacts",
after="statistics",
)
If the builder raises, the generated report contains a visible problem chapter with the exception instead of silently omitting the section.
Translations¶
SpacrPlugin.translations maps spaCR language codes to English-source /
translated-text mappings. Supported codes are sv, de, es,
zh_CN, pt, hi, ko, is and fr. Missing strings fall
back to English.
Development and diagnostics¶
During local development only, point SPACR_PLUGIN_MODULES at a
comma-separated list of module:attribute references. Set
SPACR_DISABLE_PLUGINS=1 to start spaCR without third-party plugins.
SPACR_PLUGIN_MODULES=my_spacr_plugin:plugin spacr-plugins list
spacr-plugins doctor
spacr-plugins doctor --json
The public SDK lives in spacr.plugins; the diagnostics command lives in
spacr.cli_plugins.
API reference¶
Versioned extension SDK for third-party spaCR plugins.
Plugins are ordinary Python distributions exposing one entry point in the
spacr.plugins group. The entry point may resolve to a
SpacrPlugin, a mapping accepted by plugin_from_mapping(), or a
zero-argument factory returning either. Discovery is lazy, deterministic and
failure-isolated: one malformed plugin is recorded in diagnostics()
without preventing spaCR or the remaining plugins from loading.
For editable/local development, SPACR_PLUGIN_MODULES may contain a
comma-separated list of module or module:attribute references.
Installed plugins should always use package entry points instead.
- class spacr.plugins.AppContribution(key: str, name: str, description: str, entrypoint: str, defaults: str, section: str = 'results', stage: str = 'alpha', kind: str = 'analysis', categories: ~typing.Mapping[str, ~typing.Sequence[str]] = <factory>, tooltips: ~typing.Mapping[str, str] = <factory>, labels: ~typing.Mapping[str, str] = <factory>, docs_url: str = '', aliases: ~typing.Tuple[str, ...] = (), validator: str = '', screen_factory: str = '', drop_handler: str = '', icon: str = '', requires: ~typing.Tuple[str, ...] = (), writes: ~typing.Tuple[str, ...] = (), call_style: str = 'settings')[source]¶
Bases:
objectOne runnable GUI/headless application contributed by a plugin.
- class spacr.plugins.ModelProviderContribution(key: str, provider: str)[source]¶
Bases:
objectA callable returning model-zoo entries or entry mappings.
- class spacr.plugins.PluginDiagnostic(plugin: str, severity: str, message: str, exception: str = '')[source]¶
Bases:
objectOne discovery or contribution error visible to users and logs.
- class spacr.plugins.ReportContext(src: Any, artifacts: Mapping[str, Any], runs: Tuple[Mapping[str, Any], ...], options: Mapping[str, Any])[source]¶
Bases:
objectRead-only inputs passed to plugin report-section builders.
- class spacr.plugins.ReportSectionContribution(key: str, title: str, builder: str, after: str = 'statistics')[source]¶
Bases:
objectA callable adding one section to
spacr.report.collect_report().
- class spacr.plugins.SpacrPlugin(name: str, version: str, api_version: str = '1.0', apps: ~typing.Tuple[~spacr.plugins.AppContribution, ...] = (), model_providers: ~typing.Tuple[~spacr.plugins.ModelProviderContribution, ...] = (), report_sections: ~typing.Tuple[~spacr.plugins.ReportSectionContribution, ...] = (), translations: ~typing.Mapping[str, ~typing.Mapping[str, str]] = <factory>)[source]¶
Bases:
objectValidated plugin manifest returned by a
spacr.pluginsentry point.- apps: Tuple[AppContribution, ...] = ()[source]¶
- model_providers: Tuple[ModelProviderContribution, ...] = ()[source]¶
- report_sections: Tuple[ReportSectionContribution, ...] = ()[source]¶
- spacr.plugins.diagnostics() Tuple[PluginDiagnostic, ...][source]¶
Return discovery and runtime contribution failures.
- spacr.plugins.discover_plugins() Tuple[SpacrPlugin, ...][source]¶
Return every valid discovered plugin in deterministic order.
- spacr.plugins.get_app(key: str) AppContribution | None[source]¶
Return a contributed app by key, or
None.
- spacr.plugins.load_object(reference: str) Any[source]¶
Import and return
module:attribute(nested attributes supported).
- spacr.plugins.model_providers() Tuple[Tuple[str, ModelProviderContribution], ...][source]¶
Return
(plugin_name, provider)model-zoo contributions.
- spacr.plugins.plugin_apps() Tuple[AppContribution, ...][source]¶
Return all contributed applications.
- spacr.plugins.plugin_from_mapping(value: Mapping[str, Any]) SpacrPlugin[source]¶
Validate a mapping and return its immutable
SpacrPlugin.
- spacr.plugins.record_diagnostic(plugin: str, message: str, exception: Any = '', severity: str = 'error') None[source]¶
Record a model/report/runtime plugin failure without aborting spaCR.
- spacr.plugins.reload_plugins() Tuple[SpacrPlugin, ...][source]¶
Clear the discovery cache and discover again (primarily for tests/dev).