opentrons 8.6.0__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.

Files changed (601) hide show
  1. opentrons/__init__.py +150 -0
  2. opentrons/_version.py +34 -0
  3. opentrons/calibration_storage/__init__.py +54 -0
  4. opentrons/calibration_storage/deck_configuration.py +62 -0
  5. opentrons/calibration_storage/encoder_decoder.py +31 -0
  6. opentrons/calibration_storage/file_operators.py +142 -0
  7. opentrons/calibration_storage/helpers.py +103 -0
  8. opentrons/calibration_storage/ot2/__init__.py +34 -0
  9. opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
  10. opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
  11. opentrons/calibration_storage/ot2/models/__init__.py +0 -0
  12. opentrons/calibration_storage/ot2/models/v1.py +149 -0
  13. opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
  14. opentrons/calibration_storage/ot2/tip_length.py +281 -0
  15. opentrons/calibration_storage/ot3/__init__.py +31 -0
  16. opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
  17. opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
  18. opentrons/calibration_storage/ot3/models/__init__.py +0 -0
  19. opentrons/calibration_storage/ot3/models/v1.py +122 -0
  20. opentrons/calibration_storage/ot3/module_offset.py +138 -0
  21. opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
  22. opentrons/calibration_storage/types.py +45 -0
  23. opentrons/cli/__init__.py +21 -0
  24. opentrons/cli/__main__.py +5 -0
  25. opentrons/cli/analyze.py +557 -0
  26. opentrons/config/__init__.py +631 -0
  27. opentrons/config/advanced_settings.py +871 -0
  28. opentrons/config/defaults_ot2.py +214 -0
  29. opentrons/config/defaults_ot3.py +499 -0
  30. opentrons/config/feature_flags.py +86 -0
  31. opentrons/config/gripper_config.py +55 -0
  32. opentrons/config/reset.py +203 -0
  33. opentrons/config/robot_configs.py +187 -0
  34. opentrons/config/types.py +183 -0
  35. opentrons/drivers/__init__.py +0 -0
  36. opentrons/drivers/absorbance_reader/__init__.py +11 -0
  37. opentrons/drivers/absorbance_reader/abstract.py +72 -0
  38. opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
  39. opentrons/drivers/absorbance_reader/driver.py +81 -0
  40. opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
  41. opentrons/drivers/absorbance_reader/simulator.py +84 -0
  42. opentrons/drivers/asyncio/__init__.py +0 -0
  43. opentrons/drivers/asyncio/communication/__init__.py +22 -0
  44. opentrons/drivers/asyncio/communication/async_serial.py +187 -0
  45. opentrons/drivers/asyncio/communication/errors.py +88 -0
  46. opentrons/drivers/asyncio/communication/serial_connection.py +557 -0
  47. opentrons/drivers/command_builder.py +102 -0
  48. opentrons/drivers/flex_stacker/__init__.py +13 -0
  49. opentrons/drivers/flex_stacker/abstract.py +214 -0
  50. opentrons/drivers/flex_stacker/driver.py +768 -0
  51. opentrons/drivers/flex_stacker/errors.py +68 -0
  52. opentrons/drivers/flex_stacker/simulator.py +309 -0
  53. opentrons/drivers/flex_stacker/types.py +367 -0
  54. opentrons/drivers/flex_stacker/utils.py +19 -0
  55. opentrons/drivers/heater_shaker/__init__.py +5 -0
  56. opentrons/drivers/heater_shaker/abstract.py +76 -0
  57. opentrons/drivers/heater_shaker/driver.py +204 -0
  58. opentrons/drivers/heater_shaker/simulator.py +94 -0
  59. opentrons/drivers/mag_deck/__init__.py +6 -0
  60. opentrons/drivers/mag_deck/abstract.py +44 -0
  61. opentrons/drivers/mag_deck/driver.py +208 -0
  62. opentrons/drivers/mag_deck/simulator.py +63 -0
  63. opentrons/drivers/rpi_drivers/__init__.py +33 -0
  64. opentrons/drivers/rpi_drivers/dev_types.py +94 -0
  65. opentrons/drivers/rpi_drivers/gpio.py +282 -0
  66. opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
  67. opentrons/drivers/rpi_drivers/interfaces.py +15 -0
  68. opentrons/drivers/rpi_drivers/types.py +364 -0
  69. opentrons/drivers/rpi_drivers/usb.py +102 -0
  70. opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
  71. opentrons/drivers/serial_communication.py +151 -0
  72. opentrons/drivers/smoothie_drivers/__init__.py +4 -0
  73. opentrons/drivers/smoothie_drivers/connection.py +51 -0
  74. opentrons/drivers/smoothie_drivers/constants.py +121 -0
  75. opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
  76. opentrons/drivers/smoothie_drivers/errors.py +49 -0
  77. opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
  78. opentrons/drivers/smoothie_drivers/simulator.py +99 -0
  79. opentrons/drivers/smoothie_drivers/types.py +16 -0
  80. opentrons/drivers/temp_deck/__init__.py +10 -0
  81. opentrons/drivers/temp_deck/abstract.py +54 -0
  82. opentrons/drivers/temp_deck/driver.py +197 -0
  83. opentrons/drivers/temp_deck/simulator.py +57 -0
  84. opentrons/drivers/thermocycler/__init__.py +12 -0
  85. opentrons/drivers/thermocycler/abstract.py +99 -0
  86. opentrons/drivers/thermocycler/driver.py +395 -0
  87. opentrons/drivers/thermocycler/simulator.py +126 -0
  88. opentrons/drivers/types.py +107 -0
  89. opentrons/drivers/utils.py +222 -0
  90. opentrons/execute.py +742 -0
  91. opentrons/hardware_control/__init__.py +65 -0
  92. opentrons/hardware_control/__main__.py +77 -0
  93. opentrons/hardware_control/adapters.py +98 -0
  94. opentrons/hardware_control/api.py +1347 -0
  95. opentrons/hardware_control/backends/__init__.py +7 -0
  96. opentrons/hardware_control/backends/controller.py +400 -0
  97. opentrons/hardware_control/backends/errors.py +9 -0
  98. opentrons/hardware_control/backends/estop_state.py +164 -0
  99. opentrons/hardware_control/backends/flex_protocol.py +497 -0
  100. opentrons/hardware_control/backends/ot3controller.py +1930 -0
  101. opentrons/hardware_control/backends/ot3simulator.py +900 -0
  102. opentrons/hardware_control/backends/ot3utils.py +664 -0
  103. opentrons/hardware_control/backends/simulator.py +442 -0
  104. opentrons/hardware_control/backends/status_bar_state.py +240 -0
  105. opentrons/hardware_control/backends/subsystem_manager.py +431 -0
  106. opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
  107. opentrons/hardware_control/backends/types.py +14 -0
  108. opentrons/hardware_control/constants.py +6 -0
  109. opentrons/hardware_control/dev_types.py +125 -0
  110. opentrons/hardware_control/emulation/__init__.py +0 -0
  111. opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
  112. opentrons/hardware_control/emulation/app.py +56 -0
  113. opentrons/hardware_control/emulation/connection_handler.py +38 -0
  114. opentrons/hardware_control/emulation/heater_shaker.py +150 -0
  115. opentrons/hardware_control/emulation/magdeck.py +60 -0
  116. opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
  117. opentrons/hardware_control/emulation/module_server/client.py +78 -0
  118. opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
  119. opentrons/hardware_control/emulation/module_server/models.py +31 -0
  120. opentrons/hardware_control/emulation/module_server/server.py +110 -0
  121. opentrons/hardware_control/emulation/parser.py +74 -0
  122. opentrons/hardware_control/emulation/proxy.py +241 -0
  123. opentrons/hardware_control/emulation/run_emulator.py +68 -0
  124. opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
  125. opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
  126. opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
  127. opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
  128. opentrons/hardware_control/emulation/settings.py +119 -0
  129. opentrons/hardware_control/emulation/simulations.py +133 -0
  130. opentrons/hardware_control/emulation/smoothie.py +192 -0
  131. opentrons/hardware_control/emulation/tempdeck.py +69 -0
  132. opentrons/hardware_control/emulation/thermocycler.py +128 -0
  133. opentrons/hardware_control/emulation/types.py +10 -0
  134. opentrons/hardware_control/emulation/util.py +38 -0
  135. opentrons/hardware_control/errors.py +43 -0
  136. opentrons/hardware_control/execution_manager.py +164 -0
  137. opentrons/hardware_control/instruments/__init__.py +5 -0
  138. opentrons/hardware_control/instruments/instrument_abc.py +39 -0
  139. opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
  140. opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
  141. opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
  142. opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
  143. opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
  144. opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
  145. opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
  146. opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
  147. opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
  148. opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
  149. opentrons/hardware_control/module_control.py +332 -0
  150. opentrons/hardware_control/modules/__init__.py +69 -0
  151. opentrons/hardware_control/modules/absorbance_reader.py +373 -0
  152. opentrons/hardware_control/modules/errors.py +7 -0
  153. opentrons/hardware_control/modules/flex_stacker.py +948 -0
  154. opentrons/hardware_control/modules/heater_shaker.py +426 -0
  155. opentrons/hardware_control/modules/lid_temp_status.py +35 -0
  156. opentrons/hardware_control/modules/magdeck.py +233 -0
  157. opentrons/hardware_control/modules/mod_abc.py +245 -0
  158. opentrons/hardware_control/modules/module_calibration.py +93 -0
  159. opentrons/hardware_control/modules/plate_temp_status.py +61 -0
  160. opentrons/hardware_control/modules/tempdeck.py +299 -0
  161. opentrons/hardware_control/modules/thermocycler.py +731 -0
  162. opentrons/hardware_control/modules/types.py +417 -0
  163. opentrons/hardware_control/modules/update.py +255 -0
  164. opentrons/hardware_control/modules/utils.py +73 -0
  165. opentrons/hardware_control/motion_utilities.py +318 -0
  166. opentrons/hardware_control/nozzle_manager.py +422 -0
  167. opentrons/hardware_control/ot3_calibration.py +1171 -0
  168. opentrons/hardware_control/ot3api.py +3227 -0
  169. opentrons/hardware_control/pause_manager.py +31 -0
  170. opentrons/hardware_control/poller.py +112 -0
  171. opentrons/hardware_control/protocols/__init__.py +106 -0
  172. opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
  173. opentrons/hardware_control/protocols/calibratable.py +45 -0
  174. opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
  175. opentrons/hardware_control/protocols/configurable.py +48 -0
  176. opentrons/hardware_control/protocols/event_sourcer.py +18 -0
  177. opentrons/hardware_control/protocols/execution_controllable.py +33 -0
  178. opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
  179. opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
  180. opentrons/hardware_control/protocols/gripper_controller.py +55 -0
  181. opentrons/hardware_control/protocols/hardware_manager.py +51 -0
  182. opentrons/hardware_control/protocols/identifiable.py +16 -0
  183. opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
  184. opentrons/hardware_control/protocols/liquid_handler.py +266 -0
  185. opentrons/hardware_control/protocols/module_provider.py +16 -0
  186. opentrons/hardware_control/protocols/motion_controller.py +243 -0
  187. opentrons/hardware_control/protocols/position_estimator.py +45 -0
  188. opentrons/hardware_control/protocols/simulatable.py +10 -0
  189. opentrons/hardware_control/protocols/stoppable.py +9 -0
  190. opentrons/hardware_control/protocols/types.py +27 -0
  191. opentrons/hardware_control/robot_calibration.py +224 -0
  192. opentrons/hardware_control/scripts/README.md +28 -0
  193. opentrons/hardware_control/scripts/__init__.py +1 -0
  194. opentrons/hardware_control/scripts/gripper_control.py +208 -0
  195. opentrons/hardware_control/scripts/ot3gripper +7 -0
  196. opentrons/hardware_control/scripts/ot3repl +7 -0
  197. opentrons/hardware_control/scripts/repl.py +187 -0
  198. opentrons/hardware_control/scripts/tc_control.py +97 -0
  199. opentrons/hardware_control/scripts/update_module_fw.py +274 -0
  200. opentrons/hardware_control/simulator_setup.py +260 -0
  201. opentrons/hardware_control/thread_manager.py +431 -0
  202. opentrons/hardware_control/threaded_async_lock.py +97 -0
  203. opentrons/hardware_control/types.py +792 -0
  204. opentrons/hardware_control/util.py +234 -0
  205. opentrons/legacy_broker.py +53 -0
  206. opentrons/legacy_commands/__init__.py +1 -0
  207. opentrons/legacy_commands/commands.py +483 -0
  208. opentrons/legacy_commands/helpers.py +153 -0
  209. opentrons/legacy_commands/module_commands.py +276 -0
  210. opentrons/legacy_commands/protocol_commands.py +54 -0
  211. opentrons/legacy_commands/publisher.py +155 -0
  212. opentrons/legacy_commands/robot_commands.py +51 -0
  213. opentrons/legacy_commands/types.py +1186 -0
  214. opentrons/motion_planning/__init__.py +32 -0
  215. opentrons/motion_planning/adjacent_slots_getters.py +168 -0
  216. opentrons/motion_planning/deck_conflict.py +501 -0
  217. opentrons/motion_planning/errors.py +35 -0
  218. opentrons/motion_planning/types.py +42 -0
  219. opentrons/motion_planning/waypoints.py +218 -0
  220. opentrons/ordered_set.py +138 -0
  221. opentrons/protocol_api/__init__.py +105 -0
  222. opentrons/protocol_api/_liquid.py +157 -0
  223. opentrons/protocol_api/_liquid_properties.py +814 -0
  224. opentrons/protocol_api/_nozzle_layout.py +31 -0
  225. opentrons/protocol_api/_parameter_context.py +300 -0
  226. opentrons/protocol_api/_parameters.py +31 -0
  227. opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
  228. opentrons/protocol_api/_types.py +43 -0
  229. opentrons/protocol_api/config.py +23 -0
  230. opentrons/protocol_api/core/__init__.py +23 -0
  231. opentrons/protocol_api/core/common.py +33 -0
  232. opentrons/protocol_api/core/core_map.py +74 -0
  233. opentrons/protocol_api/core/engine/__init__.py +22 -0
  234. opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
  235. opentrons/protocol_api/core/engine/deck_conflict.py +400 -0
  236. opentrons/protocol_api/core/engine/exceptions.py +19 -0
  237. opentrons/protocol_api/core/engine/instrument.py +2391 -0
  238. opentrons/protocol_api/core/engine/labware.py +238 -0
  239. opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
  240. opentrons/protocol_api/core/engine/module_core.py +1027 -0
  241. opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
  242. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
  243. opentrons/protocol_api/core/engine/point_calculations.py +64 -0
  244. opentrons/protocol_api/core/engine/protocol.py +1153 -0
  245. opentrons/protocol_api/core/engine/robot.py +139 -0
  246. opentrons/protocol_api/core/engine/stringify.py +74 -0
  247. opentrons/protocol_api/core/engine/transfer_components_executor.py +1006 -0
  248. opentrons/protocol_api/core/engine/well.py +241 -0
  249. opentrons/protocol_api/core/instrument.py +459 -0
  250. opentrons/protocol_api/core/labware.py +151 -0
  251. opentrons/protocol_api/core/legacy/__init__.py +11 -0
  252. opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
  253. opentrons/protocol_api/core/legacy/deck.py +369 -0
  254. opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
  255. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
  256. opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
  257. opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
  258. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
  259. opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
  260. opentrons/protocol_api/core/legacy/load_info.py +67 -0
  261. opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
  262. opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
  263. opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
  264. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
  265. opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
  266. opentrons/protocol_api/core/module.py +484 -0
  267. opentrons/protocol_api/core/protocol.py +311 -0
  268. opentrons/protocol_api/core/robot.py +51 -0
  269. opentrons/protocol_api/core/well.py +116 -0
  270. opentrons/protocol_api/core/well_grid.py +45 -0
  271. opentrons/protocol_api/create_protocol_context.py +177 -0
  272. opentrons/protocol_api/deck.py +223 -0
  273. opentrons/protocol_api/disposal_locations.py +244 -0
  274. opentrons/protocol_api/instrument_context.py +3272 -0
  275. opentrons/protocol_api/labware.py +1579 -0
  276. opentrons/protocol_api/module_contexts.py +1447 -0
  277. opentrons/protocol_api/module_validation_and_errors.py +61 -0
  278. opentrons/protocol_api/protocol_context.py +1688 -0
  279. opentrons/protocol_api/robot_context.py +303 -0
  280. opentrons/protocol_api/validation.py +761 -0
  281. opentrons/protocol_engine/__init__.py +155 -0
  282. opentrons/protocol_engine/actions/__init__.py +65 -0
  283. opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
  284. opentrons/protocol_engine/actions/action_handler.py +13 -0
  285. opentrons/protocol_engine/actions/actions.py +302 -0
  286. opentrons/protocol_engine/actions/get_state_update.py +38 -0
  287. opentrons/protocol_engine/clients/__init__.py +5 -0
  288. opentrons/protocol_engine/clients/sync_client.py +174 -0
  289. opentrons/protocol_engine/clients/transports.py +197 -0
  290. opentrons/protocol_engine/commands/__init__.py +757 -0
  291. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
  292. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
  293. opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
  294. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
  295. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
  296. opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
  297. opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
  298. opentrons/protocol_engine/commands/aspirate.py +244 -0
  299. opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
  300. opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
  301. opentrons/protocol_engine/commands/blow_out.py +146 -0
  302. opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
  303. opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
  304. opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
  305. opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
  306. opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
  307. opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
  308. opentrons/protocol_engine/commands/command.py +308 -0
  309. opentrons/protocol_engine/commands/command_unions.py +974 -0
  310. opentrons/protocol_engine/commands/comment.py +57 -0
  311. opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
  312. opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
  313. opentrons/protocol_engine/commands/custom.py +67 -0
  314. opentrons/protocol_engine/commands/dispense.py +194 -0
  315. opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
  316. opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
  317. opentrons/protocol_engine/commands/drop_tip.py +232 -0
  318. opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
  319. opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
  320. opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
  321. opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
  322. opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
  323. opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
  324. opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
  325. opentrons/protocol_engine/commands/flex_stacker/store.py +339 -0
  326. opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
  327. opentrons/protocol_engine/commands/get_next_tip.py +134 -0
  328. opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
  329. opentrons/protocol_engine/commands/hash_command_params.py +38 -0
  330. opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
  331. opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
  332. opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
  333. opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
  334. opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
  335. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
  336. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
  337. opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
  338. opentrons/protocol_engine/commands/home.py +100 -0
  339. opentrons/protocol_engine/commands/identify_module.py +86 -0
  340. opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
  341. opentrons/protocol_engine/commands/liquid_probe.py +464 -0
  342. opentrons/protocol_engine/commands/load_labware.py +210 -0
  343. opentrons/protocol_engine/commands/load_lid.py +154 -0
  344. opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
  345. opentrons/protocol_engine/commands/load_liquid.py +95 -0
  346. opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
  347. opentrons/protocol_engine/commands/load_module.py +223 -0
  348. opentrons/protocol_engine/commands/load_pipette.py +167 -0
  349. opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
  350. opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
  351. opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
  352. opentrons/protocol_engine/commands/move_labware.py +546 -0
  353. opentrons/protocol_engine/commands/move_relative.py +102 -0
  354. opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
  355. opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
  356. opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
  357. opentrons/protocol_engine/commands/move_to_well.py +119 -0
  358. opentrons/protocol_engine/commands/movement_common.py +338 -0
  359. opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
  360. opentrons/protocol_engine/commands/pipetting_common.py +443 -0
  361. opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
  362. opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
  363. opentrons/protocol_engine/commands/reload_labware.py +90 -0
  364. opentrons/protocol_engine/commands/retract_axis.py +75 -0
  365. opentrons/protocol_engine/commands/robot/__init__.py +70 -0
  366. opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
  367. opentrons/protocol_engine/commands/robot/common.py +18 -0
  368. opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
  369. opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
  370. opentrons/protocol_engine/commands/robot/move_to.py +94 -0
  371. opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
  372. opentrons/protocol_engine/commands/save_position.py +109 -0
  373. opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
  374. opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
  375. opentrons/protocol_engine/commands/set_status_bar.py +89 -0
  376. opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
  377. opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
  378. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
  379. opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
  380. opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
  381. opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
  382. opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
  383. opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
  384. opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
  385. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
  386. opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
  387. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
  388. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
  389. opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
  390. opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
  391. opentrons/protocol_engine/commands/touch_tip.py +189 -0
  392. opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
  393. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
  394. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
  395. opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
  396. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
  397. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
  398. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
  399. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
  400. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
  401. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
  402. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
  403. opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
  404. opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
  405. opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
  406. opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
  407. opentrons/protocol_engine/create_protocol_engine.py +193 -0
  408. opentrons/protocol_engine/engine_support.py +28 -0
  409. opentrons/protocol_engine/error_recovery_policy.py +81 -0
  410. opentrons/protocol_engine/errors/__init__.py +191 -0
  411. opentrons/protocol_engine/errors/error_occurrence.py +182 -0
  412. opentrons/protocol_engine/errors/exceptions.py +1308 -0
  413. opentrons/protocol_engine/execution/__init__.py +50 -0
  414. opentrons/protocol_engine/execution/command_executor.py +216 -0
  415. opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
  416. opentrons/protocol_engine/execution/door_watcher.py +119 -0
  417. opentrons/protocol_engine/execution/equipment.py +819 -0
  418. opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
  419. opentrons/protocol_engine/execution/gantry_mover.py +686 -0
  420. opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
  421. opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
  422. opentrons/protocol_engine/execution/labware_movement.py +297 -0
  423. opentrons/protocol_engine/execution/movement.py +350 -0
  424. opentrons/protocol_engine/execution/pipetting.py +607 -0
  425. opentrons/protocol_engine/execution/queue_worker.py +86 -0
  426. opentrons/protocol_engine/execution/rail_lights.py +25 -0
  427. opentrons/protocol_engine/execution/run_control.py +33 -0
  428. opentrons/protocol_engine/execution/status_bar.py +34 -0
  429. opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
  430. opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
  431. opentrons/protocol_engine/execution/tip_handler.py +550 -0
  432. opentrons/protocol_engine/labware_offset_standardization.py +194 -0
  433. opentrons/protocol_engine/notes/__init__.py +17 -0
  434. opentrons/protocol_engine/notes/notes.py +59 -0
  435. opentrons/protocol_engine/plugins.py +104 -0
  436. opentrons/protocol_engine/protocol_engine.py +683 -0
  437. opentrons/protocol_engine/resources/__init__.py +26 -0
  438. opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
  439. opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
  440. opentrons/protocol_engine/resources/file_provider.py +161 -0
  441. opentrons/protocol_engine/resources/fixture_validation.py +68 -0
  442. opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
  443. opentrons/protocol_engine/resources/labware_validation.py +73 -0
  444. opentrons/protocol_engine/resources/model_utils.py +32 -0
  445. opentrons/protocol_engine/resources/module_data_provider.py +44 -0
  446. opentrons/protocol_engine/resources/ot3_validation.py +21 -0
  447. opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
  448. opentrons/protocol_engine/slot_standardization.py +128 -0
  449. opentrons/protocol_engine/state/__init__.py +1 -0
  450. opentrons/protocol_engine/state/_abstract_store.py +27 -0
  451. opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
  452. opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
  453. opentrons/protocol_engine/state/_move_types.py +83 -0
  454. opentrons/protocol_engine/state/_well_math.py +193 -0
  455. opentrons/protocol_engine/state/addressable_areas.py +699 -0
  456. opentrons/protocol_engine/state/command_history.py +309 -0
  457. opentrons/protocol_engine/state/commands.py +1164 -0
  458. opentrons/protocol_engine/state/config.py +39 -0
  459. opentrons/protocol_engine/state/files.py +57 -0
  460. opentrons/protocol_engine/state/fluid_stack.py +138 -0
  461. opentrons/protocol_engine/state/geometry.py +2408 -0
  462. opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
  463. opentrons/protocol_engine/state/labware.py +1432 -0
  464. opentrons/protocol_engine/state/liquid_classes.py +82 -0
  465. opentrons/protocol_engine/state/liquids.py +73 -0
  466. opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
  467. opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
  468. opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
  469. opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
  470. opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
  471. opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
  472. opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
  473. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
  474. opentrons/protocol_engine/state/modules.py +1515 -0
  475. opentrons/protocol_engine/state/motion.py +373 -0
  476. opentrons/protocol_engine/state/pipettes.py +905 -0
  477. opentrons/protocol_engine/state/state.py +421 -0
  478. opentrons/protocol_engine/state/state_summary.py +36 -0
  479. opentrons/protocol_engine/state/tips.py +420 -0
  480. opentrons/protocol_engine/state/update_types.py +904 -0
  481. opentrons/protocol_engine/state/wells.py +290 -0
  482. opentrons/protocol_engine/types/__init__.py +310 -0
  483. opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
  484. opentrons/protocol_engine/types/command_annotations.py +53 -0
  485. opentrons/protocol_engine/types/deck_configuration.py +81 -0
  486. opentrons/protocol_engine/types/execution.py +96 -0
  487. opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
  488. opentrons/protocol_engine/types/instrument.py +47 -0
  489. opentrons/protocol_engine/types/instrument_sensors.py +47 -0
  490. opentrons/protocol_engine/types/labware.py +131 -0
  491. opentrons/protocol_engine/types/labware_movement.py +22 -0
  492. opentrons/protocol_engine/types/labware_offset_location.py +111 -0
  493. opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
  494. opentrons/protocol_engine/types/liquid.py +40 -0
  495. opentrons/protocol_engine/types/liquid_class.py +59 -0
  496. opentrons/protocol_engine/types/liquid_handling.py +13 -0
  497. opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
  498. opentrons/protocol_engine/types/location.py +194 -0
  499. opentrons/protocol_engine/types/module.py +310 -0
  500. opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
  501. opentrons/protocol_engine/types/run_time_parameters.py +133 -0
  502. opentrons/protocol_engine/types/tip.py +18 -0
  503. opentrons/protocol_engine/types/util.py +21 -0
  504. opentrons/protocol_engine/types/well_position.py +124 -0
  505. opentrons/protocol_reader/__init__.py +37 -0
  506. opentrons/protocol_reader/extract_labware_definitions.py +66 -0
  507. opentrons/protocol_reader/file_format_validator.py +152 -0
  508. opentrons/protocol_reader/file_hasher.py +27 -0
  509. opentrons/protocol_reader/file_identifier.py +284 -0
  510. opentrons/protocol_reader/file_reader_writer.py +90 -0
  511. opentrons/protocol_reader/input_file.py +16 -0
  512. opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
  513. opentrons/protocol_reader/protocol_reader.py +188 -0
  514. opentrons/protocol_reader/protocol_source.py +124 -0
  515. opentrons/protocol_reader/role_analyzer.py +86 -0
  516. opentrons/protocol_runner/__init__.py +26 -0
  517. opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
  518. opentrons/protocol_runner/json_file_reader.py +55 -0
  519. opentrons/protocol_runner/json_translator.py +314 -0
  520. opentrons/protocol_runner/legacy_command_mapper.py +852 -0
  521. opentrons/protocol_runner/legacy_context_plugin.py +116 -0
  522. opentrons/protocol_runner/protocol_runner.py +530 -0
  523. opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
  524. opentrons/protocol_runner/run_orchestrator.py +496 -0
  525. opentrons/protocol_runner/task_queue.py +95 -0
  526. opentrons/protocols/__init__.py +6 -0
  527. opentrons/protocols/advanced_control/__init__.py +0 -0
  528. opentrons/protocols/advanced_control/common.py +38 -0
  529. opentrons/protocols/advanced_control/mix.py +60 -0
  530. opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
  531. opentrons/protocols/advanced_control/transfers/common.py +180 -0
  532. opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
  533. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
  534. opentrons/protocols/api_support/__init__.py +0 -0
  535. opentrons/protocols/api_support/constants.py +8 -0
  536. opentrons/protocols/api_support/deck_type.py +110 -0
  537. opentrons/protocols/api_support/definitions.py +18 -0
  538. opentrons/protocols/api_support/instrument.py +151 -0
  539. opentrons/protocols/api_support/labware_like.py +233 -0
  540. opentrons/protocols/api_support/tip_tracker.py +175 -0
  541. opentrons/protocols/api_support/types.py +32 -0
  542. opentrons/protocols/api_support/util.py +403 -0
  543. opentrons/protocols/bundle.py +89 -0
  544. opentrons/protocols/duration/__init__.py +4 -0
  545. opentrons/protocols/duration/errors.py +5 -0
  546. opentrons/protocols/duration/estimator.py +628 -0
  547. opentrons/protocols/execution/__init__.py +0 -0
  548. opentrons/protocols/execution/dev_types.py +181 -0
  549. opentrons/protocols/execution/errors.py +40 -0
  550. opentrons/protocols/execution/execute.py +84 -0
  551. opentrons/protocols/execution/execute_json_v3.py +275 -0
  552. opentrons/protocols/execution/execute_json_v4.py +359 -0
  553. opentrons/protocols/execution/execute_json_v5.py +28 -0
  554. opentrons/protocols/execution/execute_python.py +169 -0
  555. opentrons/protocols/execution/json_dispatchers.py +87 -0
  556. opentrons/protocols/execution/types.py +7 -0
  557. opentrons/protocols/geometry/__init__.py +0 -0
  558. opentrons/protocols/geometry/planning.py +297 -0
  559. opentrons/protocols/labware.py +312 -0
  560. opentrons/protocols/models/__init__.py +0 -0
  561. opentrons/protocols/models/json_protocol.py +679 -0
  562. opentrons/protocols/parameters/__init__.py +0 -0
  563. opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
  564. opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
  565. opentrons/protocols/parameters/exceptions.py +34 -0
  566. opentrons/protocols/parameters/parameter_definition.py +272 -0
  567. opentrons/protocols/parameters/types.py +17 -0
  568. opentrons/protocols/parameters/validation.py +267 -0
  569. opentrons/protocols/parse.py +671 -0
  570. opentrons/protocols/types.py +159 -0
  571. opentrons/py.typed +0 -0
  572. opentrons/resources/scripts/lpc21isp +0 -0
  573. opentrons/resources/smoothie-edge-8414642.hex +23010 -0
  574. opentrons/simulate.py +1065 -0
  575. opentrons/system/__init__.py +6 -0
  576. opentrons/system/camera.py +51 -0
  577. opentrons/system/log_control.py +59 -0
  578. opentrons/system/nmcli.py +856 -0
  579. opentrons/system/resin.py +24 -0
  580. opentrons/system/smoothie_update.py +15 -0
  581. opentrons/system/wifi.py +204 -0
  582. opentrons/tools/__init__.py +0 -0
  583. opentrons/tools/args_handler.py +22 -0
  584. opentrons/tools/write_pipette_memory.py +157 -0
  585. opentrons/types.py +618 -0
  586. opentrons/util/__init__.py +1 -0
  587. opentrons/util/async_helpers.py +166 -0
  588. opentrons/util/broker.py +84 -0
  589. opentrons/util/change_notifier.py +47 -0
  590. opentrons/util/entrypoint_util.py +278 -0
  591. opentrons/util/get_union_elements.py +26 -0
  592. opentrons/util/helpers.py +6 -0
  593. opentrons/util/linal.py +178 -0
  594. opentrons/util/logging_config.py +265 -0
  595. opentrons/util/logging_queue_handler.py +61 -0
  596. opentrons/util/performance_helpers.py +157 -0
  597. opentrons-8.6.0.dist-info/METADATA +37 -0
  598. opentrons-8.6.0.dist-info/RECORD +601 -0
  599. opentrons-8.6.0.dist-info/WHEEL +4 -0
  600. opentrons-8.6.0.dist-info/entry_points.txt +3 -0
  601. opentrons-8.6.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,76 @@
1
+ """Protocol engine types to do with partial tip configurations."""
2
+
3
+ from typing import Literal, Union
4
+
5
+ from pydantic import (
6
+ BaseModel,
7
+ Field,
8
+ )
9
+
10
+ NOZZLE_NAME_REGEX = r"[A-Z]\d{1,2}"
11
+ PRIMARY_NOZZLE_LITERAL = Literal["A1", "H1", "A12", "H12"]
12
+
13
+
14
+ class AllNozzleLayoutConfiguration(BaseModel):
15
+ """All basemodel to represent a reset to the nozzle configuration. Sending no parameters resets to default."""
16
+
17
+ style: Literal["ALL"] = "ALL"
18
+
19
+
20
+ class SingleNozzleLayoutConfiguration(BaseModel):
21
+ """Minimum information required for a new nozzle configuration."""
22
+
23
+ style: Literal["SINGLE"] = "SINGLE"
24
+ primaryNozzle: PRIMARY_NOZZLE_LITERAL = Field(
25
+ ...,
26
+ description="The primary nozzle to use in the layout configuration. This nozzle will update the critical point of the current pipette. For now, this is also the back left corner of your rectangle.",
27
+ )
28
+
29
+
30
+ class RowNozzleLayoutConfiguration(BaseModel):
31
+ """Minimum information required for a new nozzle configuration."""
32
+
33
+ style: Literal["ROW"] = "ROW"
34
+ primaryNozzle: PRIMARY_NOZZLE_LITERAL = Field(
35
+ ...,
36
+ description="The primary nozzle to use in the layout configuration. This nozzle will update the critical point of the current pipette. For now, this is also the back left corner of your rectangle.",
37
+ )
38
+
39
+
40
+ class ColumnNozzleLayoutConfiguration(BaseModel):
41
+ """Information required for nozzle configurations of type ROW and COLUMN."""
42
+
43
+ style: Literal["COLUMN"] = "COLUMN"
44
+ primaryNozzle: PRIMARY_NOZZLE_LITERAL = Field(
45
+ ...,
46
+ description="The primary nozzle to use in the layout configuration. This nozzle will update the critical point of the current pipette. For now, this is also the back left corner of your rectangle.",
47
+ )
48
+
49
+
50
+ class QuadrantNozzleLayoutConfiguration(BaseModel):
51
+ """Information required for nozzle configurations of type QUADRANT."""
52
+
53
+ style: Literal["QUADRANT"] = "QUADRANT"
54
+ primaryNozzle: PRIMARY_NOZZLE_LITERAL = Field(
55
+ ...,
56
+ description="The primary nozzle to use in the layout configuration. This nozzle will update the critical point of the current pipette. For now, this is also the back left corner of your rectangle.",
57
+ )
58
+ frontRightNozzle: str = Field(
59
+ ...,
60
+ pattern=NOZZLE_NAME_REGEX,
61
+ description="The front right nozzle in your configuration.",
62
+ )
63
+ backLeftNozzle: str = Field(
64
+ ...,
65
+ pattern=NOZZLE_NAME_REGEX,
66
+ description="The back left nozzle in your configuration.",
67
+ )
68
+
69
+
70
+ NozzleLayoutConfigurationType = Union[
71
+ AllNozzleLayoutConfiguration,
72
+ SingleNozzleLayoutConfiguration,
73
+ ColumnNozzleLayoutConfiguration,
74
+ RowNozzleLayoutConfiguration,
75
+ QuadrantNozzleLayoutConfiguration,
76
+ ]
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """Protocol Engine types that have to do with runtime parameters."""
4
+
5
+ from pathlib import Path
6
+ from typing import Optional, Mapping, Union, Literal, Dict, List
7
+ from pydantic import (
8
+ BaseModel,
9
+ Field,
10
+ StrictBool,
11
+ StrictFloat,
12
+ StrictInt,
13
+ StrictStr,
14
+ )
15
+
16
+
17
+ # TODO (spp, 2024-04-02): move all RTP types to runner
18
+ class RTPBase(BaseModel):
19
+ """Parameters defined in a protocol."""
20
+
21
+ displayName: StrictStr = Field(..., description="Display string for the parameter.")
22
+ variableName: StrictStr = Field(
23
+ ..., description="Python variable name of the parameter."
24
+ )
25
+ description: Optional[StrictStr] = Field(
26
+ None, description="Detailed description of the parameter."
27
+ )
28
+ suffix: Optional[StrictStr] = Field(
29
+ None,
30
+ description="Units (like mL, mm/sec, etc) or a custom suffix for the parameter.",
31
+ )
32
+
33
+
34
+ class NumberParameter(RTPBase):
35
+ """An integer parameter defined in a protocol."""
36
+
37
+ type: Literal["int", "float"] = Field(
38
+ ..., description="String specifying whether the number is an int or float type."
39
+ )
40
+ min: Union[StrictInt, StrictFloat] = Field(
41
+ ..., description="Minimum value that the number param is allowed to have."
42
+ )
43
+ max: Union[StrictInt, StrictFloat] = Field(
44
+ ..., description="Maximum value that the number param is allowed to have."
45
+ )
46
+ value: Union[StrictInt, StrictFloat] = Field(
47
+ ...,
48
+ description="The value assigned to the parameter; if not supplied by the client, will be assigned the default value.",
49
+ )
50
+ default: Union[StrictInt, StrictFloat] = Field(
51
+ ...,
52
+ description="Default value of the parameter, to be used when there is no client-specified value.",
53
+ )
54
+
55
+
56
+ class BooleanParameter(RTPBase):
57
+ """A boolean parameter defined in a protocol."""
58
+
59
+ type: Literal["bool"] = Field(
60
+ default="bool", description="String specifying the type of this parameter"
61
+ )
62
+ value: StrictBool = Field(
63
+ ...,
64
+ description="The value assigned to the parameter; if not supplied by the client, will be assigned the default value.",
65
+ )
66
+ default: StrictBool = Field(
67
+ ...,
68
+ description="Default value of the parameter, to be used when there is no client-specified value.",
69
+ )
70
+
71
+
72
+ class EnumChoice(BaseModel):
73
+ """Components of choices used in RTP Enum Parameters."""
74
+
75
+ displayName: StrictStr = Field(
76
+ ..., description="Display string for the param's choice."
77
+ )
78
+ value: Union[StrictInt, StrictFloat, StrictStr] = Field(
79
+ ..., description="Enum value of the param's choice."
80
+ )
81
+
82
+
83
+ class EnumParameter(RTPBase):
84
+ """A string enum defined in a protocol."""
85
+
86
+ type: Literal["int", "float", "str"] = Field(
87
+ ...,
88
+ description="String specifying whether the parameter is an int or float or string type.",
89
+ )
90
+ choices: List[EnumChoice] = Field(
91
+ ..., description="List of valid choices for this parameter."
92
+ )
93
+ value: Union[StrictInt, StrictFloat, StrictStr] = Field(
94
+ ...,
95
+ description="The value assigned to the parameter; if not supplied by the client, will be assigned the default value.",
96
+ )
97
+ default: Union[StrictInt, StrictFloat, StrictStr] = Field(
98
+ ...,
99
+ description="Default value of the parameter, to be used when there is no client-specified value.",
100
+ )
101
+
102
+
103
+ class FileInfo(BaseModel):
104
+ """A file UUID descriptor."""
105
+
106
+ id: str = Field(
107
+ ...,
108
+ description="The UUID identifier of the file stored on the robot.",
109
+ )
110
+ name: str = Field(..., description="Name of the file, including the extension.")
111
+
112
+
113
+ class CSVParameter(RTPBase):
114
+ """A CSV file parameter defined in a protocol."""
115
+
116
+ type: Literal["csv_file"] = Field(
117
+ default="csv_file", description="String specifying the type of this parameter"
118
+ )
119
+ file: Optional[FileInfo] = Field(
120
+ default=None,
121
+ description="ID of the CSV file stored on the robot; to be used for fetching the CSV file."
122
+ " For local analysis this will most likely be empty.",
123
+ )
124
+
125
+
126
+ RunTimeParameter = Union[NumberParameter, EnumParameter, BooleanParameter, CSVParameter]
127
+
128
+ PrimitiveRunTimeParamValuesType = Mapping[
129
+ StrictStr, Union[StrictInt, StrictFloat, StrictBool, StrictStr]
130
+ ] # update value types as more RTP types are added
131
+
132
+ CSVRunTimeParamFilesType = Mapping[StrictStr, StrictStr]
133
+ CSVRuntimeParamPaths = Dict[str, Path]
@@ -0,0 +1,18 @@
1
+ """Protocol Engine types to deal with tips."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass(frozen=True)
7
+ class TipGeometry:
8
+ """Tip geometry data.
9
+
10
+ Props:
11
+ length: The effective length (total length minus overlap) of a tip in mm.
12
+ diameter: Tip diameter in mm.
13
+ volume: Maximum volume in µL.
14
+ """
15
+
16
+ length: float
17
+ diameter: float
18
+ volume: float
@@ -0,0 +1,21 @@
1
+ """Protocol engine utility types for model components."""
2
+ from dataclasses import dataclass
3
+
4
+ from pydantic import BaseModel
5
+
6
+
7
+ @dataclass(frozen=True)
8
+ class Dimensions:
9
+ """Dimensions of an object in deck-space."""
10
+
11
+ x: float
12
+ y: float
13
+ z: float
14
+
15
+
16
+ class Vec3f(BaseModel):
17
+ """A 3D vector of floats."""
18
+
19
+ x: float
20
+ y: float
21
+ z: float
@@ -0,0 +1,124 @@
1
+ """Protocol engine types to do with positions inside wells."""
2
+ from enum import Enum, auto
3
+ from typing import Union, Literal
4
+
5
+ from pydantic import BaseModel, Field
6
+
7
+
8
+ class WellOrigin(str, Enum):
9
+ """Origin of WellLocation offset.
10
+
11
+ Props:
12
+ TOP: the top-center of the well
13
+ BOTTOM: the bottom-center of the well
14
+ CENTER: the middle-center of the well
15
+ MENISCUS: the meniscus-center of the well
16
+ """
17
+
18
+ TOP = "top"
19
+ BOTTOM = "bottom"
20
+ CENTER = "center"
21
+ MENISCUS = "meniscus"
22
+
23
+
24
+ class PickUpTipWellOrigin(str, Enum):
25
+ """The origin of a PickUpTipWellLocation offset.
26
+
27
+ Props:
28
+ TOP: the top-center of the well
29
+ BOTTOM: the bottom-center of the well
30
+ CENTER: the middle-center of the well
31
+ """
32
+
33
+ TOP = "top"
34
+ BOTTOM = "bottom"
35
+ CENTER = "center"
36
+
37
+
38
+ class DropTipWellOrigin(str, Enum):
39
+ """The origin of a DropTipWellLocation offset.
40
+
41
+ Props:
42
+ TOP: the top-center of the well
43
+ BOTTOM: the bottom-center of the well
44
+ CENTER: the middle-center of the well
45
+ DEFAULT: the default drop-tip location of the well,
46
+ based on pipette configuration and length of the tip.
47
+ """
48
+
49
+ TOP = "top"
50
+ BOTTOM = "bottom"
51
+ CENTER = "center"
52
+ DEFAULT = "default"
53
+
54
+
55
+ class WellLocationFunction(int, Enum):
56
+ """The type of well location object to be created."""
57
+
58
+ BASE = auto()
59
+ LIQUID_HANDLING = auto()
60
+ PICK_UP_TIP = auto()
61
+ DROP_TIP = auto()
62
+
63
+
64
+ # This is deliberately a separate type from Vec3f to let components default to 0.
65
+ class WellOffset(BaseModel):
66
+ """An offset vector in (x, y, z)."""
67
+
68
+ x: float = 0
69
+ y: float = 0
70
+ z: float = 0
71
+
72
+
73
+ class WellLocation(BaseModel):
74
+ """A relative location in reference to a well's location."""
75
+
76
+ origin: WellOrigin = WellOrigin.TOP
77
+ offset: WellOffset = Field(default_factory=WellOffset)
78
+ volumeOffset: float = Field(
79
+ default=0.0,
80
+ description="""A volume of liquid, in µL, to offset the z-axis offset.""",
81
+ )
82
+
83
+
84
+ class LiquidHandlingWellLocation(BaseModel):
85
+ """A relative location in reference to a well's location.
86
+
87
+ To be used with commands that handle liquids.
88
+ """
89
+
90
+ origin: WellOrigin = WellOrigin.TOP
91
+ offset: WellOffset = Field(default_factory=WellOffset)
92
+ volumeOffset: Union[float, Literal["operationVolume"]] = Field(
93
+ default=0.0,
94
+ description="""A volume of liquid, in µL, to offset the z-axis offset. When "operationVolume" is specified, this volume is pulled from the command volume parameter.""",
95
+ )
96
+
97
+
98
+ class PickUpTipWellLocation(BaseModel):
99
+ """A relative location in reference to a well's location.
100
+
101
+ To be used for picking up tips.
102
+ """
103
+
104
+ origin: PickUpTipWellOrigin = PickUpTipWellOrigin.TOP
105
+ offset: WellOffset = Field(default_factory=WellOffset)
106
+
107
+
108
+ class DropTipWellLocation(BaseModel):
109
+ """Like WellLocation, but for dropping tips.
110
+
111
+ Unlike a typical WellLocation, the location for a drop tip
112
+ defaults to location based on the tip length rather than the well's top.
113
+ """
114
+
115
+ origin: DropTipWellOrigin = DropTipWellOrigin.DEFAULT
116
+ offset: WellOffset = Field(default_factory=WellOffset)
117
+
118
+
119
+ WellLocationType = Union[
120
+ WellLocation,
121
+ LiquidHandlingWellLocation,
122
+ PickUpTipWellLocation,
123
+ DropTipWellLocation,
124
+ ]
@@ -0,0 +1,37 @@
1
+ """Protocol file reading interfaces."""
2
+
3
+ from .protocol_files_invalid_error import ProtocolFilesInvalidError
4
+ from .protocol_reader import ProtocolReader
5
+ from .input_file import AbstractInputFile
6
+ from .protocol_source import (
7
+ ProtocolSource,
8
+ ProtocolSourceFile,
9
+ ProtocolFileRole,
10
+ ProtocolType,
11
+ JsonProtocolConfig,
12
+ PythonProtocolConfig,
13
+ )
14
+ from .file_reader_writer import FileReaderWriter, BufferedFile
15
+ from .file_hasher import FileHasher
16
+ from .extract_labware_definitions import extract_labware_definitions
17
+
18
+ __all__ = [
19
+ # main interfaces
20
+ "ProtocolReader",
21
+ "extract_labware_definitions",
22
+ # input values
23
+ "AbstractInputFile",
24
+ # errors
25
+ "ProtocolFilesInvalidError",
26
+ # values and types
27
+ "ProtocolSource",
28
+ "ProtocolSourceFile",
29
+ "ProtocolFileRole",
30
+ "ProtocolType",
31
+ "JsonProtocolConfig",
32
+ "PythonProtocolConfig",
33
+ "BufferedFile",
34
+ # helpers
35
+ "FileReaderWriter",
36
+ "FileHasher",
37
+ ]
@@ -0,0 +1,66 @@
1
+ # noqa: D100
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import List
6
+
7
+ import anyio
8
+
9
+ from opentrons_shared_data.labware.labware_definition import (
10
+ LabwareDefinition,
11
+ labware_definition_type_adapter,
12
+ )
13
+
14
+ from .protocol_source import ProtocolFileRole, ProtocolSource, ProtocolType
15
+
16
+
17
+ async def extract_labware_definitions(
18
+ protocol_source: ProtocolSource,
19
+ ) -> List[LabwareDefinition]:
20
+ """Extract all the labware definitions that are in the given protocol source.
21
+
22
+ This accounts for differences between JSON protocols,
23
+ which embed their labware definitions in the main protocol file,
24
+ and Python protocols, which have them in separate sidecar files.
25
+
26
+ May raise an exception if the files are not well-formed. Do not depend on the exact
27
+ exception type. This should not happen if the `ProtocolSource` was acquired from a
28
+ `ProtocolReader`, which should have validated the files.
29
+ """
30
+ if protocol_source.config.protocol_type == ProtocolType.JSON:
31
+ return await _extract_from_json_protocol_file(path=protocol_source.main_file)
32
+ # If there are any separate labware files, ignore them. This avoids custom
33
+ # labware definitions shadowing the ones intrinsic to the main file, which would
34
+ # be confusing. Note that, at least as of v6.2.0, the Opentrons App sends us
35
+ # *every* custom labware definition along with *every* protocol.
36
+
37
+ else:
38
+ assert protocol_source.config.protocol_type == ProtocolType.PYTHON
39
+ return [
40
+ await _extract_from_labware_file(file.path)
41
+ for file in protocol_source.files
42
+ if file.role == ProtocolFileRole.LABWARE
43
+ ]
44
+
45
+
46
+ async def _extract_from_labware_file(path: Path) -> LabwareDefinition:
47
+ def _do_parse() -> LabwareDefinition:
48
+ return labware_definition_type_adapter.validate_json(path.read_bytes())
49
+
50
+ return await anyio.to_thread.run_sync(_do_parse)
51
+
52
+
53
+ async def _extract_from_json_protocol_file(path: Path) -> List[LabwareDefinition]:
54
+ def extract_sync(path: Path) -> List[LabwareDefinition]:
55
+ with path.open("rb") as file:
56
+ json_contents = json.load(file)
57
+ # Rely on the file conforming to one of our JSON protocol schemas 3 to 7,
58
+ # which require this labwareDefinitions key.
59
+ unvalidated_definitions = json_contents["labwareDefinitions"].values()
60
+ validated_definitions = [
61
+ labware_definition_type_adapter.validate_python(u)
62
+ for u in unvalidated_definitions
63
+ ]
64
+ return validated_definitions
65
+
66
+ return await anyio.to_thread.run_sync(extract_sync, path)
@@ -0,0 +1,152 @@
1
+ """File format validation interface."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Iterable
5
+
6
+ import anyio
7
+ from pydantic import ValidationError as PydanticValidationError
8
+
9
+ from opentrons_shared_data.labware.labware_definition import (
10
+ labware_definition_type_adapter,
11
+ )
12
+ from opentrons_shared_data.protocol.models import (
13
+ ProtocolSchemaV6 as JsonProtocolV6,
14
+ ProtocolSchemaV7 as JsonProtocolV7,
15
+ ProtocolSchemaV8 as JsonProtocolV8,
16
+ )
17
+ from opentrons_shared_data.errors.exceptions import PythonException
18
+
19
+ from opentrons.protocols.models.json_protocol import Model as JsonProtocolUpToV5
20
+
21
+ from .file_identifier import (
22
+ IdentifiedFile,
23
+ IdentifiedJsonMain,
24
+ IdentifiedPythonMain,
25
+ IdentifiedLabwareDefinition,
26
+ IdentifiedData,
27
+ )
28
+ from .protocol_files_invalid_error import ProtocolFilesInvalidError
29
+
30
+
31
+ class FileFormatValidationError(ProtocolFilesInvalidError):
32
+ """Raised when a file does not conform to the format it's supposed to."""
33
+
34
+ @classmethod
35
+ def _generic_json_failure(
36
+ cls, info: IdentifiedJsonMain, exc: Exception
37
+ ) -> FileFormatValidationError:
38
+ return cls(
39
+ message=f"{info.original_file.name} could not be read as a JSON protocol.",
40
+ detail={"kind": "bad-json-protocol"},
41
+ wrapping=[PythonException(exc)],
42
+ )
43
+
44
+
45
+ class FileFormatValidator:
46
+ """File format validation interface."""
47
+
48
+ @staticmethod
49
+ async def validate(files: Iterable[IdentifiedFile]) -> None:
50
+ """Validate that each file actually conforms to the format we think it does."""
51
+ for file in files:
52
+ if isinstance(file, IdentifiedJsonMain):
53
+ await _validate_json_protocol(file)
54
+ elif isinstance(file, IdentifiedPythonMain):
55
+ pass # No more validation to do for Python protocols.
56
+ elif isinstance(file, IdentifiedLabwareDefinition):
57
+ await _validate_labware_definition(file)
58
+ elif isinstance(file, IdentifiedData):
59
+ pass # No more validation to do for bundled data files.
60
+
61
+
62
+ async def _validate_labware_definition(info: IdentifiedLabwareDefinition) -> None:
63
+ def validate_sync() -> None:
64
+ try:
65
+ labware_definition_type_adapter.validate_python(info.unvalidated_json)
66
+ except PydanticValidationError as e:
67
+ raise FileFormatValidationError(
68
+ message=f"{info.original_file.name} could not be read as a labware definition.",
69
+ detail={"kind": "bad-labware-definition"},
70
+ wrapping=[PythonException(e)],
71
+ ) from e
72
+
73
+ await anyio.to_thread.run_sync(validate_sync)
74
+
75
+
76
+ def _handle_v8_json_protocol_validation_error(
77
+ info: IdentifiedJsonMain, pve: PydanticValidationError
78
+ ) -> None:
79
+ for error in pve.errors():
80
+ if error["loc"] == ("commandSchemaId",) and error["type"] == "type_error.enum":
81
+ # type_error.enum is for "this entry is not in this enum" and happens if you constrain a field by
82
+ # annotating it with Enum, as we now do for command schema IDs
83
+ raise FileFormatValidationError(
84
+ message=(
85
+ f"{info.original_file.name} could not be read as a JSON protocol, in part because its command schema "
86
+ "id is unknown. This protocol may have been exported from a future version of authorship software. "
87
+ "Updating your Opentrons software may help."
88
+ ),
89
+ detail={
90
+ "kind": "bad-command-schema-id",
91
+ "command-schema-id": info.unvalidated_json.get(
92
+ "commandSchemaId", "<unknown>"
93
+ ),
94
+ },
95
+ wrapping=[PythonException(pve)],
96
+ ) from pve
97
+ if (
98
+ error["loc"] == ("labwareDefinitionSchemaId",)
99
+ and error["type"] == "value_error.const"
100
+ ):
101
+ # value_error.const is for "this entry is not one of these const values", which is different from type_error.enum
102
+ # for I'm sure a very good reason, and happens if you constrain a field by annotating it with a Literal
103
+ raise FileFormatValidationError(
104
+ message=(
105
+ f"{info.original_file.name} could not be read as a JSON protocol, in part because its labware schema "
106
+ "id is unknown. This protocol may have been exported from a future version of authorship software. "
107
+ "Updating your Opentrons software may help."
108
+ ),
109
+ detail={
110
+ "kind": "bad-labware-schema-id",
111
+ "labware-schema-id": info.unvalidated_json.get(
112
+ "labwareDefinitionSchemaId", "<unknown>"
113
+ ),
114
+ },
115
+ )
116
+ if error["loc"] == ("liquidSchemaId",) and error["type"] == "value_error.const":
117
+ raise FileFormatValidationError(
118
+ message=(
119
+ f"{info.original_file.name} could not be read as a JSON protocol, in part because its liquid schema "
120
+ "id is unknown. This protocol may have been exported from a future version of authorship software. "
121
+ "Updating your Opentrons software may help."
122
+ ),
123
+ detail={
124
+ "kind": "bad-liquid-schema-id",
125
+ "liquid-schema-id": info.unvalidated_json.get(
126
+ "liquidSchemaId", "<unknown>"
127
+ ),
128
+ },
129
+ )
130
+ else:
131
+ raise FileFormatValidationError._generic_json_failure(info, pve) from pve
132
+
133
+
134
+ async def _validate_json_protocol(info: IdentifiedJsonMain) -> None:
135
+ def validate_sync() -> None:
136
+ if info.schema_version == 8:
137
+ try:
138
+ JsonProtocolV8.model_validate(info.unvalidated_json)
139
+ except PydanticValidationError as pve:
140
+ _handle_v8_json_protocol_validation_error(info, pve)
141
+ else:
142
+ try:
143
+ if info.schema_version == 7:
144
+ JsonProtocolV7.model_validate(info.unvalidated_json)
145
+ elif info.schema_version == 6:
146
+ JsonProtocolV6.model_validate(info.unvalidated_json)
147
+ else:
148
+ JsonProtocolUpToV5.model_validate(info.unvalidated_json)
149
+ except PydanticValidationError as e:
150
+ raise FileFormatValidationError._generic_json_failure(info, e) from e
151
+
152
+ await anyio.to_thread.run_sync(validate_sync)
@@ -0,0 +1,27 @@
1
+ """File hashing utiliy class."""
2
+
3
+ from typing import Sequence
4
+ import anyio
5
+ import unicodedata
6
+ from hashlib import md5
7
+ from .file_reader_writer import BufferedFile
8
+
9
+
10
+ # TODO (spp: 2024-06-17): move file hasher to utils
11
+ class FileHasher:
12
+ """Hashing utility class that hashes a combination of protocol and labware files."""
13
+
14
+ @staticmethod
15
+ async def hash(files: Sequence[BufferedFile]) -> str:
16
+ """Sort and hash a sequence of protocol and labware files."""
17
+ return await anyio.to_thread.run_sync(_hash_sync, files)
18
+
19
+
20
+ def _hash_sync(files: Sequence[BufferedFile]) -> str:
21
+ sorted_files = sorted(files, key=lambda x: unicodedata.normalize("NFC", x.name))
22
+ name_content_hasher = md5()
23
+ for file in sorted_files:
24
+ name_hash = md5(file.name.encode("utf-8")).digest()
25
+ contents_hash = md5(file.contents).digest()
26
+ name_content_hasher.update(name_hash + contents_hash)
27
+ return name_content_hasher.hexdigest()