Unified API layer for wet lab automation across multiple providers.
Project description
Refua WetLab
Refua WetLab is a standalone project that exposes a unified HTTP API for wet-lab automation workflows.
It provides:
- A canonical protocol schema for common liquid-handling and assay operations.
- Provider adapters that compile canonical steps into provider-specific commands.
- Async run orchestration with status tracking and cancellation.
- A simulation-safe execution mode (
dry_run) for workflow development. - Inventory-aware simulation checks to catch impossible liquid moves before hardware time is spent.
- Priority-based background scheduling for urgent protocols.
- A built-in LMS layer for project/sample/plate/inventory/experiment management.
- End-to-end audit trails and LMS summaries (low-stock + expiring-material alerts).
Quick Start
cd refua-wetlab
pip install -e .
refua-wetlab --host 127.0.0.1 --port 8790
API Endpoints
Core WetLab API:
GET /api/healthGET /api/providersPOST /api/protocols/validatePOST /api/protocols/compilePOST /api/runsGET /api/runsGET /api/runs/{run_id}GET /api/runs/{run_id}/lineagePOST /api/runs/{run_id}/cancel
LMS API:
GET /api/lmsGET /api/lms/summaryGET /api/lms/auditGET /api/lms/projectsPOST /api/lms/projectsGET /api/lms/projects/{project_id}POST /api/lms/projects/{project_id}/statusGET /api/lms/samplesPOST /api/lms/samplesGET /api/lms/samples/{sample_id}POST /api/lms/samples/{sample_id}/statusGET /api/lms/samples/{sample_id}/eventsPOST /api/lms/samples/{sample_id}/eventsGET /api/lms/platesPOST /api/lms/platesGET /api/lms/plates/{plate_id}POST /api/lms/plates/{plate_id}/assignmentsGET /api/lms/inventory/itemsPOST /api/lms/inventory/itemsGET /api/lms/inventory/items/{item_id}POST /api/lms/inventory/items/{item_id}/transactionsGET /api/lms/inventory/items/{item_id}/transactionsGET /api/lms/experimentsPOST /api/lms/experimentsGET /api/lms/experiments/{experiment_id}POST /api/lms/experiments/{experiment_id}/statusPOST /api/lms/experiments/{experiment_id}/schedule-run
Python API
refua-wetlab now ships a direct Python LMS API so callers can use LMS workflows
without going through HTTP handlers.
from pathlib import Path
from refua_wetlab import LmsApi, LmsStore, UnifiedWetLabEngine
from refua_wetlab.runner import RunBackgroundRunner
from refua_wetlab.storage import RunStore
db_path = Path(".refua-wetlab") / "runs.sqlite3"
run_store = RunStore(db_path)
lms_store = LmsStore(db_path)
runner = RunBackgroundRunner(run_store, max_workers=2)
api = LmsApi(
lms_store=lms_store,
run_store=run_store,
runner=runner,
engine=UnifiedWetLabEngine(),
)
project = api.route_post(path="/api/lms/projects", payload={"name": "KRAS campaign"})
summary = api.route_get(path="/api/lms/summary")
api.shutdown()
Example Protocol
{
"name": "serial-dilution-screen",
"steps": [
{
"type": "transfer",
"source": "plate:A1",
"destination": "plate:B1",
"volume_ul": 50
},
{
"type": "mix",
"well": "plate:B1",
"volume_ul": 40,
"cycles": 5
},
{
"type": "incubate",
"duration_s": 900,
"temperature_c": 37
},
{
"type": "read_absorbance",
"plate": "plate",
"wavelength_nm": 450
}
]
}
Compile For A Provider
curl -s http://127.0.0.1:8790/api/protocols/compile \
-X POST \
-H "Content-Type: application/json" \
-d '{
"provider": "opentrons",
"protocol": {
"name": "serial-dilution-screen",
"steps": [
{"type":"transfer","source":"plate:A1","destination":"plate:B1","volume_ul":50}
]
}
}' | jq
Create Async Run
curl -s http://127.0.0.1:8790/api/runs \
-X POST \
-H "Content-Type: application/json" \
-d '{
"provider": "hamilton",
"async_mode": true,
"dry_run": true,
"priority": 80,
"protocol": {
"name": "screen-v1",
"inventory": {
"plate:A1": 120.0,
"plate:B1": 0.0
},
"steps": [
{"type":"transfer","source":"plate:A1","destination":"plate:B1","volume_ul":20},
{"type":"incubate","duration_s":300}
]
}
}' | jq
LMS Workflow Example
# 1) Create project
PROJECT_ID=$(curl -s http://127.0.0.1:8790/api/lms/projects \
-X POST -H "Content-Type: application/json" \
-d '{"name":"KRAS campaign","owner":"wetlab-team"}' | jq -r '.project.project_id')
# 2) Register sample
SAMPLE_ID=$(curl -s http://127.0.0.1:8790/api/lms/samples \
-X POST -H "Content-Type: application/json" \
-d '{
"project_id":"'"$PROJECT_ID"'",
"name":"KRAS_clone_1",
"sample_type":"cell_lysate",
"volume_ul":120
}' | jq -r '.sample.sample_id')
# 3) Create experiment with protocol
EXP_ID=$(curl -s http://127.0.0.1:8790/api/lms/experiments \
-X POST -H "Content-Type: application/json" \
-d '{
"project_id":"'"$PROJECT_ID"'",
"name":"KRAS absorbance screen",
"provider":"opentrons",
"sample_ids":["'"$SAMPLE_ID"'"],
"protocol": {
"name":"kras-screen",
"steps":[
{"type":"transfer","source":"plate:A1","destination":"plate:B1","volume_ul":20},
{"type":"mix","well":"plate:B1","volume_ul":15,"cycles":4},
{"type":"read_absorbance","plate":"plate","wavelength_nm":450}
]
}
}' | jq -r '.experiment.experiment_id')
# 4) Schedule run from experiment
curl -s http://127.0.0.1:8790/api/lms/experiments/$EXP_ID/schedule-run \
-X POST -H "Content-Type: application/json" \
-d '{"async_mode":false,"dry_run":true,"priority":85}' | jq
# 5) Get LMS summary
curl -s http://127.0.0.1:8790/api/lms/summary | jq
Scope And Limitations
refua-wetlab is a simulation-first orchestration layer intended for protocol
design, dry-run validation, run metadata tracking, and LMS operations.
Current limitations:
- Provider execution in this package is mock/simulated; it does not drive real robotic hardware without an external adapter/runtime bridge.
- The canonical protocol model covers common liquid-handling and plate-read operations, not every vendor-native instruction.
- Scheduling is process-local and SQLite-backed; it is not a distributed queue.
- LMS data model is lightweight and embedded; it is not a replacement for enterprise LIMS/ELN systems.
- Auth is bearer-token based; there is no built-in SSO, RBAC policy engine, or audit-signature workflow.
- This package does not provide GxP/21 CFR Part 11 compliance guarantees.
Production Notes
- Treat this as an orchestration service, not as the final source of truth for regulated records.
- Run behind a trusted gateway (TLS termination, centralized authn/authz, request logging, and secrets management).
- Use routine backups for the SQLite database or replace storage with a managed backend in your deployment architecture.
Development
cd refua-wetlab
python -m unittest discover -s tests -v
Build artifacts:
cd refua-wetlab
python -m build
python -m twine check dist/*
CI And Hooks
- GitHub Actions CI:
.github/workflows/ci.yml - Pre-commit config:
.pre-commit-config.yaml
Run hooks locally:
cd refua-wetlab
pre-commit run --all-files
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file refua_wetlab-0.7.1.tar.gz.
File metadata
- Download URL: refua_wetlab-0.7.1.tar.gz
- Upload date:
- Size: 42.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.14.3 Darwin/25.3.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b355cc3087c773f957070cf18b37e033a8e1fdbed99a9b196fcf5c345f1431c
|
|
| MD5 |
8e693fef61dc15ba3a9bfa10aabcd9cc
|
|
| BLAKE2b-256 |
320213db8d26f1e12bc9e8130db6ebf6feb3826f5027f9eced6761e7396bcdcb
|
File details
Details for the file refua_wetlab-0.7.1-py3-none-any.whl.
File metadata
- Download URL: refua_wetlab-0.7.1-py3-none-any.whl
- Upload date:
- Size: 39.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.14.3 Darwin/25.3.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
baca5c60b56901194e626a45425d4d91e21b105f17914cc538b80b6d71f630bf
|
|
| MD5 |
aa87b640cbbcff5e77a3b4f2c225c1e0
|
|
| BLAKE2b-256 |
63ae8d1f020a449562bf26e1bd1fcb9c2ac42d2727b80c192a24f8e4a3b2ae7f
|