ContributingCreating Custom Nodes

Creating Custom Nodes

This is the full guide to authoring a BioNodulo node. For a quick overview see Node Reference → Custom Nodes Guide.

1. Scaffold a node

Use the SDK’s @node decorator. A node declares typed inputs and outputs, parameters, and how to execute the tool.

from bionodulo.sdk import node, Input, Output, Param, FASTQ, FASTA, BAM, run
 
@node(
    category="Alignment",
    label="Bowtie2",
    image="quay.io/biocontainers/bowtie2:2.5.4--he20e202_2",
)
def bowtie2(
    reads: Input[FASTQ],
    reference: Input[FASTA],
    threads: Param[int] = 4,
    preset: Param[str] = "--sensitive",
) -> Output[BAM]:
    """Align reads to a reference with Bowtie2."""
    return run(
        f"bowtie2 -p {threads} {preset} -x {reference.index} "
        f"-1 {reads.r1} -2 {reads.r2} "
        f"| samtools sort -o {output.aligned}"
    )

2. Declare accurate types

Port types feed the editor’s connection validation and the platform’s suggestions. Reuse built-in data types where they fit, and register new types only when necessary.

3. Set resource hints

Tell the scheduler what the node needs so it can recommend a resource tier:

@node(category="Assembly", label="SPAdes", resources={"min_ram_gb": 32, "cpu": 8})
def spades(...):
    ...

4. Pin the tool version

Always reference a specific container image tag (as above). This is the single most important thing for reproducibility — it guarantees the same binary runs for every user, forever.

5. Test the node

pytest tests/nodes/test_bowtie2.py

Write a test that runs the node on a tiny fixture input and asserts on the output (file exists, non-empty, expected header). Keep fixtures small so tests stay fast.

6. Document parameters

Every parameter should have a docstring/help text and a sensible default. These surface directly in the node inspector for end users.

7. Lint & validate

bionodulo lint-node bowtie2     # checks ports, types, image, params

Next