Writing a plugin¶
noodlelab new-plugin thermo # scaffolds noodlelab-thermo/
cd noodlelab-thermo
git init && git add -A && git commit -m "First version"
uv pip install -e . # into the environment noodlelab runs in
noodlelab check-plugin . # the standard: manifest, imports, permissions, nodes, examples
The scaffold is a complete plugin: pyproject.toml (the version comes from
git tags), the manifest, two nodes, an example graph, a test, and a release
workflow that checks it and publishes signed wheels.
Nodes¶
A node is a type-hinted function with @node. The hints decide its sockets,
units and widgets, and its docstring is the help text people and agents read:
from typing import Annotated
from noodlelab.plugin import Param, Quantity, node
@node(category="Thermodynamics")
def isentropic_efficiency(
h_in: Quantity["kJ/kg"],
h_out: Quantity["kJ/kg"],
h_out_isentropic: Quantity["kJ/kg"],
) -> float:
"""Efficiency of a turbine stage: actual over ideal enthalpy drop."""
return float((h_in - h_out) / (h_in - h_out_isentropic))
Uncertainty propagates through a node without any code in it. A node never changes its inputs in place: arrays arrive read-only, tables and lists as copies of their own.
The public API¶
Import noodlelab only through noodlelab.plugin:
Module |
What |
|---|---|
|
|
|
the unit registry ( |
|
making and reading values with uncertainties |
|
units and descriptions of table columns |
|
columns as arrays, table attributes |
|
checking expressions typed into widgets before evaluating them |
|
constants, saving figures, parameter studies, Typst maths |
warning and error are what a node’s .check returns before a run;
warn("...") is for what a node finds while it runs (a matrix close to
singular, a fit the data cannot pin down): the run goes on, and the warning
is shown on the node and kept in the run’s provenance. The executor also warns
by itself when a node returns a value that is not a number (NaN or infinite).
A node that judges its result returns a Check among its outputs (see the
Checks pack): it is reported like Expect Value’s, without stopping the run.
Everything else in noodlelab is internal and may change in any release.
noodlelab.plugin.API_VERSION is the version of this contract; a plugin states
the one it was written for in its manifest, and noodlelab refuses, before
running any of its code, a plugin written for a version it does not speak.
To use another plugin’s helpers, import its public (not _-prefixed) modules
and declare it in requires. Optional dependencies are checked at import with
noodlelab.plugin.require("noodlelab-thermo[steam]", "CoolProp"), which fails
with the install command instead of an ImportError deep in a run.
The manifest¶
src/<package>/noodlelab-plugin.toml, shipped inside the package:
name = "thermo" # = the entry point name = the node id prefix
title = "Thermodynamics"
description = "Steam tables, cycles and heat exchangers"
api = 1 # the noodlelab.plugin API it was written for
requires = { maths = ">=1.2,<2" } # other plugins, with version ranges ("*": any)
permissions = [] # see below
examples = ["examples/rankine.graph.json"]
templates = ["reports/datasheet"] # report templates: folders with template.typ
homepage = "https://github.com/you/noodlelab-thermo"
license = "MIT"
The version is not in the manifest: it comes from the git tag.
Permissions declare what the plugin does besides computing on its inputs
and reading and writing files in the workspace: network, subprocess,
filesystem:home, filesystem:any, native (ctypes/cffi) and env.
check-plugin and the index read the code and refuse a version that does
more than it declares, and admins decide whether to grant them.
Versions¶
Plugins follow semantic versioning:
major (2.0.0): a node id, socket, unit or meaning changed, so saved graphs may break;
minor (1.3.0): new nodes or options;
patch (1.2.1): fixes.
A saved graph records the plugins it uses as >=<saved version>,<next major>.
When a node’s results change (a corrected formula), also raise its own
@node(version=N): that invalidates cached results computed by the old code.
check-plugin¶
noodlelab check-plugin . checks everything an index checks, before you
publish:
the manifest, and that its name is the entry point’s;
the plugin API;
imports: only
noodlelab.plugin, its own package, the plugins it requires and third-party libraries;permissions: nothing it does that it does not declare (and what it hides, like
evalor dynamic imports, is pointed out for a reviewer);the nodes, as strict mode judges them;
the example graphs, which must run;
at a tag, that the package builds that version.