Receber por email
← Voltar para o catálogo

pylabrobot

Hardware-agnostic Python liquid-handler library: portable scripts run on Hamilton STAR, Tecan Freedom EVO, Opentrons OT-2, or a simulator without vendor lock-in. For protocol automation, method dev, plate reformatting, serial dilutions, and Python lab workflows.

207estrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: NOASSERTION

Como adicionar

/plugin marketplace add jaechang-hits/SciAgent-Skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/pylabrobot-jaechang-hits/svg)](https://www.skillteca.com.br/skills/pylabrobot-jaechang-hits)

Skills relacionadas

Ver todas de Automação →

Alerta por categoria

Receba novas skills de Automação toda segunda

1 email curto, só com as skills novas de Automação. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

pylabrobot

Overview

PyLabRobot is an open-source Python library that abstracts liquid handling robot hardware behind a unified API. Write a protocol once and run it on any supported robot — Hamilton STAR, Tecan Freedom EVO, Opentrons OT-2, or a simulated backend — without changing the protocol code. PyLabRobot handles deck layout, resource management, and aspirate/dispense operations through a clean, async-first interface.

When to Use

  • Writing portable liquid handling protocols: You want a single Python script that works across Hamilton, Tecan, Opentrons, and a simulator without code changes.
  • Developing and testing protocols before robot time: Use the simulation backend to validate logic, volumes, and deck layouts without occupying physical hardware.
  • Automating plate reformatting and cherry-picking: Transfer specific wells between plates based on upstream data (e.g., hit compounds from a screen).
  • Building serial dilution curves: Systematically aspirate and dispense across a plate with precise volume steps.
  • Integrating liquid handling into Python data pipelines: Trigger robot actions from analysis code, LIMS queries, or machine learning models.
  • Rapid method development: Iterate quickly in Python rather than in vendor-specific scripting environments.
  • For Opentrons-specific features (temperature module control, built-in app integration), use the opentrons Python SDK instead; for multi-vendor portability use PyLabRobot.

Prerequisites

  • Python packages: pylabrobot
  • Optional backends: pylabrobot[hamilton] for Hamilton STAR, pylabrobot[opentrons] for OT-2
  • Data requirements: None — deck resources are defined in Python
  • Environment: Python 3.9+; physical robot drivers installed separately per vendor docs
pip install pylabrobot
pip install "pylabrobot[hamilton]"   # add Hamilton USB driver
pip install "pylabrobot[opentrons]"  # add Opentrons REST driver

Quick Start

import asyncio
from pylabrobot.liquid_handling import LiquidHandler
from pylabrobot.liquid_handling.backends import SimulatorBackend
from pylabrobot.resources import Deck, Cos_96_Rd, HTF_L

async def main():
    backend = SimulatorBackend(open_browser=False)
    lh = LiquidHandler(backend=backend, deck=Deck())
    await lh.setup()

    plate = Cos_96_Rd(name="plate")
    tips  = HTF_L(name="tips")
    lh.deck.assign_child_resource(plate, rails=2)
    lh.deck.assign_child_resource(tips,  rails=5)

    await lh.pick_up_tips(tips["A1"])
    await lh.aspirate(plate["A1"], vols=50)
    await lh.dispense(plate["B1"], vols=50)
    await lh.drop_tips(tips["A1"])
    await lh.stop()
    print("Transfer complete: 50 uL from A1 -> B1")

asyncio.run(main())

Core API

Module 1: LiquidHandler — Setup and Teardown

The LiquidHandler class is the central controller. It wraps a backend and a Deck.

import asyncio
from pylabrobot.liquid_handling import LiquidHandler
from pylabrobot.liquid_handling.backends import SimulatorBackend
from pylabrobot.resources import Deck

async def main():
    backend = SimulatorBackend(open_browser=False)
    lh = LiquidHandler(backend=backend, deck=Deck())
    await lh.setup()      # connect to hardware / start simulator
    print("LiquidHandler ready:", lh)
    await lh.stop()       # disconnect cleanly

asyncio.run(main())
# Connecting to a real Hamilton STAR
from pylabrobot.liquid_handling.backends.hamilton import STAR

async def main():
    backend = STAR()
    lh = LiquidHandler(backend=backend, deck=Deck())
    await lh.setup()
    # lh is now connected to physical hardware
    await lh.stop()

Module 2: Deck and Resource Assignment

Resources (plates, tip racks, reservoirs) are placed on the deck by rail position.

from pylabrobot.resources import (
    Deck,
    Cos_96_Rd,                  # Corning 96-well round-bottom plate
    Cos_384_Sq,                 # Corning 384-well plate
    HTF_L,                      # Hamilton tip rack (filtered, large)
    Trough_1_Row_1_Col_4,       # 4-channel reservoir
)

deck = Deck()
plate_96  = Cos_96_Rd(name="sample_plate")
plate_384 = Cos_384_Sq(name="assay_plate")
tips      = HTF_L(name="tip_rack")
reservoir = Trough_1_Row_1_Col_4(name="buffer")

deck.assign_child_resource(plate_96,  rails=1)
deck.assign_child_resource(plate_384, rails=4)
deck.assign_child_resource(tips,      rails=8)
deck.assign_child_resource(reservoir, rails=11)

print("Deck resources:", [r.name for r in deck.children])

Module 3: Tip Operations

Pick up and drop tips before and after liquid operations.

# Pick up tips from the first column of the tip rack
await lh.pick_up_tips(tips["A1:H1"])   # all 8 tips in column 1

# After liquid operations, drop tips back
await lh.drop_tips(tips["A1:H1"])

# Single tip
await lh.pick_up_tips(tips["A1"])
await lh.drop_tips(tips["A1"])
print("Tip operations complete")

Module 4: Aspirate Operations

Aspirate liquid from wells. Accepts single wells, ranges, or lists.

# Aspirate 100 uL from a single well
await lh.aspirate(plate["A1"], vols=100)

# Aspirate different volumes from multiple wells simultaneously
await lh.aspirate(
    plate["A1:A4"],
    vols=[50, 75, 100, 125],
)
print("Aspiration complete")
from pylabrobot.resources import Coordinate

# Aspirate with flow rate and liquid height control
await lh.aspirate(
    plate["A1"],
    vols=50,
    flow_rates=100,                    # uL/s
    offsets=Coordinate(0, 0, 1),       # 1 mm above well bottom
)

Module 5: Dispense Operations

Dispense liquid into target wells.

# Dispense 100 uL into a single well
await lh.dispense(plate["B1"], vols=100)

# Multi-well dispense with different volumes
await lh.dispense(
    plate["B1:B4"],
    vols=[50, 75, 100, 125],
)
print("Dispense complete")

Module 6: Transfer — High-Level Convenience

transfer combines aspirate and dispense for simple source-to-destination moves.

# Transfer 50 uL from A1 -> B1
await lh.transfer(plate["A1"], plate["B1"], transfer_volume=50)

# Multi-well pairwise transfer
sources      = plate["A1:A8"]
destinations = plate["B1:B8"]
await lh.transfer(sources, destinations, transfer_volume=75)
print("Transfer complete")

Module 7: Simulation Backend

The SimulatorBackend runs a browser-based visualizer for protocol debugging.

from pylabrobot.liquid_handling.backends import SimulatorBackend

# With visual browser (default — opens http://localhost:2121)
backend = SimulatorBackend(open_browser=True)

# Headless simulation (CI/testing)
backend = SimulatorBackend(open_browser=False)

# After setup(), liquid movements are visualized in real time
await lh.setup()
# Check browser for visual confirmation before running on real hardware
print("Simulator running at http://localhost:2121")

Key Concepts

Async-First Design

All robot operations (setup, aspirate, dispense, transfer) are Python async coroutines. Run them inside an async def function using asyncio.run() or Jupyter's top-level await syntax.

import asyncio

async def run_protocol(lh, plate, tips):
    await lh.pick_up_tips(tips["A1"])
    await lh.aspirate(plate["A1"], vols=50)
    await lh.dispense(plate["B1"], vols=50)
    await lh.drop_tips(tips["A1"])
    print("Protocol complete")

asyncio.run(run_protocol(lh, plate, tips))

Well Addressing

Wells are addressed by alphanumeric position ("A1") or slice notation ("A1:H1" for a column, "A1:A12" for a row).

well    = plate["A1"]             # single well
col1    = plate["A1:H1"]          # 8 wells in column 1
row_a   = plate["A1:A12"]         # 12 wells in row A
print(f"Single: {well.name}")
print(f"Column: {len(col1)} wells")
print(f"Row:    {len(row_a)} wells")

Common Workflows

Workflow 1: 96-Well Serial Dilution

Goal: Perform a 2-fold serial dilution across

Compartilhar X LinkedIn