Pylabrobot Dynamic
Powerful skill for laboratory, automation, toolkit, controlling. Includes structured workflows, validation checks, and reusable patterns for scientific.
PyLabRobot Dynamic
Control laboratory automation hardware using PyLabRobot, a hardware-agnostic Python SDK for liquid handling robots, plate readers, and lab instruments. This skill covers device control, protocol writing, labware management, and building automated experimental workflows across multiple instrument vendors.
When to Use This Skill
Choose PyLabRobot Dynamic when you need to:
- Control liquid handling robots from Python (Hamilton, Opentrons, Tecan)
- Write hardware-agnostic lab automation protocols that work across platforms
- Coordinate multiple instruments (robots, plate readers, incubators) in a workflow
- Build custom automation routines beyond vendor-provided software capabilities
Consider alternatives when:
- You only need Opentrons-specific features (use Opentrons API directly)
- You need cloud-based workflow deployment (use Latch SDK)
- You need scheduling across many instruments (use LIMS/scheduling platforms)
Quick Start
pip install pylabrobot
from pylabrobot.liquid_handling import LiquidHandler from pylabrobot.liquid_handling.backends import ChatterBoxBackend from pylabrobot.resources import ( Plate, TipRack, Reservoir, HTF_L, Cos_96_EZWash ) # Initialize with simulator backend (for development) lh = LiquidHandler(backend=ChatterBoxBackend()) await lh.setup() # Define deck layout tip_rack = TipRack(name="tips", size_x=127.76, size_y=85.48, size_z=100) plate = Cos_96_EZWash(name="assay_plate") reservoir = Reservoir(name="reagent_reservoir") lh.deck.assign_child_at_slot(tip_rack, slot=1) lh.deck.assign_child_at_slot(plate, slot=3) lh.deck.assign_child_at_slot(reservoir, slot=5) # Simple transfer await lh.pick_up_tips(tip_rack["A1:H1"]) await lh.aspirate(reservoir["A1"], vols=[200] * 8) await lh.dispense(plate["A1:H1"], vols=[200] * 8) await lh.drop_tips(tip_rack["A1:H1"]) await lh.stop()
Core Concepts
Architecture
| Layer | Component | Purpose |
|---|---|---|
| Protocol | User code | Define experimental steps |
| LiquidHandler | Core API | Hardware-agnostic operations |
| Backend | Driver | Vendor-specific communication |
| Resources | Labware | Plates, tips, reservoirs definitions |
| Deck | Layout | Physical arrangement of labware |
Supported Backends
| Backend | Hardware | Status |
|---|---|---|
ChatterBoxBackend | Simulator (prints commands) | Development |
HamiltonSTAR | Hamilton STAR/Vantage | Production |
OpentronsBackend | Opentrons OT-2/Flex | Production |
TecanBackend | Tecan EVO/FluentControl | Beta |
Complex Protocol: Dose-Response Assay
from pylabrobot.liquid_handling import LiquidHandler import numpy as np async def dose_response_assay(lh, compound_conc_uM, dilution_factor=3, n_concentrations=8, n_replicates=3): """Automated dose-response curve setup.""" # Calculate concentrations concentrations = [ compound_conc_uM / (dilution_factor ** i) for i in range(n_concentrations) ] plate = lh.deck.get_resource("assay_plate") compound_res = lh.deck.get_resource("compound_reservoir") media_res = lh.deck.get_resource("media_reservoir") tips = lh.deck.get_resource("tips") # Step 1: Add media to all wells await lh.pick_up_tips(tips["A1:H1"]) for col in range(12): wells = plate.get_wells(f"A{col+1}:H{col+1}") await lh.aspirate(media_res["A1"], vols=[180] * 8) await lh.dispense(wells, vols=[180] * 8) await lh.drop_tips(tips["A1:H1"]) # Step 2: Serial dilution of compound await lh.pick_up_tips(tips["A2:H2"]) # Add highest concentration to column 1 await lh.aspirate(compound_res["A1"], vols=[20] * 8) await lh.dispense(plate.get_wells("A1:H1"), vols=[20] * 8) # Serial dilution across columns for col in range(n_concentrations - 1): source = plate.get_wells(f"A{col+1}:H{col+1}") dest = plate.get_wells(f"A{col+2}:H{col+2}") await lh.aspirate(source, vols=[67] * 8) # 1:3 dilution await lh.dispense(dest, vols=[67] * 8) # Mix for _ in range(3): await lh.aspirate(dest, vols=[100] * 8) await lh.dispense(dest, vols=[100] * 8) await lh.drop_tips(tips["A2:H2"]) return concentrations
Configuration
| Parameter | Description | Default |
|---|---|---|
backend | Hardware backend driver | Required |
deck_layout | Physical slot assignments | Protocol-specific |
aspiration_speed | Aspiration rate (ยตL/s) | 100 |
dispense_speed | Dispensing rate (ยตL/s) | 100 |
tip_type | Tip rack specification | Backend-dependent |
liquid_class | Liquid handling parameters | "default" |
Best Practices
-
Develop with ChatterBoxBackend first โ The simulator backend prints all commands without moving hardware. Use it to verify protocol logic, tip usage, and deck layout before running on real equipment. This prevents wasted reagents and potential collisions.
-
Define labware with exact physical dimensions โ Incorrect labware dimensions cause tip crashes or missed wells. Use manufacturer specifications for well positions, depths, and plate heights. Verify with a test run using water before real reagents.
-
Track tip usage carefully โ Running out of tips mid-protocol is a common failure. Calculate total tips needed before starting and verify tip rack capacity. For long protocols, add tip rack swaps at defined protocol checkpoints.
-
Use async/await consistently โ PyLabRobot uses asyncio for hardware communication. All liquid handling operations must be
awaited. Forgettingawaitcauses commands to be scheduled but not executed, producing confusing results. -
Add error recovery checkpoints โ Insert
lh.deck.summary()calls at protocol milestones to verify deck state. If an error occurs, the protocol can resume from the last checkpoint rather than restarting from the beginning.
Common Issues
"Resource not found on deck" error โ The resource name in your protocol doesn't match the assigned deck resource. Use lh.deck.summary() to see all assigned resources and their names. Names are case-sensitive and must match exactly.
Liquid not aspirating despite correct volumes โ The aspiration height may be above the liquid surface. Adjust liquid level tracking or manually set aspiration height: await lh.aspirate(well, vols=[200], offsets=[Coordinate(0, 0, -5)]) to lower the tip 5mm below the default position.
Backend connection fails โ Ensure the instrument is powered on and connected via USB or network. For Hamilton STAR, the VENUS software must not be running simultaneously. For Opentrons, the robot must be in "Jupyter mode" or API access must be enabled in the settings.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.