Big update: PLR is now asynchronous

PyLabRobot is now asynchronous, based on Python’s asyncio. This will make the implementation of complex methods significantly easier.

Each operation can be awaited using await:

await lh.aspirate(...)


fut = lh.aspirate(...)
# do something else in between
await fut

In IPython/Jupyter Notebooks, you can use await directly.

In scripts, I recommend using

import asyncio

async def my_method():
    await lh.aspirate(...)

One of the many neat features of asyncio is gather, which can be used to run two actions simultaneously:

async def pipetting_sequence():
  await lh.aspirate(...)
  await lh.dispense(...)


Depending on the model of robot, running two ‘active operations’ (such as aspirate/dispense) simultaneously might raise an error. This is the case on STAR. You can, however, aspirate while performing ‘passive operations’.


This is amazing! Congrats!

1 Like

This is great Rick, I was actually postponing writing the Klipper backend because it relies on asyncio. This greatly simplifies things.

A quick feedback on my experience with using-the-simulator.ipynb. Everything seems to work except for the following:

  • Cell 21: set_well_volumes is not awaitable, and it raises an error.
  • Cell 32: (tip_car[0].resource) is not awaitable, and a TypeError is also raised.
Bonus: unrelated to asyncio but possibly helpful.
  • The included screenshots seem outdated and led me to some minor confusion.
  • An effect of dropping tips is that they placed back into the tip racks: is this the expected behaviour?
  • The simulator looks a bit off, I’m using Chromium:

Amazing work!

1 Like