Run lifecycle
Every server execution is a durable job. The external states are:
queued → running → completed
↘ failed
↘ timed_out
queued/running → cancelledPOST /runs returns 202 Accepted and a Location header. The SDK’s runs.create() maps that response to a Run or AsyncRun handle.
Wait and refresh
run.wait(timeout=300) polls with bounded exponential backoff. The timeout applies to the caller only. If it expires, RunTimeout.run retains the handle and the cloud execution continues.
from biosimulant import Client, RunTimeout
with Client() as client:
run = client.runs.create(ref="demi/microbiology-hello-world-growth@1.0.0")
try:
result = run.wait(timeout=30)
except RunTimeout as exc:
print("still running", exc.run.id)Cancel
run.cancel()Cancellation is idempotent. A completed, failed, cancelled, or timed-out run remains in its terminal state.
Events
Use GET /runs/{id}/events?after=<cursor> for progress and logs. Save next_cursor and pass it as after on the next request. Polling is the canonical SDK transport for the first release; public WebSocket and SSE connections are not required.
Results and artifacts
Results become available after completed. GET /runs/{id}/results returns lab-level outputs, artifact descriptors, and provenance. Download an artifact only through its run-scoped URL; authorization is checked against the owning account.