Custom Nodes Guide
When no built-in node covers your tool, you can author your own. This page summarizes the node contract; the step-by-step authoring walkthrough lives in Contributing → Creating Custom Nodes.
The node contract
Every node — built-in or custom — declares the same things:
- Identity — a fully-qualified
type(category.tool) and a display label. - Ports — typed
inputsandoutputs. - Params — typed, validated, user-editable parameters with defaults.
- Execution — the command/script to run, templated with resolved inputs and params.
- Resources — RAM/CPU hints used for scheduling and tier recommendations.
Minimal example
from bionodulo.sdk import node, Input, Output, Param, FASTA, Report
@node(category="QC", label="seqkit stats")
def seqkit_stats(
fasta: Input[FASTA],
all_stats: Param[bool] = True,
) -> Output[Report]:
"""Summarize sequence statistics with seqkit."""
flag = "-a" if all_stats else ""
return run(f"seqkit stats {flag} {fasta} > {output.report}")This node immediately appears in the palette under QC, with a checkbox for
all_stats in the inspector and a typed FASTA input port.
Packaging for reproducibility
For nodes that wrap external binaries, package the tool in a container image and declare it on the node:
@node(
category="Alignment",
label="minimap2",
image="quay.io/biocontainers/minimap2:2.28--h577a1d6_4",
)
def minimap2(...):
...This guarantees the exact tool version travels with the node, so a workflow’s results are reproducible across machines and over time.
Publishing to the registry
Once tested locally, publish your node to the community registry so others can install it by name with a pinned version. See Submitting PRs.