-
Notifications
You must be signed in to change notification settings - Fork 179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(protocol-engine): Support loading pipettes and labware from JSON protocols #7950
Conversation
Codecov Report
@@ Coverage Diff @@
## edge #7950 +/- ##
==========================================
+ Coverage 85.93% 86.06% +0.13%
==========================================
Files 348 348
Lines 21232 21471 +239
==========================================
+ Hits 18245 18479 +234
- Misses 2987 2992 +5
Continue to review full report at Codecov.
|
Just did some real world testing, and it's looking like this is fundamentally working! We've got a little issue with the command state, but otherwise this looks like it's doing the thing 🎉 |
As we've just implemented things in pipette and labware translation, yes, these IDs are the same.
* Revert some thoughtless re-exports I made earlier in this PR. * Say what I think actually should be re-exported here, so I don't make the same mistake again.
api/tests/opentrons/protocols/runnner/json_proto/test_command_translator.py
Outdated
Show resolved
Hide resolved
api/tests/opentrons/protocols/runnner/json_proto/test_command_translator.py
Outdated
Show resolved
Hide resolved
api/tests/opentrons/protocols/runnner/json_proto/test_command_translator.py
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some discussion points, but covered most of this on chat. Got a few discussion points below, but otherwise this looks to be fundamentally working and the TODOs check out
# Convenience re-exports of models that are especially common or important. | ||
# More detailed sub-models are always available through the underlying | ||
# submodules. | ||
# | ||
# If re-exporting something, its name should still make sense when it's separatred | ||
# from the name of its parent submodule. e.g. re-exporting models.json_protocol.Labware | ||
# as models.Labware could be confusing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, this is referring to the from .json_protocol import Model as JsonProtocol
re-export business? Agree that should be avoided
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not totally sure we're talking about the same thing.
I had gone down an unproductive path of adding re-exports for everything I could possibly need from json_protocol
and labware_definitions
to this __init__.py
. I tried re-exporting json_protocol.Labware
, json_protocol.AllCommands
, and so on.
Somewhere in the middle of this PR, I realized that this would cause confusing naming problems. For example, models.Labware
sounds like it's about Opentrons labware definitions in general, but as a re-export of json_protocols.Labware
, it's actually a very specific JSON protocol thing.
So this comment is meant to say, "I know we're re-exporting some things here at the top level, but don't get tempted into doing this for absolutely everything. Here's where it does and doesn't make sense."
json_protocol.Model
is funky but I don't think the concern is specific to it.
PickUpTipRequest, DropTipRequest | ||
) | ||
from opentrons.protocols.models import json_protocol as models | ||
import opentrons.types |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find import foo.bar
to be very confusing; it's was non-obvious to me that you then proceed to use foo.bar
in the code.
Given that we use exactly two structures from here, I would've written this as:
from opentrons.types import DeckSlotName, MountType
Mostly because I'm lazy and it's less typing everywhere, and doesn't feel to me like it's a loss in understanding because the name is consistent everywhere and most of us are working in editors / IDEs with type info + click-to-follow
Translate a PD/JSON protocol to Protocol Engine commands. | ||
def translate(self, protocol: models.JsonProtocol) -> PECommands: | ||
"""Return all Protocol Engine commands required to run the given protocol.""" | ||
result: List[pe.commands.CommandRequestType] = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pe.commands.WhateverThing
makes me feel a little like we're locking into the internal shape of the protocol_engine
module. It sort of makes me think that this translator belongs in the protocol_engine
module itself (perhaps in clients
or something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we mention commands
over and over every time we type pe.commands.WhateverThing
, as opposed to once at the top of the file like from protocol_engine.commands import ...
?
That's true.
I think in this particular case, it gets resolved if we do from protocol_engine import commands as pe_commands
, as you suggested and as I've just written about in Slack.
This also brings up a second discussion of whether submodule names are / can be / should be part of the whole collective package's stable interface. I'll write about this separately.
api/tests/opentrons/protocols/runnner/json_proto/test_command_translator.py
Show resolved
Hide resolved
Merging this now to make it easier to test running protocols on robots (yay!). But feel free to keep leaving comments here (and maybe ping me) for stuff to clarify/fix/change in a follow-up. |
Overview
When a JSON protocol is uploaded through the experimental HTTP API, to be run through protocol engine, implement the missing parts of loading the pipettes and labware that the JSON protocol uses. Closes #7946.
Changelog
Main changes:
CommandTranslator
to take in an entire protocol at once, instead of going command-by-command.CommandTranslator
the ability to translate a JSON protocol's choices of pipettes and labware into Protocol EngineLoadPipetteRequest
s,AddLabwareDefinitionRequest
s, andLoadLabwareRequest
s.Also:
LoadPipetteRequest.pipetteName
is the pipette load name, as opposed to the model name or something.opentrons/protocols/models/__init.py__
describing when (I think) it should re-export things from its child submodules. I had gone down an unproductive path adding re-exports for everything I could possibly need from that tree.Deferred work
todo
comment at the top oftest_command_translator.py
for the fix approach that @mcous and I agreed on.CommandTranslator
tests #7958Other stuff discussed in in-person reviews
CommandTranslator
toProtocolTranslator
, since it now takes in and translates an entire JSON protocol at once, rather than going command-by-command. This could have been necessary if we chose a testing approach where command translation is a separate class from protocol translation, but we didn't, so this renaming doesn't feel worthwhile to me anymore.Review requests
I would focus on the production code, since we know the tests to be messy and we already have a good path in mind to fix them.
Risk assessment
Low. Only used in our experimental Protocol Engine work, behind a feature flag.