Skip to content
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

fix(api): Support simulating PAPIv≥2.14 #13709

Merged
merged 17 commits into from
Oct 11, 2023

Conversation

SyntaxColoring
Copy link
Contributor

@SyntaxColoring SyntaxColoring commented Oct 3, 2023

Overview

Closes RSS-322. Lets you run new Python protocols through opentrons_simulate, opentrons.simulate.simulate(), and opentrons.simulate.get_protocol_api().

Also fixes a straggling instance of RSS-156, incorrectly using the machine's current deck type in simulation, instead of the correct deck type to match the protocol.

Test Plan

See this document.

Changelog

Notable changes:

  • Rework simulate.py to support PAPIv≥2.14 protocols, via Protocol Engine. This rework mirrors what we did to execute.py in feat(api): Limited support for programmatically running PAPIv≥2.14 #12970.

  • Rework the adapt_protocol_source() helper to cope with protocols for which we don't know the filename. This is necessary to support opentrons.simulate.simulate(), whose filename argument is optional.

    Unfortunately, this requires modifications to opentrons.protocols.parse to make the filename more pass-through, so adapt_protocol_source() can tell when it wasn't provided.

Plus various smaller refactors for type safety, deduplication, and consistency.

Code review requests

I suggest code-reviewing this in two ways:

  1. Read the latest simulate.py file side-by-side with the latest execute.py file. They should mirror each other almost exactly.
    • Known discrepancy: They have minor differences because of differences in their interfaces. For example, the stuff in simulate.py returns the run log, whereas the stuff in execute.py sends run log events to a callback.
    • Known discrepancy: execute.py has a global hardware controller and global ProtocolEngines, whereas simulate.py only has the global ProtocolEngines.
  2. To get a more semantic sense of what changed, go commit-by-commit. Many of the commits are trivial refactors and can be glossed over. The commit messages should mark when this is the case.

Some special things to watch out for:

  • When rewriting simulate.py to make it look like execute.py, make sure I didn't accidentally drop anything unique to the old simulate.py that was important.
  • Double-check my work on adapt_protocol_source() and opentrons.protocols.parse.

Risk assessment

Medium.

This touches some subtle parts of opentrons.protocols.parse and opentrons.protocols.execute. The touches are light, but those areas are critical to protocol execution.

It also touches the simulation of PAPIv≤2.13 and JSONv≤5 protocols, so we need regression testing on those. See the test plan.

@SyntaxColoring SyntaxColoring changed the base branch from edge to chore_release-7.0.1 October 3, 2023 18:20
@SyntaxColoring SyntaxColoring changed the base branch from chore_release-7.0.1 to stab_at_simulation_dev_integration October 10, 2023 18:30
@codecov
Copy link

codecov bot commented Oct 10, 2023

Codecov Report

Merging #13709 (ca8da73) into chore_release-7.0.1 (27e594a) will decrease coverage by 0.01%.
Report is 5 commits behind head on chore_release-7.0.1.
The diff coverage is n/a.

Additional details and impacted files

Impacted file tree graph

@@                   Coverage Diff                   @@
##           chore_release-7.0.1   #13709      +/-   ##
=======================================================
- Coverage                71.23%   71.23%   -0.01%     
=======================================================
  Files                     2430     2430              
  Lines                    68439    68383      -56     
  Branches                  8043     8043              
=======================================================
- Hits                     48755    48713      -42     
+ Misses                   17786    17772      -14     
  Partials                  1898     1898              
Flag Coverage Δ
g-code-testing 96.44% <ø> (ø)
notify-server 89.13% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
api/src/opentrons/execute.py 54.23% <ø> (+0.13%) ⬆️
...rc/opentrons/protocols/execution/execute_python.py 87.23% <ø> (ø)
api/src/opentrons/protocols/parse.py 96.45% <ø> (-0.03%) ⬇️
api/src/opentrons/protocols/types.py 89.74% <ø> (ø)
api/src/opentrons/simulate.py 57.14% <ø> (-6.44%) ⬇️
api/src/opentrons/util/entrypoint_util.py 90.69% <ø> (ø)

* Mark CommandScraper and AccumulatingHandler as private.
* Tighten up typing on CommandScraper queue.
* Add comment about _CommandScraper setting the log level.
…cols.

Rewrite simulate.py to be structured like execute.py.
This helps us deal with `ProtocolReader` requiring a filename to infer the protocol type, while `opentrons.simulate.simulate()` doesn't always have a trustworthy protocol filename to work with.

By accepting a `Protocol` object as input, we can reuse `opentrons.protocols.parse`'s logic for guessing the protocol type.
@SyntaxColoring SyntaxColoring changed the base branch from stab_at_simulation_dev_integration to chore_release-7.0.1 October 10, 2023 19:29
@SyntaxColoring

This comment was marked as resolved.

@SyntaxColoring SyntaxColoring marked this pull request as ready for review October 10, 2023 21:26
@SyntaxColoring SyntaxColoring requested a review from a team as a code owner October 10, 2023 21:26
@SyntaxColoring SyntaxColoring requested a review from a team October 10, 2023 21:26
Comment on lines -260 to +265
filename=getattr(protocol, "co_filename", "<protocol>"),
filename=filename,
Copy link
Contributor Author

@SyntaxColoring SyntaxColoring Oct 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Falling back to "<protocol>" at this level was lossy. If we weren't given a filename, we want to preserve that information for the caller, by returning None, so they can choose their own fallback.

@ecormany

This comment was marked as resolved.

@CaseyBatten
Copy link
Contributor

Running locally, so far so good, need to test standard and JSON protocols on a Flex, might I recommend a change here:

prog="opentrons_simulate", description="Simulate an OT-2 protocol"

Should say something more like this to clarify support for the Flex:

parser = argparse.ArgumentParser(
        prog="opentrons_simulate", description="Simulate an OT-2/Flex protocol"
    )

I'll update again once I have run this on actual Flex hardware.

Copy link
Contributor

@jbleon95 jbleon95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went through code and tested in a live review, looks good. Welcome back opentrons_simulate.

Copy link
Member

@sanni-t sanni-t left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙌 Great work! Changes make sense

Copy link
Contributor

@CaseyBatten CaseyBatten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was capable of running multiple Flex python and JSONv5 protocols via the simulation CLI. Did not interrupt standard Flex operation.

@SyntaxColoring SyntaxColoring merged commit 1437d61 into chore_release-7.0.1 Oct 11, 2023
27 checks passed
@SyntaxColoring SyntaxColoring deleted the stab_at_simulation branch October 11, 2023 21:41
SyntaxColoring added a commit that referenced this pull request Oct 19, 2023
Notable changes:

* Rework `simulate.py` to support PAPIv≥2.14 protocols, via Protocol Engine. This rework mirrors what we did to `execute.py` in #12970.
* Rework the `adapt_protocol_source()` helper to cope with protocols for which we don't know the filename. This is necessary to support `opentrons.simulate.simulate()`, whose `filename` argument is optional.

  Unfortunately, this requires modifications to `opentrons.protocols.parse` to make the filename more pass-through, so `adapt_protocol_source()` can tell when it wasn't provided.

Plus various smaller refactors for type safety, deduplication, and consistency.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants