01 A workflow engine for computational biology

Type the wires.
Run the pipeline.

Drag RFdiffusion, Rosetta, AlphaFold and PyMOL onto a node canvas. Wire their typed inputs and outputs. Chaperonin serializes the graph, dispatches each step as a Docker container, and streams the run back live.

FIG. 01 Six modules wired to the orchestrator. Click Run to dispatch.
Modules06
Type systemHierarchical · covariant
DispatchDocker · WebSocket
BackendPython 3.12 stdlib

02 The mechanism

Three views,
one shared graph.

Edit a node on the canvas, the DSL regenerates. Edit the DSL text, the canvas re-renders. Both compile to the same typed graph the orchestrator runs.

A

Canvas

Direct manipulation. Drag, wire, run. The visual representation of the AST.

B

Graph

The canonical typed AST. Both canvas and DSL serialize to it; the orchestrator runs it.

C

DSL

# Same pipeline as text.
pdb     = input(Structure.PDB,
            label="scaffold")
relaxed = ROSETTA_RELAX(
            structure=pdb,
            nstruct=1)
viz     = VISUALIZER(
            value=relaxed.relaxed)
best    = select(
            from=relaxed.score,
            mode="min")

Field note

Being able to connect different computational programs and run them on a single platform would be enormously convenient. If Chaperonin really lets a researcher wire the tools together with a mouse and execute them, it will be an exceptionally practical bioinformatics tool.

03 The type system

Hierarchical.
Covariant. Strict.

Every handle declares a type. The canvas refuses incompatible wires before the run ever leaves the browser. Structure.PDB satisfies Structure. Union inputs accept Structure.PDB | Sequence.FASTA.

NamespaceSubtypesDirectionUse
Structure .PDB · .mmCIF I / O 3D atomic models
Sequence .FASTA · .FASTQ I / O Linear residue strings
Visual .PNG · .Web3D OUT Renderable artifacts
Text .RawString · .Integer · .Float · .Score I / O Scalars & metadata

04 Modules

Six tools,
one decorator,
identical contract.

Each module is a single Python file under backend/modules/. The @module decorator self-describes inputs, params, outputs, resources, and the Docker image. The palette and the DSL pick it up on restart.

ID Category Container image Resources
RFDIFFUSION Design rosettacommons/rfdiffusion 1× GPU · 24 GB
ALPHAFOLD Prediction ghcr.io/sokrypton/colabfold 1× GPU · 16 GB
ROSETTAFOLD Prediction rosettacommons/rosettafold 1× GPU · 24 GB
ROSETTA_RELAX Refinement rosettacommons/rosetta CPU · 4 cores
PYMOL Visualization pegi3s/pymol CPU · 2 GB
PDB_TO_FASTA Conversion host (no container) CPU · ~0

Adding a tool is one decorated Python file. Drop it in backend/modules/, restart the server. No registry edits, no scheduler patches.

05 Protocol

Execution
you can watch.

A single WebSocket carries one JSON object per event. The frontend sends a run with the serialized graph; the backend streams progress back until exactly one of pipeline.done or pipeline.error closes the run.

Event grammar

pipeline.start
Emitted once. Carries total.
node.queued
Node is scheduled, awaiting dispatch.
node.running
Container has started.
node.progress
Drives the progress bar. current / total.
node.log
One stdout or stderr line.
node.done
Container exited zero.
pipeline.done
Terminal. UI unlocks.
ws://localhost:8000/ws
{"type": "pipeline.start", "total": 3}
{"type": "node.queued", "nodeId": "rfdiffusion_1"}
{"type": "node.running", "nodeId": "rfdiffusion_1"}
{"type": "node.progress", "nodeId": "rfdiffusion_1", "current": 12, "total": 50}
{"type": "node.log", "nodeId": "rfdiffusion_1", "line": "[12/50] pLDDT=0.74 loss=0.89"}
{"type": "node.done", "nodeId": "rfdiffusion_1"}
{"type": "node.running", "nodeId": "rosetta_1"}
{"type": "node.done", "nodeId": "rosetta_1"}
{"type": "node.running", "nodeId": "pymol_1"}
{"type": "node.done", "nodeId": "pymol_1"}
{"type": "pipeline.done"}

06 Start

Run it locally
in two commands.

Requires a Docker daemon and about 30 GB of free disk for module images. The chaperonin container bind-mounts the host socket and spawns each module as a sibling container.

$ docker build -t chaperonin .
$ docker run -d --name chaperonin \
    -p 8000:8000 \
    -v /var/run/docker.sock:/var/run/docker.sock \
    chaperonin

Then open http://localhost:8000. Drag from the palette, wire it up, hit Run.