Skip to main content

biosimulant

PyPI - Version PyPI - Python Version

Composable simulation runtime + UI layer for orchestrating runnable biomodules.

biosimulant is the primary package, import namespace, and CLI name. The existing biosim Python import path and python -m biosim command remain supported for existing model packages during the migration.


Executive Summary & System Goals

Vision

Provide a small, stable composition layer for simulations: wire reusable components ("biomodules") into a BioWorld, run them with a single orchestration contract, and visualize/debug labs via the local labs serve web UI. Biomodules are self-contained Python packages that can wrap external simulators internally (SBML/NeuroML/CellML/etc.) without a separate adapter layer.

Core Mission

  • Compose simulations from reusable, interoperable biomodules.
  • Make "run + visualize + share a config" the default local workflow, with an explicit client for durable hosted execution when requested.
  • Keep the runtime small and predictable while letting biomodules embed their own simulator/tooling.

Primary Users

  • Developers and researchers who need composable simulation workflows and fast iteration.
  • Near-term beachhead: neuroscience demos (single neuron + small E/I microcircuits) with strong visuals and reproducible configs.

Installation

Preferred (pinned GitHub ref):

pip install "biosimulant @ git+https://github.com/<org>/biosim.git@<ref>"

Alternative (package index):

pip install biosimulant

The default install includes the local web runtime used by biosimulant labs serve.

Managed Developer API

BioWorld.run() remains local and free. Use Client or AsyncClient when you explicitly want to run an accessible, versioned Hub lab on managed compute:

from biosimulant import Client

with Client() as client:  # reads BIOSIMULANT_API_KEY
    result = client.run(
        "demi/microbiology-hello-world-growth@1.0.0",
        inputs={"initial_cells": 10, "available_food": 80},
        timeout=300,
    )
    print(result.outputs)

For a durable handle that returns immediately, use client.runs.create(...).wait(). See the Developer API documentation for async execution, cancellation, timeout recovery, webhooks, and billing. The supported Python API surface lists every supported root import, including Client, AsyncClient, result types, and public errors.

For the shared ONNX biomodule helpers:

pip install "biosimulant[ml]"

Compatibility and command ownership

Use biosimulant for new Python examples:

import biosimulant as biosim

The package still ships the legacy biosim Python import path so existing model packages keep working:

import biosim

Use biosimulant for new CLI examples:

biosimulant --help
python -m biosimulant --help

python -m biosim remains available as a compatibility command. The PyPI package is the canonical headless CLI used by Desktop, Studio, local terminals, CI, and servers. Desktop-specific windows and application state remain private application code; Biosimulant operations use this same CLI everywhere.

Shell completion

biosimulant supports bash and zsh completion for commands, options, and file paths. Add the completion hook once to your shell startup file:

# ~/.zshrc or ~/.bashrc
eval "$(register-python-argcomplete biosimulant)"

Then restart the shell, or run source ~/.zshrc / source ~/.bashrc.

Publishing to PyPI

See the release guide: docs/releasing.md.

Local Labs

The open-source Python CLI can create, manage, validate, run, and serve local lab source trees without Desktop or Hub:

biosimulant labs create ./my-lab --name "My Lab"
biosimulant labs list .
biosimulant labs get ./my-lab
biosimulant labs package ./my-lab --out dist
biosimulant labs validate ./my-lab
biosimulant labs run ./my-lab --no-install-deps
biosimulant labs serve ./my-lab

labs init creates a runnable starter lab by default. Use --empty when you want only a bare lab.yaml scaffold. Managed local lab identity lives in .biosimulant/lab.json; exported labs use the portable lab.yaml source manifest.

Compose Hub Labs Locally

Use a local BioModule beside a version-pinned Hub Lab in one BioWorld. The parent Lab owns the dependency state and lockfile; resolving a Hub Lab is explicit and is never triggered by importing Python code.

from biosimulant import BioWorld
from biosimulant.hub import HubComposition

world = BioWorld(communication_step=0.1)
world.add_biomodule("controller", DoseController())

# ./lab/biosimulant.lock pins the exact archive checksum for this reference.
composition = HubComposition(world, lab_root="./lab")
composition.add("medium", "your-namespace/nutrient-medium@1.1.0")
composition.apply()
composition.setup()
world.run(duration=24.0)

biosimulant.lock must contain an exact SHA-256 for every package-backed child Lab. Dependencies resolve into ./lab/.biosimulant/dependencies/; delete that directory to force a clean, lockfile-verified resolution. See docs/hub-composition.md for the lockfile format, vendored archival packages, and read-only archive state overrides. The hosted HubComposition API reference documents its constructor, .add(), .connect(), .apply(), and .setup() methods.

Packaging Models And Labs

biosimulant packages labs through the labs command group. Standalone model package helpers remain Python APIs, but the public CLI object is the lab.

Common commands:

# Validate and build a package repository manifest
biosimulant labs release validate biosimulant-packages.yaml
biosimulant labs release build biosimulant-packages.yaml --out dist/biosimulant-packages

# Build a self-contained lab package (.bsilab)
biosimulant labs package path/to/lab --out dist

# Discover and pull public registry labs
biosimulant labs search immune
biosimulant labs info owner/lab-name@1.0.0
biosimulant labs pull owner/lab-name@1.0.0 --target ./labs/lab-name

# Validate or run a lab source tree or .bsilab
biosimulant labs validate path/to/lab
biosimulant labs run dist/local__source-lab-1.0.0.bsilab --no-install-deps

Notes:

  • local labs validate, labs run, and labs serve can use source labs without package: or version:; the CLI assigns a transient local/<lab-directory-slug> identity for local execution.
  • standalone labs package builds require package: and version: in lab.yaml, or explicit --package and --version values. Release manifests can supply identity through biosimulant-packages.yaml.
  • model dependencies in manifests must use exact == pins.
  • ordinary lab builds preserve version-pinned Hub child references and their lockfile; use --vendor-dependencies when an archival .bsilab must embed every child Lab.
  • nested lab dependencies may use a relative path, or an exact package + version with a matching biosimulant.lock checksum.
  • validate prints human-readable success or failure output by default; add --json for machine-readable output.

See docs/packaging.md for the full package layout, recommended authoring flow, and CLI examples.

Provisional Runtime Helpers

biosimulant.runtime is the provisional public home for package interpretation helpers shared by the open-source CLI and Biosimulant platform executors. It owns entrypoint loading, typed run input coercion, communication-step resolution, and source-neutral lab flattening. Import these helpers from biosimulant.runtime; the legacy biosim.runtime path remains available for compatibility.

BioModule Convenience Layers

BioModule remains the minimal full-control runtime contract. For common model adapters, biosimulant also exports opt-in helpers:

  • SignalEmitterBioModule: output storage, source-name resolution, and raw value to typed BioSignal wrapping.
  • StatefulBioModule: fixed-step window advancement, input override storage, bounded history, and output publishing hooks.

Signal helper functions are available from biosimulant.signals and top-level biosimulant: unwrap_payload, coerce_float, scalar_or_record_input, and make_signal.

Examples

  • See examples/ for quick-start scripts. Try:
pip install -e .
python examples/basic_usage.py

For advanced curated demos (neuro/ecology), wiring configs, and model-pack templates, see the companion repo:

Quick Start: BioWorld

Minimal usage:

import biosimulant as biosim
from biosimulant import ScalarSignal, SignalSpec


class Counter(biosim.BioModule):
    def __init__(self):
        self.value = 0
        self._t = 0.0

    def outputs(self):
        return {"count": SignalSpec.scalar(dtype="int64", emitted_unit="1")}

    def advance_window(self, start: float, end: float) -> None:
        _ = start
        self.value += 1
        self._t = end

    def get_outputs(self):
        return {
            "count": ScalarSignal(
                source="counter",
                name="count",
                value=self.value,
                emitted_at=self._t,
                spec=self.outputs()["count"],
            )
        }

    def snapshot(self) -> dict:
        return {"value": self.value, "t": self._t}

    def restore(self, snapshot: dict) -> None:
        self.value = int(snapshot.get("value", 0))
        self._t = float(snapshot.get("t", 0.0))


world = biosim.BioWorld(communication_step=0.1)
world.add_biomodule("counter", Counter())
world.run(duration=1.0)

Outputs produced during a communication window are committed at the end of that window and become visible to downstream modules on a later communication turn. For final report, export, or visualisation modules in workflow-style graphs, call world.settle(steps=1) after world.run(...) to propagate final outputs without advancing simulated time.

Visuals from Modules

Modules may optionally expose visuals via visualize(), returning a dict or list of dicts with keys render and data. The world can collect them without any transport layer:

class MyModule(biosim.BioModule):
    def advance_window(self, start: float, end: float) -> None:
        _ = start, end

    def get_outputs(self):
        return {}

    def snapshot(self) -> dict:
        return {}

    def restore(self, snapshot: dict) -> None:
        _ = snapshot

    def visualize(self):
        return {
            "render": "timeseries",
            "data": {"series": [{"name": "s", "points": [[0.0, 1.0]]}]},
        }

world = biosim.BioWorld(communication_step=0.1)
world.add_biomodule("module", MyModule())
world.run(duration=0.1)
print(world.collect_visuals())  # [{"module": "module", "visuals": [...]}]

If visuals are generated by a separate downstream module wired to another producer's final outputs, run one or more settle turns before collecting visuals: world.run(duration=...); world.settle(1); world.collect_visuals().

See examples/visuals_demo.py for a minimal end-to-end example.

ONNX Modules

biosimulant can host ONNX-backed modules without changing the core runtime. Install the ML extras and wrap the ONNX model behind the standard BioModule interface:

from biosimulant import OnnxClassifierModule, ScalarSignal, SignalSpec

classifier = OnnxClassifierModule(
    model_path="artifacts/model.onnx",
    class_labels=["quiescent", "subthreshold", "spiking"],
    input_port="state_vector",
    probabilities_port="state_probabilities",
    predicted_port="predicted_state",
    input_vector_length=4,
)

classifier.set_inputs(
    {
        "state_vector": ScalarSignal(
            source="adapter",
            name="state_vector",
            value=-64.0,
            emitted_at=0.0,
            spec=SignalSpec.scalar(dtype="float64"),
        )
    }
)
classifier.advance_window(0.0, 0.001)
print(classifier.get_outputs()["predicted_state"].value)

Model packs can subclass OnnxClassifierModule to set model-relative model_path, port names, and label sets while keeping the inference logic in the shared library.

Local Lab UI

biosimulant labs serve starts the bundled local lab UI from any runnable lab source tree, .bsilab package, or registry reference.

biosimulant labs serve ./my-lab

The command opens the browser by default and serves the UI at the root URL, for example http://127.0.0.1:8765/. Use --no-open to suppress the browser launch and --port to choose a different port.

The UI stores lab edits in local files:

  • lab.yaml for model, world, runtime, and wiring changes.
  • wiring-layout.json for canvas positions.
  • Run history is in memory for the active server process.

Maintainer flow for the bundled frontend:

  • Edit the private React/Vite app under packages/labs-serve-ui.
  • Build with bash scripts/build_labs_serve_ui.sh.
  • Packaging includes src/biosim/labs_serve/static/**, so end users never need npm.

Visual Notes

  • VisualSpec types supported now:
    • timeseries: data = { "series": [{ "name": str, "points": [[x, y], ...] }, ...] }
    • bar: data = { "items": [{ "label": str, "value": number }, ...] }
    • scatter: data = { "points": [{ "x": number, "y": number, "label"?: str, "series"?: str }, ...] }
    • heatmap: data = { "values": [[number, ...], ...], "x_labels"?: [str, ...], "y_labels"?: [str, ...] }
    • table: data = { "columns": [..], "rows": [[..], ...] } or data = { "items": [{...}, ...] }
    • image: data = { "src": str, "alt"?: str, "width"?: number, "height"?: number }
    • graph: simple node-edge graph renderer
    • structure3d: data = { "title"?: str, "source": { "kind": "url", "url": str } | { "kind": "artifact", "artifact_id": str }, "format": "mmcif" | "pdb", "annotations"?: [{ "label": str, "value": str|number|bool }], "initial_view"?: {...} }
  • VisualSpec may also include an optional description (string) for hover text or captions.

Terminology

Understanding the core concepts is essential for working with Biosimulant effectively.

Term Description
BioWorld Runtime container that orchestrates multi-rate biomodules, routes signals, and publishes lifecycle events.
BioModule Pluggable unit of behavior with local state. Implements the runnable contract (setup/reset/advance_to/...).
BioSignal Typed, versioned data payload exchanged between modules via named ports.
WorldEvent Runtime events emitted by the BioWorld (STARTED, TICK, FINISHED, etc.).
Wiring Module connection graph. Defined programmatically, via WiringBuilder, or loaded from YAML/TOML configs.
VisualSpec JSON structure returned by module.visualize() with render type and data payload.

Event Lifecycle

Every simulation follows this sequence:

STARTED -> TICK (xN) -> FINISHED

PAUSED, RESUMED, STOPPED, and ERROR may also be emitted depending on runtime control flow.

License

MIT. See LICENSE.txt.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

biosimulant-0.0.24.tar.gz (2.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

biosimulant-0.0.24-py3-none-any.whl (2.5 MB view details)

Uploaded Python 3

File details

Details for the file biosimulant-0.0.24.tar.gz.

File metadata

  • Download URL: biosimulant-0.0.24.tar.gz
  • Upload date:
  • Size: 2.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for biosimulant-0.0.24.tar.gz
Algorithm Hash digest
SHA256 5790669667e56e7418c0744ce87b0c46e73c92db2dbf4b4beec93be569dc2273
MD5 8a7a9a2e2dc20a76d145ab666e190b5b
BLAKE2b-256 2f903b4649c5f0ed9744563445071782861e2a5acc729db9eb75f7b244209c75

See more details on using hashes here.

Provenance

The following attestation bundles were made for biosimulant-0.0.24.tar.gz:

Publisher: publish-pypi.yml on Biosimulant/biosim

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file biosimulant-0.0.24-py3-none-any.whl.

File metadata

  • Download URL: biosimulant-0.0.24-py3-none-any.whl
  • Upload date:
  • Size: 2.5 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for biosimulant-0.0.24-py3-none-any.whl
Algorithm Hash digest
SHA256 cc63afd2c0ec38f89a26b6a043e2290c86f70edd6f158eb4135d77686b2ea8fd
MD5 f261de3ea6b6005abaef0370f72f12b5
BLAKE2b-256 7d36a486579b19dcbf6608d2edaa560353415173caa7d42a949e8c3c328c8279

See more details on using hashes here.

Provenance

The following attestation bundles were made for biosimulant-0.0.24-py3-none-any.whl:

Publisher: publish-pypi.yml on Biosimulant/biosim

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page