| name | opentrons-integration |
| description | Lab automation platform for Flex/OT-2 robots. Write Protocol API v2 protocols, liquid handling, hardware modules (heater-shaker, thermocycler), labware management, for automated pipetting workflows. |
Opentrons Integration
Overview
Opentrons is a Python-based lab automation platform for Flex and OT-2 robots. Write Protocol API v2 protocols for liquid handling, control hardware modules (heater-shaker, thermocycler), manage labware, for automated pipetting workflows.
When to Use This Skill
This skill should be used when:
- Writing Opentrons Protocol API v2 protocols in Python
- Automating liquid handling workflows on Flex or OT-2 robots
- Controlling hardware modules (temperature, magnetic, heater-shaker, thermocycler)
- Setting up labware configurations and deck layouts
- Implementing complex pipetting operations (serial dilutions, plate replication, PCR setup)
- Managing tip usage and optimizing protocol efficiency
- Working with multi-channel pipettes for 96-well plate operations
- Simulating and testing protocols before robot execution
Core Capabilities
1. Protocol Structure and Metadata
Every Opentrons protocol follows a standard structure:
from opentrons import protocol_api
metadata = {
'protocolName': 'My Protocol',
'author': 'Name <email@example.com>',
'description': 'Protocol description',
'apiLevel': '2.19'
}
requirements = {
'robotType': 'Flex',
'apiLevel': '2.19'
}
def run(protocol: protocol_api.ProtocolContext):
pass
Key elements:
- Import
protocol_api from opentrons
- Define
metadata dict with protocolName, author, description, apiLevel
- Optional
requirements dict for robot type and API version
- Implement
run() function receiving ProtocolContext as parameter
- All protocol logic goes inside the
run() function
2. Loading Hardware
Loading Instruments (Pipettes):
def run(protocol: protocol_api.ProtocolContext):
left_pipette = protocol.load_instrument(
'p1000_single_flex',
'left',
tip_racks=[tip_rack]
)
Common pipette names:
- Flex:
p50_single_flex, p1000_single_flex, p50_multi_flex, p1000_multi_flex
- OT-2:
p20_single_gen2, p300_single_gen2, p1000_single_gen2, p20_multi_gen2, p300_multi_gen2
Loading Labware:
plate = protocol.load_labware(
'corning_96_wellplate_360ul_flat',
'D1',
label='Sample Plate'
)
tip_rack = protocol.load_labware('opentrons_flex_96_tiprack_1000ul', 'C1')
adapter = protocol.load_adapter('opentrons_flex_96_tiprack_adapter', 'B1')
tips = adapter.load_labware('opentrons_flex_96_tiprack_200ul')
Loading Modules:
temp_module = protocol.load_module('temperature module gen2', 'D3')
temp_plate = temp_module.load_labware('corning_96_wellplate_360ul_flat')
mag_module = protocol.load_module('magnetic module gen2', 'C2')
mag_plate = mag_module.load_labware('nest_96_wellplate_100ul_pcr_full_skirt')
hs_module = protocol.load_module('heaterShakerModuleV1', 'D1')
hs_plate = hs_module.load_labware('corning_96_wellplate_360ul_flat')
tc_module = protocol.load_module('thermocyclerModuleV2')
tc_plate = tc_module.load_labware('nest_96_wellplate_100ul_pcr_full_skirt')
3. Liquid Handling Operations
Basic Operations:
pipette.pick_up_tip()
pipette.aspirate(
volume=100,
location=source['A1']
)
pipette.dispense(
volume=100,
location=dest['B1']
)
pipette.drop_tip()
pipette.return_tip()
Complex Operations:
pipette.transfer(
volume=100,
source=source_plate['A1'],
dest=dest_plate['B1'],
new_tip='always'
)
pipette.distribute(
volume=50,
source=reservoir['A1'],
dest=[plate['A1'], plate['A2'], plate['A3']],
new_tip='once'
)
pipette.consolidate(
volume=50,
source=[plate['A1'], plate['A2'], plate['A3']],
dest=reservoir['A1'],
new_tip='once'
)
Advanced Techniques:
pipette.mix(
repetitions=3,
volume=50,
location=plate['A1']
)
pipette.aspirate(100, source['A1'])
pipette.air_gap(20)
pipette.dispense(120, dest['A1'])
pipette.blow_out(location=dest['A1'].top())
pipette.touch_tip(location=plate['A1'])
Flow Rate Control:
pipette.flow_rate.aspirate = 150
pipette.flow_rate.dispense = 300
pipette.flow_rate.blow_out = 400
4. Accessing Wells and Locations
Well Access Methods:
well_a1 = plate['A1']
first_well = plate.wells()[0]
all_wells = plate.wells()
rows = plate.rows()
row_a = plate.rows()[0]
columns = plate.columns()
column_1 = plate.columns()[0]
wells_dict = plate.wells_by_name()
Location Methods:
pipette.aspirate(100, well.top())
pipette.aspirate(100, well.top(z=5))
pipette.aspirate(100, well.bottom())
pipette.aspirate(100, well.bottom(z=2))
pipette.aspirate(100, well.center())
5. Hardware Module Control
Temperature Module:
temp_module.set_temperature(celsius=4)
temp_module.await_temperature(celsius=4)
temp_module.deactivate()
current_temp = temp_module.temperature
target_temp = temp_module.target
Magnetic Module:
mag_module.engage(height_from_base=10)
mag_module.disengage()
is_engaged = mag_module.status
Heater-Shaker Module:
hs_module.set_target_temperature(celsius=37)
hs_module.wait_for_temperature()
hs_module.set_and_wait_for_shake_speed(rpm=500)
hs_module.close_labware_latch()
hs_module.open_labware_latch()
hs_module.deactivate_heater()
hs_module.deactivate_shaker()
Thermocycler Module:
tc_module.open_lid()
tc_module.close_lid()
tc_module.set_lid_temperature(celsius=105)
tc_module.set_block_temperature(
temperature=95,
hold_time_seconds=30,
hold_time_minutes=0.5,
block_max_volume=50
)
profile = [
{'temperature': 95, 'hold_time_seconds': 30},
{'temperature': 57, 'hold_time_seconds': 30},
{'temperature': 72, 'hold_time_seconds': 60}
]
tc_module.execute_profile(
steps=profile,
repetitions=30,
block_max_volume=50
)
tc_module.deactivate_lid()
tc_module.deactivate_block()
Absorbance Plate Reader:
result = plate_reader.read(wavelengths=[450, 650])
absorbance_data = result
6. Liquid Tracking and Labeling
Define Liquids:
water = protocol.define_liquid(
name='Water',
description='Ultrapure water',
display_color='#0000FF'
)
sample = protocol.define_liquid(
name='Sample',
description='Cell lysate sample',
display_color='#FF0000'
)
Load Liquids into Wells:
reservoir['A1'].load_liquid(liquid=water, volume=50000)
plate['A1'].load_liquid(liquid=sample, volume=100)
plate['B1'].load_empty()
7. Protocol Control and Utilities
Execution Control:
protocol.pause(msg='Replace tip box and resume')
protocol.delay(seconds=60)
protocol.delay(minutes=5)
protocol.comment('Starting serial dilution')
protocol.home()
Conditional Logic:
if protocol.is_simulating():
protocol.comment('Running in simulation mode')
else:
protocol.comment('Running on actual robot')
Rail Lights (Flex only):
protocol.set_rail_lights(on=True)
protocol.set_rail_lights(on=False)
8. Multi-Channel and 8-Channel Pipetting
When using multi-channel pipettes:
multi_pipette = protocol.load_instrument(
'p300_multi_gen2',
'left',
tip_racks=[tips]
)
multi_pipette.transfer(
volume=100,
source=source_plate['A1'],
dest=dest_plate['A1']
)
for row in plate.rows():
multi_pipette.transfer(100, reservoir['A1'], row[0])
9. Common Protocol Patterns
Serial Dilution:
def run(protocol: protocol_api.ProtocolContext):
tips = protocol.load_labware('opentrons_flex_96_tiprack_200ul', 'D1')
reservoir = protocol.load_labware('nest_12_reservoir_15ml', 'D2')
plate = protocol.load_labware('corning_96_wellplate_360ul_flat', 'D3')
p300 = protocol.load_instrument('p300_single_flex', 'left', tip_racks=[tips])
p300.transfer(100, reservoir['A1'], plate.rows()[0][1:])
p300.transfer(
100,
plate.rows()[0][:11],
plate.rows()[0][1:],
mix_after=(3, 50),
new_tip='always'
)
Plate Replication:
def run(protocol: protocol_api.ProtocolContext):
tips = protocol.load_labware('opentrons_flex_96_tiprack_1000ul', 'C1')
source = protocol.load_labware('corning_96_wellplate_360ul_flat', 'D1')
dest = protocol.load_labware('corning_96_wellplate_360ul_flat', 'D2')
p1000 = protocol.load_instrument('p1000_single_flex', 'left', tip_racks=[tips])
p1000.transfer(
100,
source.wells(),
dest.wells(),
new_tip='always'
)
PCR Setup:
def run(protocol: protocol_api.ProtocolContext):
tc_mod = protocol.load_module('thermocyclerModuleV2')
tc_plate = tc_mod.load_labware('nest_96_wellplate_100ul_pcr_full_skirt')
tips = protocol.load_labware('opentrons_flex_96_tiprack_200ul', 'C1')
reagents = protocol.load_labware('opentrons_24_tuberack_nest_1.5ml_snapcap', 'D1')
p300 = protocol.load_instrument('p300_single_flex', 'left', tip_racks=[tips])
tc_mod.open_lid()
p300.distribute(
20,
reagents['A1'],
tc_plate.wells(),
new_tip='once'
)
for i, well in enumerate(tc_plate.wells()[:8]):
p300.transfer(5, reagents.wells()[i+1], well, new_tip='always')
tc_mod.close_lid()
tc_mod.set_lid_temperature(105)
tc_mod.set_block_temperature(95, hold_time_seconds=180)
profile = [
{'temperature': 95, 'hold_time_seconds': 15},
{'temperature': 60, 'hold_time_seconds': 30},
{'temperature': 72, 'hold_time_seconds': 30}
]
tc_mod.execute_profile(steps=profile, repetitions=35, block_max_volume=25)
tc_mod.set_block_temperature(72, hold_time_minutes=5)
tc_mod.set_block_temperature(4)
tc_mod.deactivate_lid()
tc_mod.open_lid()
Best Practices
- Always specify API level: Use the latest stable API version in metadata
- Use meaningful labels: Label labware for easier identification in logs
- Check tip availability: Ensure sufficient tips for protocol completion
- Add comments: Use
protocol.comment() for debugging and logging
- Simulate first: Always test protocols in simulation before running on robot
- Handle errors gracefully: Add pauses for manual intervention when needed
- Consider timing: Use delays when protocols require incubation periods
- Track liquids: Use liquid tracking for better setup validation
- Optimize tip usage: Use
new_tip='once' when appropriate to save tips
- Control flow rates: Adjust flow rates for viscous or volatile liquids
Troubleshooting
Common Issues:
- Out of tips: Verify tip rack capacity matches protocol requirements
- Labware collisions: Check deck layout for spatial conflicts
- Volume errors: Ensure volumes don't exceed well or pipette capacities
- Module not responding: Verify module is properly connected and firmware is updated
- Inaccurate volumes: Calibrate pipettes and check for air bubbles
- Protocol fails in simulation: Check API version compatibility and labware definitions
Resources
For detailed API documentation, see references/api_reference.md in this skill directory.
For example protocol templates, see scripts/ directory.