opentrons 8.6.0a10__py3-none-any.whl → 8.6.0a12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of opentrons might be problematic. Click here for more details.

opentrons/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '8.6.0a10'
32
- __version_tuple__ = version_tuple = (8, 6, 0, 'a10')
31
+ __version__ = version = '8.6.0a12'
32
+ __version_tuple__ = version_tuple = (8, 6, 0, 'a12')
33
33
 
34
34
  __commit_id__ = commit_id = None
opentrons/cli/analyze.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Opentrons analyze CLI."""
2
+
2
3
  import click
3
4
 
4
5
  from anyio import run
@@ -24,7 +25,9 @@ from typing import (
24
25
  import logging
25
26
  import sys
26
27
  import json
28
+ import gc
27
29
 
30
+ from opentrons.protocol_engine import ProtocolEngine
28
31
  from opentrons.protocol_engine.types import (
29
32
  RunTimeParameter,
30
33
  CSVRuntimeParamPaths,
@@ -94,6 +97,18 @@ class _Output:
94
97
  help="Return analysis results as JSON, formatted for human eyes. Specify --human-json-output=- to use stdout, but be aware that Python protocols may contain print() which will make the output JSON invalid.",
95
98
  type=click.File(mode="wb"),
96
99
  )
100
+ @click.option(
101
+ "--leaks",
102
+ help="Fail (via exit code) if the analysis engine has not been garbage collected after analysis is complete.",
103
+ is_flag=True,
104
+ default=False,
105
+ )
106
+ @click.option(
107
+ "--leaks-debug",
108
+ help="Drop into a PDB shell if a leak is detected",
109
+ is_flag=True,
110
+ default=False,
111
+ )
97
112
  @click.option(
98
113
  "--check",
99
114
  help="Fail (via exit code) if the protocol had an error. If not specified, always succeed.",
@@ -133,6 +148,8 @@ def analyze(
133
148
  log_output: str,
134
149
  log_level: str,
135
150
  check: bool,
151
+ leaks: bool,
152
+ leaks_debug: bool,
136
153
  ) -> int:
137
154
  """Analyze a protocol.
138
155
 
@@ -147,7 +164,18 @@ def analyze(
147
164
 
148
165
  try:
149
166
  with _capture_logs(log_output, log_level):
150
- sys.exit(run(_analyze, files, rtp_values, rtp_files, outputs, check))
167
+ sys.exit(
168
+ run(
169
+ _analyze,
170
+ files,
171
+ rtp_values,
172
+ rtp_files,
173
+ outputs,
174
+ check,
175
+ leaks or leaks_debug,
176
+ leaks_debug,
177
+ )
178
+ )
151
179
  except click.ClickException:
152
180
  raise
153
181
  except Exception as e:
@@ -344,12 +372,14 @@ async def _do_analyze(
344
372
  return await orchestrator.run(deck_configuration=[])
345
373
 
346
374
 
347
- async def _analyze(
375
+ async def _analyze( # noqa: C901
348
376
  files_and_dirs: Sequence[Path],
349
377
  rtp_values: str,
350
378
  rtp_files: str,
351
379
  outputs: Sequence[_Output],
352
380
  check: bool,
381
+ fail_on_leak: bool,
382
+ debug_on_leak: bool,
353
383
  ) -> int:
354
384
  input_files = _get_input_files(files_and_dirs)
355
385
  parsed_rtp_values = _get_runtime_parameter_values(rtp_values)
@@ -366,6 +396,32 @@ async def _analyze(
366
396
  analysis = await _do_analyze(protocol_source, parsed_rtp_values, rtp_paths)
367
397
  return_code = _get_return_code(analysis)
368
398
 
399
+ # This ugly code checks to see if an engine remains past garbage collection
400
+ # after analysis is complete.
401
+ # It should be here and open coded to make it a little easier to present
402
+ # the debug option.
403
+ if fail_on_leak or debug_on_leak:
404
+ gc.collect()
405
+ leaked_engine = next(
406
+ (obj for obj in gc.get_objects() if isinstance(obj, ProtocolEngine)), None
407
+ )
408
+ if leaked_engine:
409
+ if fail_on_leak:
410
+ print(
411
+ "A ProtocolEngine instance exists even after garbage collection; "
412
+ "some thing (likely in the protocol) has caused it to be leaked, "
413
+ "likely by reference to the engine or something that refers to the "
414
+ "engine after the run function ends.",
415
+ file=sys.stderr,
416
+ )
417
+ return_code = -2
418
+ if debug_on_leak:
419
+ print(
420
+ "You are now in an interactive PDB (https://docs.python.org/3.10/library/pdb.html) "
421
+ "session; the leaked engine is bound to the variable leaked_engine."
422
+ )
423
+ breakpoint()
424
+
369
425
  if not outputs:
370
426
  return return_code
371
427
 
@@ -1,4 +1,4 @@
1
- from typing import List
1
+ from typing import Any, List
2
2
  from math import trunc
3
3
 
4
4
  from opentrons.drivers import utils
@@ -213,3 +213,64 @@ def heater_shaker_deactivate_heater() -> command_types.HeaterShakerDeactivateHea
213
213
  "name": command_types.HEATER_SHAKER_DEACTIVATE_HEATER,
214
214
  "payload": {"text": text},
215
215
  }
216
+
217
+
218
+ # FLex Stacker
219
+
220
+
221
+ def flex_stacker_set_stored_labware(
222
+ self: Any,
223
+ load_name: str,
224
+ namespace: str | None = None,
225
+ version: int | None = None,
226
+ adapter: str | None = None,
227
+ lid: str | None = None,
228
+ count: int | None = None,
229
+ stacking_offset_z: float | None = None,
230
+ ) -> command_types.FlexStackerSetStoredLabwareCommand:
231
+ uri = f"{namespace}/{load_name}/{version}"
232
+ text = f"Configuring {self} with {count} labware {uri}, adapter: {adapter}, lid: {lid}, stacking_offset_z: {stacking_offset_z}"
233
+ return {
234
+ "name": command_types.FLEX_STACKER_SET_STORED_LABWARE,
235
+ "payload": {"text": text},
236
+ }
237
+
238
+
239
+ def flex_stacker_retrieve(
240
+ self: Any,
241
+ ) -> command_types.FlexStackerRetrieveCommand:
242
+ text = f"Retrieving labware from {self}"
243
+ return {
244
+ "name": command_types.FLEX_STACKER_RETRIEVE,
245
+ "payload": {"text": text},
246
+ }
247
+
248
+
249
+ def flex_stacker_store(
250
+ self: Any,
251
+ ) -> command_types.FlexStackerStoreCommand:
252
+ text = f"Storing labware to {self}"
253
+ return {
254
+ "name": command_types.FLEX_STACKER_STORE,
255
+ "payload": {"text": text},
256
+ }
257
+
258
+
259
+ def flex_stacker_empty(
260
+ self: Any,
261
+ ) -> command_types.FlexStackerEmptyCommand:
262
+ text = f"Emptying {self}"
263
+ return {
264
+ "name": command_types.FLEX_STACKER_EMPTY,
265
+ "payload": {"text": text},
266
+ }
267
+
268
+
269
+ def flex_stacker_fill(
270
+ self: Any, count: int | None = None
271
+ ) -> command_types.FlexStackerFillCommand:
272
+ text = f"Filling {self} with {count} labware"
273
+ return {
274
+ "name": command_types.FLEX_STACKER_FILL,
275
+ "payload": {"text": text},
276
+ }
@@ -89,6 +89,12 @@ THERMOCYCLER_SET_LID_TEMP: Final = "command.THERMOCYCLER_SET_LID_TEMP"
89
89
  THERMOCYCLER_DEACTIVATE_LID: Final = "command.THERMOCYCLER_DEACTIVATE_LID"
90
90
  THERMOCYCLER_DEACTIVATE_BLOCK: Final = "command.THERMOCYCLER_DEACTIVATE_BLOCK"
91
91
 
92
+ FLEX_STACKER_SET_STORED_LABWARE: Final = "command.FLEX_STACKER_SET_STORED_LABWARE"
93
+ FLEX_STACKER_RETRIEVE: Final = "command.FLEX_STACKER_RETRIEVE"
94
+ FLEX_STACKER_STORE: Final = "command.FLEX_STACKER_STORE"
95
+ FLEX_STACKER_EMPTY: Final = "command.FLEX_STACKER_EMPTY"
96
+ FLEX_STACKER_FILL: Final = "command.FLEX_STACKER_FILL"
97
+
92
98
  # Robot #
93
99
  ROBOT_MOVE_TO: Final = "command.ROBOT_MOVE_TO"
94
100
  ROBOT_MOVE_AXES_TO: Final = "command.ROBOT_MOVE_AXES_TO"
@@ -154,6 +160,9 @@ class ResumeCommand(TypedDict):
154
160
  payload: ResumeCommandPayload
155
161
 
156
162
 
163
+ # Module commands
164
+
165
+
157
166
  class HeaterShakerSetTargetTemperaturePayload(TextOnlyPayload):
158
167
  pass
159
168
 
@@ -371,6 +380,34 @@ class ThermocyclerCloseCommand(TypedDict):
371
380
  payload: ThermocyclerCloseCommandPayload
372
381
 
373
382
 
383
+ class FlexStackerSetStoredLabwareCommand(TypedDict):
384
+ name: Literal["command.FLEX_STACKER_SET_STORED_LABWARE"]
385
+ payload: TextOnlyPayload
386
+
387
+
388
+ class FlexStackerRetrieveCommand(TypedDict):
389
+ name: Literal["command.FLEX_STACKER_RETRIEVE"]
390
+ payload: TextOnlyPayload
391
+
392
+
393
+ class FlexStackerStoreCommand(TypedDict):
394
+ name: Literal["command.FLEX_STACKER_STORE"]
395
+ payload: TextOnlyPayload
396
+
397
+
398
+ class FlexStackerEmptyCommand(TypedDict):
399
+ name: Literal["command.FLEX_STACKER_EMPTY"]
400
+ payload: TextOnlyPayload
401
+
402
+
403
+ class FlexStackerFillCommand(TypedDict):
404
+ name: Literal["command.FLEX_STACKER_FILL"]
405
+ payload: TextOnlyPayload
406
+
407
+
408
+ # Module command end
409
+
410
+
374
411
  class HomeCommandPayload(TextOnlyPayload):
375
412
  axis: str
376
413
 
@@ -739,6 +776,12 @@ Command = Union[
739
776
  RobotMoveAxisRelativeCommand,
740
777
  RobotOpenGripperJawCommand,
741
778
  RobotCloseGripperJawCommand,
779
+ # Flex Stacker commands
780
+ FlexStackerSetStoredLabwareCommand,
781
+ FlexStackerRetrieveCommand,
782
+ FlexStackerStoreCommand,
783
+ FlexStackerEmptyCommand,
784
+ FlexStackerFillCommand,
742
785
  ]
743
786
 
744
787
 
@@ -1019,6 +1062,28 @@ class MagdeckEngageMessage(CommandMessageFields, MagdeckEngageCommand):
1019
1062
  pass
1020
1063
 
1021
1064
 
1065
+ class FlexStackerSetStoredLabwareMessage(
1066
+ CommandMessageFields, FlexStackerSetStoredLabwareCommand
1067
+ ):
1068
+ pass
1069
+
1070
+
1071
+ class FlexStackerRetrieveMessage(CommandMessageFields, FlexStackerRetrieveCommand):
1072
+ pass
1073
+
1074
+
1075
+ class FlexStackerStoreMessage(CommandMessageFields, FlexStackerStoreCommand):
1076
+ pass
1077
+
1078
+
1079
+ class FlexStackerEmptyMessage(CommandMessageFields, FlexStackerEmptyCommand):
1080
+ pass
1081
+
1082
+
1083
+ class FlexStackerFillMessage(CommandMessageFields, FlexStackerFillCommand):
1084
+ pass
1085
+
1086
+
1022
1087
  class ResumeMessage(CommandMessageFields, ResumeCommand):
1023
1088
  pass
1024
1089
 
@@ -1112,4 +1177,10 @@ CommandMessage = Union[
1112
1177
  RobotMoveAxisRelativeMessage,
1113
1178
  RobotOpenGripperJawMessage,
1114
1179
  RobotCloseGripperJawMessage,
1180
+ # Flex Stacker Messages
1181
+ FlexStackerSetStoredLabwareMessage,
1182
+ FlexStackerRetrieveMessage,
1183
+ FlexStackerStoreMessage,
1184
+ FlexStackerEmptyMessage,
1185
+ FlexStackerFillMessage,
1115
1186
  ]
@@ -5,7 +5,7 @@ import logging
5
5
  from copy import deepcopy
6
6
  from enum import Enum
7
7
  from typing import TYPE_CHECKING, Optional, Union, Literal
8
- from dataclasses import dataclass, field
8
+ from dataclasses import dataclass, field, replace
9
9
 
10
10
  from opentrons_shared_data.liquid_classes.liquid_class_definition import (
11
11
  PositionReference,
@@ -21,7 +21,6 @@ from opentrons.protocol_api._liquid_properties import (
21
21
  MultiDispenseProperties,
22
22
  TouchTipProperties,
23
23
  )
24
- from opentrons.protocol_engine.errors import TouchTipDisabledError
25
24
  from opentrons.types import Location, Point, Mount
26
25
  from opentrons.protocols.advanced_control.transfers.transfer_liquid_utils import (
27
26
  LocationCheckDescriptors,
@@ -466,7 +465,7 @@ class TransferComponentsExecutor:
466
465
  2. If blowout is enabled and “destination”
467
466
  - Do blow-out (at the retract position)
468
467
  - Leave plunger down
469
- 3. Touch-tip
468
+ 3. Touch-tip in the destination well.
470
469
  4. If not ready-to-aspirate
471
470
  - Prepare-to-aspirate (at the retract position)
472
471
  5. Air-gap (at the retract position)
@@ -479,7 +478,7 @@ class TransferComponentsExecutor:
479
478
  6. If blowout is “source” or “trash”
480
479
  - Move to location (top of Well)
481
480
  - Do blow-out (top of well)
482
- - Do touch-tip (?????) (only if it’s in a non-trash location)
481
+ - Do touch-tip AGAIN at the source well (if blowout in a non-trash location)
483
482
  - Prepare-to-aspirate (top of well)
484
483
  - Do air-gap (top of well)
485
484
  7. If drop tip, move to drop tip location, drop tip
@@ -563,9 +562,9 @@ class TransferComponentsExecutor:
563
562
  blowout_props.enabled
564
563
  and blowout_props.location != BlowoutLocation.DESTINATION
565
564
  ):
566
- # TODO: no-op touch tip if touch tip is enabled and blowout is in trash/ reservoir/ any labware with touch-tip disabled
567
565
  assert blowout_props.flow_rate is not None
568
566
  self._instrument.set_flow_rate(blow_out=blowout_props.flow_rate)
567
+ blowout_touch_tip_props = retract_props.touch_tip
569
568
  touch_tip_and_air_gap_location: Union[Location, TrashBin, WasteChute]
570
569
  if blowout_props.location == BlowoutLocation.SOURCE:
571
570
  if source_location is None or source_well is None:
@@ -584,6 +583,13 @@ class TransferComponentsExecutor:
584
583
  source_well.get_top(0), labware=source_location.labware
585
584
  )
586
585
  touch_tip_and_air_gap_well = source_well
586
+ # Skip touch tip if blowing out at the SOURCE and it's untouchable:
587
+ if (
588
+ "touchTipDisabled"
589
+ in source_location.labware.quirks_from_any_parent()
590
+ ):
591
+ blowout_touch_tip_props = replace(blowout_touch_tip_props)
592
+ blowout_touch_tip_props.enabled = False
587
593
  else:
588
594
  self._instrument.blow_out(
589
595
  location=trash_location,
@@ -612,7 +618,7 @@ class TransferComponentsExecutor:
612
618
  )
613
619
  # Do touch tip and air gap again after blowing out into source well or trash
614
620
  self._do_touch_tip_and_air_gap_after_dispense(
615
- touch_tip_properties=retract_props.touch_tip,
621
+ touch_tip_properties=blowout_touch_tip_props,
616
622
  location=touch_tip_and_air_gap_location,
617
623
  well=touch_tip_and_air_gap_well,
618
624
  air_gap_volume=air_gap_volume,
@@ -758,6 +764,7 @@ class TransferComponentsExecutor:
758
764
  ):
759
765
  assert blowout_props.flow_rate is not None
760
766
  self._instrument.set_flow_rate(blow_out=blowout_props.flow_rate)
767
+ blowout_touch_tip_props = retract_props.touch_tip
761
768
  touch_tip_and_air_gap_location: Union[Location, TrashBin, WasteChute]
762
769
  if blowout_props.location == BlowoutLocation.SOURCE:
763
770
  if source_location is None or source_well is None:
@@ -776,6 +783,13 @@ class TransferComponentsExecutor:
776
783
  source_well.get_top(0), labware=source_location.labware
777
784
  )
778
785
  touch_tip_and_air_gap_well = source_well
786
+ # Skip touch tip if blowing out at the SOURCE and it's untouchable:
787
+ if (
788
+ "touchTipDisabled"
789
+ in source_location.labware.quirks_from_any_parent()
790
+ ):
791
+ blowout_touch_tip_props = replace(blowout_touch_tip_props)
792
+ blowout_touch_tip_props.enabled = False
779
793
  else:
780
794
  self._instrument.blow_out(
781
795
  location=trash_location,
@@ -807,13 +821,13 @@ class TransferComponentsExecutor:
807
821
  air_gap_volume = 0
808
822
  # Do touch tip and air gap again after blowing out into source well or trash
809
823
  self._do_touch_tip_and_air_gap_after_dispense(
810
- touch_tip_properties=retract_props.touch_tip,
824
+ touch_tip_properties=blowout_touch_tip_props,
811
825
  location=touch_tip_and_air_gap_location,
812
826
  well=touch_tip_and_air_gap_well,
813
827
  air_gap_volume=air_gap_volume,
814
828
  )
815
829
 
816
- def _do_touch_tip_and_air_gap_after_dispense( # noqa: C901
830
+ def _do_touch_tip_and_air_gap_after_dispense(
817
831
  self,
818
832
  touch_tip_properties: TouchTipProperties,
819
833
  location: Union[Location, TrashBin, WasteChute],
@@ -822,6 +836,12 @@ class TransferComponentsExecutor:
822
836
  ) -> None:
823
837
  """Perform touch tip and air gap as part of post-dispense retract.
824
838
 
839
+ This function can be invoked up to 2 times for each dispense:
840
+ 1) Once for touching tip at the dispense location.
841
+ 2) Then again in the blowout location if it is not the dispense location.
842
+ For case (2), the caller should disable touch-tip in touch_tip_properties
843
+ if the blowout location is not touchable (such as reservoirs).
844
+
825
845
  If the retract location is at or above the safe location of
826
846
  AIR_GAP_LOC_Z_OFFSET_FROM_WELL_TOP, then add the air gap at the retract location
827
847
  (where the pipette is already assumed to be at).
@@ -842,18 +862,14 @@ class TransferComponentsExecutor:
842
862
  # whether the touch tip params from transfer props should be used for
843
863
  # both dest-well touch tip and non-dest-well touch tip.
844
864
  if isinstance(location, Location) and well is not None:
845
- try:
846
- self._instrument.touch_tip(
847
- location=location,
848
- well_core=well,
849
- radius=1,
850
- z_offset=touch_tip_properties.z_offset,
851
- speed=touch_tip_properties.speed,
852
- mm_from_edge=touch_tip_properties.mm_from_edge,
853
- )
854
- except TouchTipDisabledError:
855
- # TODO: log a warning
856
- pass
865
+ self._instrument.touch_tip(
866
+ location=location,
867
+ well_core=well,
868
+ radius=1,
869
+ z_offset=touch_tip_properties.z_offset,
870
+ speed=touch_tip_properties.speed,
871
+ mm_from_edge=touch_tip_properties.mm_from_edge,
872
+ )
857
873
 
858
874
  # Move back to the 'retract' position
859
875
  self._instrument.move_to(
@@ -1140,6 +1140,7 @@ class FlexStackerContext(ModuleContext):
1140
1140
  return self._core.get_serial_number()
1141
1141
 
1142
1142
  @requires_version(2, 25)
1143
+ @publish(command=cmds.flex_stacker_retrieve)
1143
1144
  def retrieve(self) -> Labware:
1144
1145
  """Retrieve a labware from the Flex Stacker and move it onto the shuttle.
1145
1146
 
@@ -1160,6 +1161,7 @@ class FlexStackerContext(ModuleContext):
1160
1161
  )
1161
1162
 
1162
1163
  @requires_version(2, 25)
1164
+ @publish(command=cmds.flex_stacker_store)
1163
1165
  def store(self) -> None:
1164
1166
  """Move a labware currently on the Flex Stacker shuttle into the Flex Stacker.
1165
1167
 
@@ -1318,6 +1320,7 @@ class FlexStackerContext(ModuleContext):
1318
1320
  )
1319
1321
 
1320
1322
  @requires_version(2, 25)
1323
+ @publish(command=cmds.flex_stacker_set_stored_labware)
1321
1324
  def set_stored_labware(
1322
1325
  self,
1323
1326
  load_name: str,
@@ -1392,6 +1395,7 @@ class FlexStackerContext(ModuleContext):
1392
1395
  )
1393
1396
 
1394
1397
  @requires_version(2, 25)
1398
+ @publish(command=cmds.flex_stacker_fill)
1395
1399
  def fill(self, count: int | None = None, message: str | None = None) -> None:
1396
1400
  """Pause the protocol to add labware to the Flex Stacker.
1397
1401
 
@@ -1418,6 +1422,7 @@ class FlexStackerContext(ModuleContext):
1418
1422
  self._core.fill_items(self._labware_to_cores(labware), message)
1419
1423
 
1420
1424
  @requires_version(2, 25)
1425
+ @publish(command=cmds.flex_stacker_empty)
1421
1426
  def empty(self, message: str | None = None) -> None:
1422
1427
  """Pause the protocol to remove all labware stored in the Flex Stacker.
1423
1428
 
@@ -10,6 +10,8 @@ from opentrons.hardware_control.modules.types import (
10
10
  MagneticModuleModel,
11
11
  ThermocyclerModuleModel,
12
12
  HeaterShakerModuleModel,
13
+ AbsorbanceReaderModel,
14
+ FlexStackerModuleModel,
13
15
  )
14
16
  from opentrons_shared_data.pipette.types import PipetteNameType
15
17
  from opentrons.types import MountType, DeckSlotName, Location
@@ -78,6 +80,8 @@ _HARDWARE_TO_PE_MODULE: Dict[HardwareModuleModel, pe_types.ModuleModel] = {
78
80
  ThermocyclerModuleModel.THERMOCYCLER_V1: pe_types.ModuleModel.THERMOCYCLER_MODULE_V1,
79
81
  ThermocyclerModuleModel.THERMOCYCLER_V2: pe_types.ModuleModel.THERMOCYCLER_MODULE_V2,
80
82
  HeaterShakerModuleModel.HEATER_SHAKER_V1: pe_types.ModuleModel.HEATER_SHAKER_MODULE_V1,
83
+ AbsorbanceReaderModel.ABSORBANCE_READER_V1: pe_types.ModuleModel.ABSORBANCE_READER_V1,
84
+ FlexStackerModuleModel.FLEX_STACKER_V1: pe_types.ModuleModel.FLEX_STACKER_MODULE_V1,
81
85
  }
82
86
 
83
87
  _HIGHER_ORDER_COMMAND_TYPES = {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opentrons
3
- Version: 8.6.0a10
3
+ Version: 8.6.0a12
4
4
  Summary: The Opentrons API is a simple framework designed to make writing automated biology lab protocols easy.
5
5
  Project-URL: opentrons.com, https://www.opentrons.com
6
6
  Project-URL: Source Code On Github, https://github.com/Opentrons/opentrons/tree/edge/api
@@ -24,7 +24,7 @@ Requires-Dist: click<9,>=8.0.0
24
24
  Requires-Dist: importlib-metadata>=1.0; python_version < '3.8'
25
25
  Requires-Dist: jsonschema<4.18.0,>=3.0.1
26
26
  Requires-Dist: numpy<2,>=1.20.0
27
- Requires-Dist: opentrons-shared-data==8.6.0a10
27
+ Requires-Dist: opentrons-shared-data==8.6.0a12
28
28
  Requires-Dist: packaging>=21.0
29
29
  Requires-Dist: pydantic-settings<3,>=2
30
30
  Requires-Dist: pydantic<3,>=2.0.0
@@ -32,6 +32,6 @@ Requires-Dist: pyserial>=3.5
32
32
  Requires-Dist: pyusb==1.2.1
33
33
  Requires-Dist: typing-extensions<5,>=4.0.0
34
34
  Provides-Extra: flex-hardware
35
- Requires-Dist: opentrons-hardware[flex]==8.6.0a10; extra == 'flex-hardware'
35
+ Requires-Dist: opentrons-hardware[flex]==8.6.0a12; extra == 'flex-hardware'
36
36
  Provides-Extra: ot2-hardware
37
- Requires-Dist: opentrons-hardware==8.6.0a10; extra == 'ot2-hardware'
37
+ Requires-Dist: opentrons-hardware==8.6.0a12; extra == 'ot2-hardware'
@@ -1,5 +1,5 @@
1
1
  opentrons/__init__.py,sha256=TQ_Ca_zzAM3iLzAysWKkFkQHG8-imihxDPQbLCYrf-E,4533
2
- opentrons/_version.py,sha256=WOzpqMGqbeQfu1DNnQl-_lxA9A_N9iJAD333-1EKRCI,714
2
+ opentrons/_version.py,sha256=Ej-eiQxj2liXf3S-OFMSv77mR8rEtkyJT0yFtbesf_E,714
3
3
  opentrons/execute.py,sha256=Y88qICDiHWQjU0L4Ou7DI5OXXu7zZcdkUvNUYmZqIfc,29282
4
4
  opentrons/legacy_broker.py,sha256=XnuEBBlrHCThc31RFW2UR0tGqctqWZ-CZ9vSC4L9whU,1553
5
5
  opentrons/ordered_set.py,sha256=g-SB3qA14yxHu9zjGyc2wC7d2TUCBE6fKZlHAtbPzI8,4082
@@ -28,7 +28,7 @@ opentrons/calibration_storage/ot3/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5
28
28
  opentrons/calibration_storage/ot3/models/v1.py,sha256=SZU9CilK4HjPNtE-6mLcGX4ZsT3o0PGX8-RPjogmwXY,4393
29
29
  opentrons/cli/__init__.py,sha256=zP_n-SnZnZc_yzb0JnnwvUvIBiIpupGOQrqPZrSmnRs,430
30
30
  opentrons/cli/__main__.py,sha256=Jvtl3eMKDT1eX00BGULAw6WqenKe911TMTg4b97y5dA,73
31
- opentrons/cli/analyze.py,sha256=70ZR9bTZCedmvaYcrklRZXozgINf_gZseYgb1oSZVJ8,14837
31
+ opentrons/cli/analyze.py,sha256=sZHRQxVyQASunYpjl0iks_Gkc8K6iX79cBuaipHfVys,16747
32
32
  opentrons/config/__init__.py,sha256=N_ls4aKFt5jrXiPg-M8g2ecc2PgEzH2qTjbPjlr2fFk,21488
33
33
  opentrons/config/advanced_settings.py,sha256=CzR1IzIMGMkvzyzwIjaVR7_ZIZ9_zr-Odgq2Ij4K4vU,27215
34
34
  opentrons/config/defaults_ot2.py,sha256=_l63QNW0aWTh0HGZcgF592ETJg8-W4M0XrQbbzkAPjA,6031
@@ -210,11 +210,11 @@ opentrons/hardware_control/scripts/update_module_fw.py,sha256=FqX4y5_Ghs-uY1_Kjb
210
210
  opentrons/legacy_commands/__init__.py,sha256=erkaz7hc2iHsTtjpFDWrR1V5n47it3U1qxD2zL9CkuE,63
211
211
  opentrons/legacy_commands/commands.py,sha256=lgImZ0Y3gZrMKDVioaOXWqa6mMJCNKDa8p-lQhTghWk,14530
212
212
  opentrons/legacy_commands/helpers.py,sha256=Bc7mjK6V7b4h472NCx_qSwD0ojd_DM7mPg18tjo1DIQ,5228
213
- opentrons/legacy_commands/module_commands.py,sha256=EO2YtrfzCCaGPYjGXWfk6jjSHiEqk1E6D8Ef2qDi1qI,7769
213
+ opentrons/legacy_commands/module_commands.py,sha256=bAqZmsAqXkjf3qzexo9fOs4QxZ-RvcZmdy0_QEcHd7U,9368
214
214
  opentrons/legacy_commands/protocol_commands.py,sha256=nPYBrm7j9co83IGWjzae2GOVkEZdu58pXQv3eOdpLzg,1383
215
215
  opentrons/legacy_commands/publisher.py,sha256=JRrpF-kG7qt5dwDFbCqeMjokCSwn8BdllMMYnJeDLn8,5440
216
216
  opentrons/legacy_commands/robot_commands.py,sha256=c51gVAh-98PxhxmEL_3P80rejkaY58gAQ7S6wNwctao,1642
217
- opentrons/legacy_commands/types.py,sha256=dtmHB2VOtsQHFzhdoZgjJZZc8pNGcCnleA5zsi5GTo0,28904
217
+ opentrons/legacy_commands/types.py,sha256=cbW_flEmurZIcAh-EOcJp3bgrUCvx3ASTrw1oRqMv10,30745
218
218
  opentrons/motion_planning/__init__.py,sha256=Gma3SLAvKbL7QuhVGtL9zFx5vlk_7YBF0TjYZQSiv9s,755
219
219
  opentrons/motion_planning/adjacent_slots_getters.py,sha256=z7HkfC8ymAdGHdFq-sC_1_cERX_v29b9x4HKtJ6gp9I,5390
220
220
  opentrons/motion_planning/deck_conflict.py,sha256=gIAQYJbSKEn5XM_AoBVCOdp-acQsc0nF5FHaeuF53vg,16757
@@ -235,7 +235,7 @@ opentrons/protocol_api/deck.py,sha256=94vFceg1SC1bAGd7TvC1ZpYwnJR-VlzurEZ6jkacYe
235
235
  opentrons/protocol_api/disposal_locations.py,sha256=NRiSGmDR0LnbyEkWSOM-o64uR2fUoB1NWJG7Y7SsJSs,7920
236
236
  opentrons/protocol_api/instrument_context.py,sha256=dOg04iqYnNMJ7XnlHBX3tTGiEahc-7feIuErcevRdwY,141216
237
237
  opentrons/protocol_api/labware.py,sha256=ZP4QuGadoDp6xtyToupXVSJFnsx4NfWcskRQAH3iU4Y,61443
238
- opentrons/protocol_api/module_contexts.py,sha256=RF6T__0Y7cYoFDWLmRU2BxPEVtMshEflelCHdW7IDbM,59743
238
+ opentrons/protocol_api/module_contexts.py,sha256=HYQ20RV2c-NNwgObQZNxyvVKmy2Ufkf--ILoRmhkcvA,59988
239
239
  opentrons/protocol_api/module_validation_and_errors.py,sha256=ljst-M_KK78GnyG3pyZ_6yoYkMY3HORS1QyQyWrme-U,2250
240
240
  opentrons/protocol_api/protocol_context.py,sha256=Hzgw3FbCRyd4kWmw4RZwZHJhoGZkmn7ug-Q7JZGCcqs,70298
241
241
  opentrons/protocol_api/robot_context.py,sha256=D6ZdpFX30VTtVUDHitsVjabJQXD5TxOV9_Z6sik1LvE,11891
@@ -264,7 +264,7 @@ opentrons/protocol_api/core/engine/point_calculations.py,sha256=C2eF0fvJQGMqQv3D
264
264
  opentrons/protocol_api/core/engine/protocol.py,sha256=uX-qwATcTXiEUXe9gGDmp1cJ1Xd4eQnyy-q_jpiyAYY,46023
265
265
  opentrons/protocol_api/core/engine/robot.py,sha256=bzUt23NG-clD-9-QFsV_6nm3fMgSmvYEG9DyyZI1xgw,5366
266
266
  opentrons/protocol_api/core/engine/stringify.py,sha256=GwFgEhFMk-uPfFQhQG_2mkaf4cxaItiY8RW7rZwiooQ,2794
267
- opentrons/protocol_api/core/engine/transfer_components_executor.py,sha256=PAH4hpg5QIp9gwsq0segY113_3ZyRgDV4OnDagNSrTE,44306
267
+ opentrons/protocol_api/core/engine/transfer_components_executor.py,sha256=mR59C-e6IHSZthlbQEwmRnh5ye8lhr6a0Qp5CNNi9n8,45211
268
268
  opentrons/protocol_api/core/engine/well.py,sha256=IaaFK-3hoUfabfn_twIT7zcAynhzAmRxDnvABss2szo,8923
269
269
  opentrons/protocol_api/core/legacy/__init__.py,sha256=_9jCJNKG3SlS_vljVu8HHkZmtLf4F-f-JHALLF5d5go,401
270
270
  opentrons/protocol_api/core/legacy/_labware_geometry.py,sha256=ugtMdfnSkUwBCC3Sdj5nP5aDUxX-Dr7BeiuPVmdjAtg,1091
@@ -520,7 +520,7 @@ opentrons/protocol_runner/__init__.py,sha256=Sr0gBDzNv3nuHPapeNy_IWadhohtwmlhfnB
520
520
  opentrons/protocol_runner/create_simulating_orchestrator.py,sha256=S1Fu9TMa3NrujcPYTfULHpfqLTkrZPYz7CbcXtcDes0,4249
521
521
  opentrons/protocol_runner/json_file_reader.py,sha256=dE9ujq3sWyKF1yFg0AN8h-roGVfvqf1tEcIq5wxHbxE,2341
522
522
  opentrons/protocol_runner/json_translator.py,sha256=lrDzHOOkQ19ac4KEdUbfEOnfx-F_QCO-6oGqQZegy4g,12134
523
- opentrons/protocol_runner/legacy_command_mapper.py,sha256=SSCNe6eUZPZ4wXF6Pe6-plJou8YJkYvG4QdbppOvgS8,36890
523
+ opentrons/protocol_runner/legacy_command_mapper.py,sha256=yUCfnp4sNawFikrujyPo27Ba_aOy-kr-9F3dOK6Zu9Q,37125
524
524
  opentrons/protocol_runner/legacy_context_plugin.py,sha256=G_qpeyaLvsCjb72_n96Luy8CPSfgPZpt0QKVzKc6LKY,4730
525
525
  opentrons/protocol_runner/protocol_runner.py,sha256=YUHZvttojkYghq82IWYWvTfN2kUZ1oZdm8Fm4K-zftI,21658
526
526
  opentrons/protocol_runner/python_protocol_wrappers.py,sha256=KEuM4M7rYD4zLjTqK89T47CiBIZJ42kG0JXWarLUq4E,6511
@@ -594,8 +594,8 @@ opentrons/util/linal.py,sha256=IlKAP9HkNBBgULeSf4YVwSKHdx9jnCjSr7nvDvlRALg,5753
594
594
  opentrons/util/logging_config.py,sha256=7et4YYuQdWdq_e50U-8vFS_QyNBRgdnqPGAQJm8qrIo,9954
595
595
  opentrons/util/logging_queue_handler.py,sha256=ZsSJwy-oV8DXwpYiZisQ1PbYwmK2cOslD46AcyJ1E4I,2484
596
596
  opentrons/util/performance_helpers.py,sha256=ew7H8XD20iS6-2TJAzbQeyzStZkkE6PzHt_Adx3wbZQ,5172
597
- opentrons-8.6.0a10.dist-info/METADATA,sha256=hjGup8Y1ej9BXaAbYLKI-_0wSxiI2BR2JNPy01YO7Sk,1611
598
- opentrons-8.6.0a10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
599
- opentrons-8.6.0a10.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
600
- opentrons-8.6.0a10.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
601
- opentrons-8.6.0a10.dist-info/RECORD,,
597
+ opentrons-8.6.0a12.dist-info/METADATA,sha256=l9QH2vlXU_XB9ZQoxc0ls8JKOmdyxwzStTlW-DmhdUw,1611
598
+ opentrons-8.6.0a12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
599
+ opentrons-8.6.0a12.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
600
+ opentrons-8.6.0a12.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
601
+ opentrons-8.6.0a12.dist-info/RECORD,,