@opentrons/shared-data 0.1.7-alpha.1 → 0.2.0-alpha.0

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.
Files changed (258) hide show
  1. package/.coveragerc +4 -0
  2. package/.flake8 +31 -0
  3. package/Config.in +11 -0
  4. package/LICENSE +202 -0
  5. package/Makefile +13 -14
  6. package/Makefile-python.mk +134 -0
  7. package/buildroot.mk +35 -0
  8. package/command/index.ts +3 -1
  9. package/command/schemas/13.json +147 -315
  10. package/command/schemas/14.json +7254 -0
  11. package/command/types/index.ts +15 -4
  12. package/command/types/module.ts +24 -4
  13. package/command/types/setup.ts +5 -5
  14. package/command/types/support.ts +1 -0
  15. package/deck/definitions/5/ot2_short_trash.json +37 -0
  16. package/deck/definitions/5/ot2_standard.json +37 -0
  17. package/deck/definitions/5/ot3_standard.json +152 -51
  18. package/deck/schemas/5.json +46 -1
  19. package/labware/definitions/2/appliedbiosystemsmicroamp_384_wellplate_40ul/3.json +4737 -0
  20. package/labware/definitions/2/axygen_96_wellplate_500ul/1.json +1036 -0
  21. package/labware/definitions/2/axygen_96_wellplate_500ul/2.json +1159 -0
  22. package/labware/definitions/2/biorad_384_wellplate_50ul/4.json +4748 -0
  23. package/labware/definitions/2/biorad_96_wellplate_200ul_pcr/4.json +1187 -0
  24. package/labware/definitions/2/corning_12_wellplate_6.9ml_flat/4.json +210 -0
  25. package/labware/definitions/2/corning_24_wellplate_3.4ml_flat/4.json +342 -0
  26. package/labware/definitions/2/corning_48_wellplate_1.6ml_flat/5.json +610 -0
  27. package/labware/definitions/2/corning_6_wellplate_16.8ml_flat/4.json +134 -0
  28. package/labware/definitions/2/corning_96_wellplate_360ul_flat/4.json +1177 -0
  29. package/labware/definitions/2/corning_96_wellplate_360ul_lid/1.json +111 -0
  30. package/labware/definitions/2/ev_resin_tips_flex_96_labware/1.json +1 -1
  31. package/labware/definitions/2/ibidi_96_square_well_plate_300ul/1.json +1105 -0
  32. package/labware/definitions/2/ibidi_96_square_well_plate_300ul/2.json +1216 -0
  33. package/labware/definitions/2/ibidi_96_square_well_plate_300ul_lid/1.json +110 -0
  34. package/labware/definitions/2/nest_12_reservoir_22ml/1.json +232 -0
  35. package/labware/definitions/2/nest_24_wellplate_10.4ml/1.json +386 -0
  36. package/labware/definitions/2/nest_8_reservoir_22ml/1.json +162 -0
  37. package/labware/definitions/2/nest_96_wellplate_100ul_pcr_full_skirt/4.json +1166 -0
  38. package/labware/definitions/2/nest_96_wellplate_200ul_flat/4.json +1145 -0
  39. package/labware/definitions/2/nest_96_wellplate_2ml_deep/4.json +1261 -0
  40. package/labware/definitions/2/opentrons_96_wellplate_200ul_pcr_full_skirt/4.json +1174 -0
  41. package/labware/definitions/2/opentrons_flex_96_filtertiprack_1000ul/1.json +5 -0
  42. package/labware/definitions/2/opentrons_flex_96_filtertiprack_200ul/1.json +5 -0
  43. package/labware/definitions/2/opentrons_flex_96_filtertiprack_20ul/1.json +5 -0
  44. package/labware/definitions/2/opentrons_flex_96_filtertiprack_50ul/1.json +5 -0
  45. package/labware/definitions/2/opentrons_flex_96_tiprack_1000ul/1.json +5 -0
  46. package/labware/definitions/2/opentrons_flex_96_tiprack_200ul/1.json +5 -0
  47. package/labware/definitions/2/opentrons_flex_96_tiprack_20ul/1.json +5 -0
  48. package/labware/definitions/2/opentrons_flex_96_tiprack_50ul/1.json +5 -0
  49. package/labware/definitions/2/opentrons_flex_tiprack_lid/1.json +8 -8
  50. package/labware/definitions/2/opentrons_tough_pcr_auto_sealing_lid/1.json +8 -0
  51. package/labware/definitions/2/opentrons_tough_universal_lid/1.json +16 -1
  52. package/labware/definitions/2/smc_384_read_plate/1.json +4701 -0
  53. package/labware/definitions/2/smc_384_read_plate/2.json +5100 -0
  54. package/labware/definitions/2/thermoscientificnunc_96_wellplate_1300ul/3.json +1141 -0
  55. package/labware/definitions/2/thermoscientificnunc_96_wellplate_2000ul/3.json +1141 -0
  56. package/labware/definitions/2/usascientific_96_wellplate_2.4ml_deep/3.json +1243 -0
  57. package/labware/definitions/3/schema3test_96_well_aluminum_block/999.json +5 -2
  58. package/labware/definitions/3/schema3test_96_wellplate_200ul_pcr_full_skirt/999.json +15 -2
  59. package/labware/definitions/3/schema3test_aluminum_flat_bottom_plate/999.json +70 -0
  60. package/labware/definitions/3/schema3test_flex_96_tiprack_200ul/999.json +5 -9
  61. package/labware/definitions/3/schema3test_flex_96_tiprack_adapter/999.json +70 -0
  62. package/labware/definitions/3/schema3test_flex_tiprack_lid/999.json +146 -0
  63. package/labware/definitions/3/schema3test_tough_pcr_auto_sealing_lid/999.json +162 -0
  64. package/labware/definitions/3/schema3test_universal_flat_adapter/999.json +157 -0
  65. package/labware/fixtures/2/fixture_user_volumes_prototype.json +1137 -0
  66. package/labware/fixtures/3/fixture_2_plate.json +5 -2
  67. package/labware/fixtures/3/fixture_corning_24_plate.json +6 -3
  68. package/labware/fixtures/3/index.ts +4 -0
  69. package/labware/schemas/2.json +36 -1
  70. package/labware/schemas/3.json +57 -5
  71. package/lib/command/index.d.ts +39 -1
  72. package/lib/command/schemas/13.json +147 -315
  73. package/lib/command/schemas/14.json +7254 -0
  74. package/lib/command/types/index.d.ts +11 -3
  75. package/lib/command/types/module.d.ts +19 -6
  76. package/lib/command/types/setup.d.ts +5 -5
  77. package/lib/deck/definitions/5/ot2_short_trash.json +37 -0
  78. package/lib/deck/definitions/5/ot2_standard.json +37 -0
  79. package/lib/deck/definitions/5/ot3_standard.json +152 -51
  80. package/lib/deck/schemas/5.json +46 -1
  81. package/lib/index.mjs +240842 -193770
  82. package/lib/js/constants.d.ts +30 -9
  83. package/lib/js/fixtures.d.ts +77 -2
  84. package/lib/js/getLabware.d.ts +3 -3
  85. package/lib/js/helpers/__tests__/getMaxPushOutVolume.test.d.ts +1 -0
  86. package/lib/js/helpers/__tests__/getStackedItemsOnStartingDeck.test.d.ts +1 -0
  87. package/lib/js/helpers/__tests__/labwareSchemaShims.test.d.ts +1 -0
  88. package/lib/js/helpers/__tests__/pairsFromArray.test.d.ts +1 -0
  89. package/lib/js/helpers/__tests__/vectorMath.test.d.ts +1 -0
  90. package/lib/js/helpers/getFixedTrashLabwareDefinition.d.ts +2 -2
  91. package/lib/js/helpers/getLabwareDefURI.d.ts +3 -0
  92. package/lib/js/helpers/getLabwareDefinitionsByURIForProtocol.d.ts +6 -0
  93. package/lib/js/helpers/getLabwareInfoByLiquidId.d.ts +10 -0
  94. package/lib/js/helpers/getLiquidsByIdForLabware.d.ts +2 -0
  95. package/lib/js/helpers/getLoadedLabwareDefinitionsByUri.d.ts +2 -2
  96. package/lib/js/helpers/getMaxPushOutVolume.d.ts +2 -0
  97. package/lib/js/helpers/getStackedItemsOnStartingDeck.d.ts +50 -0
  98. package/lib/js/helpers/getStandardDeckViewLayerBlockList.d.ts +2 -0
  99. package/lib/js/helpers/getTipTypeFromTipRackDefinition.d.ts +2 -2
  100. package/lib/js/helpers/getWellFillFromLabwareId.d.ts +4 -0
  101. package/lib/js/helpers/getWellNamePerMultiTip.d.ts +3 -3
  102. package/lib/js/helpers/getWellTotalVolume.d.ts +2 -2
  103. package/lib/js/helpers/index.d.ts +22 -14
  104. package/lib/js/helpers/labwareInference.d.ts +3 -3
  105. package/lib/js/helpers/liquidClasses.d.ts +4 -2
  106. package/lib/js/helpers/matrixMath.d.ts +3 -0
  107. package/lib/js/helpers/pairsFromArray.d.ts +8 -0
  108. package/lib/js/helpers/parseProtocolCommands.d.ts +4 -4
  109. package/lib/js/helpers/positionMath.d.ts +127 -0
  110. package/lib/js/helpers/validateCustomLabwareHelper.d.ts +2 -2
  111. package/lib/js/helpers/vectorMath.d.ts +14 -0
  112. package/lib/js/helpers/wellSets.d.ts +4 -4
  113. package/lib/js/labware.d.ts +4 -3
  114. package/lib/js/liquidClasses.d.ts +4 -0
  115. package/lib/js/modules.d.ts +1 -1
  116. package/lib/js/types.d.ts +62 -13
  117. package/lib/labware/definitions/2/appliedbiosystemsmicroamp_384_wellplate_40ul/3.json +4737 -0
  118. package/lib/labware/definitions/2/axygen_96_wellplate_500ul/1.json +1036 -0
  119. package/lib/labware/definitions/2/axygen_96_wellplate_500ul/2.json +1159 -0
  120. package/lib/labware/definitions/2/biorad_384_wellplate_50ul/4.json +4748 -0
  121. package/lib/labware/definitions/2/biorad_96_wellplate_200ul_pcr/4.json +1187 -0
  122. package/lib/labware/definitions/2/corning_12_wellplate_6.9ml_flat/4.json +210 -0
  123. package/lib/labware/definitions/2/corning_24_wellplate_3.4ml_flat/4.json +342 -0
  124. package/lib/labware/definitions/2/corning_48_wellplate_1.6ml_flat/5.json +610 -0
  125. package/lib/labware/definitions/2/corning_6_wellplate_16.8ml_flat/4.json +134 -0
  126. package/lib/labware/definitions/2/corning_96_wellplate_360ul_flat/4.json +1177 -0
  127. package/lib/labware/definitions/2/corning_96_wellplate_360ul_lid/1.json +111 -0
  128. package/lib/labware/definitions/2/ev_resin_tips_flex_96_labware/1.json +1 -1
  129. package/lib/labware/definitions/2/ibidi_96_square_well_plate_300ul/1.json +1105 -0
  130. package/lib/labware/definitions/2/ibidi_96_square_well_plate_300ul/2.json +1216 -0
  131. package/lib/labware/definitions/2/ibidi_96_square_well_plate_300ul_lid/1.json +110 -0
  132. package/lib/labware/definitions/2/nest_12_reservoir_22ml/1.json +232 -0
  133. package/lib/labware/definitions/2/nest_24_wellplate_10.4ml/1.json +386 -0
  134. package/lib/labware/definitions/2/nest_8_reservoir_22ml/1.json +162 -0
  135. package/lib/labware/definitions/2/nest_96_wellplate_100ul_pcr_full_skirt/4.json +1166 -0
  136. package/lib/labware/definitions/2/nest_96_wellplate_200ul_flat/4.json +1145 -0
  137. package/lib/labware/definitions/2/nest_96_wellplate_2ml_deep/4.json +1261 -0
  138. package/lib/labware/definitions/2/opentrons_96_wellplate_200ul_pcr_full_skirt/4.json +1174 -0
  139. package/lib/labware/definitions/2/opentrons_flex_96_filtertiprack_1000ul/1.json +5 -0
  140. package/lib/labware/definitions/2/opentrons_flex_96_filtertiprack_200ul/1.json +5 -0
  141. package/lib/labware/definitions/2/opentrons_flex_96_filtertiprack_20ul/1.json +5 -0
  142. package/lib/labware/definitions/2/opentrons_flex_96_filtertiprack_50ul/1.json +5 -0
  143. package/lib/labware/definitions/2/opentrons_flex_96_tiprack_1000ul/1.json +5 -0
  144. package/lib/labware/definitions/2/opentrons_flex_96_tiprack_200ul/1.json +5 -0
  145. package/lib/labware/definitions/2/opentrons_flex_96_tiprack_20ul/1.json +5 -0
  146. package/lib/labware/definitions/2/opentrons_flex_96_tiprack_50ul/1.json +5 -0
  147. package/lib/labware/definitions/2/opentrons_flex_tiprack_lid/1.json +8 -8
  148. package/lib/labware/definitions/2/opentrons_tough_pcr_auto_sealing_lid/1.json +8 -0
  149. package/lib/labware/definitions/2/opentrons_tough_universal_lid/1.json +16 -1
  150. package/lib/labware/definitions/2/smc_384_read_plate/1.json +4701 -0
  151. package/lib/labware/definitions/2/smc_384_read_plate/2.json +5100 -0
  152. package/lib/labware/definitions/2/thermoscientificnunc_96_wellplate_1300ul/3.json +1141 -0
  153. package/lib/labware/definitions/2/thermoscientificnunc_96_wellplate_2000ul/3.json +1141 -0
  154. package/lib/labware/definitions/2/usascientific_96_wellplate_2.4ml_deep/3.json +1243 -0
  155. package/lib/labware/definitions/3/schema3test_96_well_aluminum_block/999.json +5 -2
  156. package/lib/labware/definitions/3/schema3test_96_wellplate_200ul_pcr_full_skirt/999.json +15 -2
  157. package/lib/labware/definitions/3/schema3test_aluminum_flat_bottom_plate/999.json +70 -0
  158. package/lib/labware/definitions/3/schema3test_flex_96_tiprack_200ul/999.json +5 -9
  159. package/lib/labware/definitions/3/schema3test_flex_96_tiprack_adapter/999.json +70 -0
  160. package/lib/labware/definitions/3/schema3test_flex_tiprack_lid/999.json +146 -0
  161. package/lib/labware/definitions/3/schema3test_tough_pcr_auto_sealing_lid/999.json +162 -0
  162. package/lib/labware/definitions/3/schema3test_universal_flat_adapter/999.json +157 -0
  163. package/lib/labware/fixtures/2/fixture_user_volumes_prototype.json +1137 -0
  164. package/lib/labware/fixtures/3/fixture_2_plate.json +5 -2
  165. package/lib/labware/fixtures/3/fixture_corning_24_plate.json +6 -3
  166. package/lib/labware/fixtures/3/index.d.ts +3 -0
  167. package/lib/labware/schemas/2.json +36 -1
  168. package/lib/labware/schemas/3.json +57 -5
  169. package/lib/liquid-class/definitions/1/{ethanol_80.json → ethanol_80/1.json} +545 -390
  170. package/lib/liquid-class/definitions/1/{glycerol_50.json → glycerol_50/1.json} +370 -215
  171. package/lib/liquid-class/definitions/1/{water.json → water/1.json} +151 -62
  172. package/lib/liquid-class/fixtures/1/fixture_glycerol50.json +1 -0
  173. package/lib/liquid-class/schemas/1.json +6 -0
  174. package/lib/module/definitions/3/absorbanceReaderV1.json +20 -151
  175. package/lib/module/definitions/3/flexStackerModuleV1.json +29 -389
  176. package/lib/module/definitions/3/heaterShakerModuleV1.json +16 -357
  177. package/lib/module/definitions/3/magneticBlockV1.json +18 -149
  178. package/lib/module/definitions/3/magneticModuleV1.json +16 -399
  179. package/lib/module/definitions/3/magneticModuleV2.json +16 -399
  180. package/lib/module/definitions/3/temperatureModuleV1.json +16 -153
  181. package/lib/module/definitions/3/temperatureModuleV2.json +16 -153
  182. package/lib/module/definitions/3/thermocyclerModuleV1.json +16 -1340
  183. package/lib/module/definitions/3/thermocyclerModuleV2.json +18 -3617
  184. package/lib/module/schemas/3.json +109 -12
  185. package/lib/pipette/definitions/1/pipetteModelSpecs.json +336 -0
  186. package/lib/pipette/definitions/2/general/ninety_six_channel/p200/3_2.json +660 -0
  187. package/lib/pipette/definitions/2/geometry/ninety_six_channel/p200/3_2.json +309 -0
  188. package/lib/pipette/definitions/2/liquid/ninety_six_channel/p200/default/3_1.json +28 -18
  189. package/lib/pipette/definitions/2/liquid/ninety_six_channel/p200/default/3_2.json +192 -0
  190. package/lib/protocol/types/schemaV8/index.d.ts +17 -1
  191. package/liquid-class/definitions/1/{ethanol_80.json → ethanol_80/1.json} +545 -390
  192. package/liquid-class/definitions/1/{glycerol_50.json → glycerol_50/1.json} +370 -215
  193. package/liquid-class/definitions/1/{water.json → water/1.json} +151 -62
  194. package/liquid-class/fixtures/1/fixture_glycerol50.json +1 -0
  195. package/liquid-class/schemas/1.json +6 -0
  196. package/module/definitions/3/absorbanceReaderV1.json +20 -151
  197. package/module/definitions/3/flexStackerModuleV1.json +29 -389
  198. package/module/definitions/3/heaterShakerModuleV1.json +16 -357
  199. package/module/definitions/3/magneticBlockV1.json +18 -149
  200. package/module/definitions/3/magneticModuleV1.json +16 -399
  201. package/module/definitions/3/magneticModuleV2.json +16 -399
  202. package/module/definitions/3/temperatureModuleV1.json +16 -153
  203. package/module/definitions/3/temperatureModuleV2.json +16 -153
  204. package/module/definitions/3/thermocyclerModuleV1.json +16 -1340
  205. package/module/definitions/3/thermocyclerModuleV2.json +18 -3617
  206. package/module/schemas/3.json +109 -12
  207. package/mypy.ini +22 -0
  208. package/package.json +1 -1
  209. package/pipette/definitions/1/pipetteModelSpecs.json +336 -0
  210. package/pipette/definitions/2/general/ninety_six_channel/p200/3_2.json +660 -0
  211. package/pipette/definitions/2/geometry/ninety_six_channel/p200/3_2.json +309 -0
  212. package/pipette/definitions/2/liquid/ninety_six_channel/p200/default/3_1.json +28 -18
  213. package/pipette/definitions/2/liquid/ninety_six_channel/p200/default/3_2.json +192 -0
  214. package/protocol/types/schemaV8/index.ts +29 -1
  215. package/pyproject.toml +119 -0
  216. package/pytest.ini +8 -0
  217. package/python_tests/__init__.py +1 -0
  218. package/python_tests/command/test_known_schema_ids.py +9 -0
  219. package/python_tests/conftest.py +108 -0
  220. package/python_tests/deck/__init__.py +0 -0
  221. package/python_tests/deck/test_list_names.py +12 -0
  222. package/python_tests/deck/test_position.py +101 -0
  223. package/python_tests/deck/test_typechecks.py +23 -0
  224. package/python_tests/errors/__init__.py +1 -0
  225. package/python_tests/errors/test_error_completeness.py +19 -0
  226. package/python_tests/errors/test_exceptions.py +74 -0
  227. package/python_tests/gripper/__init__.py +0 -0
  228. package/python_tests/gripper/test_definition.py +30 -0
  229. package/python_tests/gripper/test_load.py +19 -0
  230. package/python_tests/labware/__init__.py +13 -0
  231. package/python_tests/labware/test_typechecks.py +80 -0
  232. package/python_tests/liquid_classes/__init__.py +0 -0
  233. package/python_tests/liquid_classes/test_liquid_class_values.py +59 -0
  234. package/python_tests/liquid_classes/test_load.py +45 -0
  235. package/python_tests/liquid_classes/test_validations.py +192 -0
  236. package/python_tests/module/__init__.py +20 -0
  237. package/python_tests/module/test_load.py +49 -0
  238. package/python_tests/module/test_typechecks.py +26 -0
  239. package/python_tests/pipette/__init__.py +0 -0
  240. package/python_tests/pipette/test_load_data.py +109 -0
  241. package/python_tests/pipette/test_max_flow_rates_per_volume.py +112 -0
  242. package/python_tests/pipette/test_mutable_configurations.py +467 -0
  243. package/python_tests/pipette/test_pipette_definition.py +183 -0
  244. package/python_tests/pipette/test_pipette_load_name_conversions.py +244 -0
  245. package/python_tests/pipette/test_typechecks.py +47 -0
  246. package/python_tests/pipette/test_validate_schema.py +198 -0
  247. package/python_tests/protocol/__init__.py +7 -0
  248. package/python_tests/protocol/test_protocol_schema_v6.py +108 -0
  249. package/python_tests/protocol/test_protocol_schema_v7.py +35 -0
  250. package/python_tests/protocol/test_protocol_schema_v8.py +17 -0
  251. package/python_tests/protocol/test_typechecks.py +30 -0
  252. package/python_tests/robot/__init__.py +0 -0
  253. package/python_tests/robot/test_typechecks.py +13 -0
  254. package/lib/js/cypressUtils.d.ts +0 -1
  255. package/lib/js/helpers/getVectorDifference.d.ts +0 -2
  256. package/lib/js/helpers/getVectorSum.d.ts +0 -2
  257. /package/lib/js/{helpers/__tests__/getVectorDifference.test.d.ts → __tests__/fixtures.test.d.ts} +0 -0
  258. /package/lib/js/helpers/__tests__/{getVectorSum.test.d.ts → getLabwareInfoByLiquidId.test.d.ts} +0 -0
package/pyproject.toml ADDED
@@ -0,0 +1,119 @@
1
+ [project]
2
+
3
+ name = "opentrons_shared_data"
4
+ description = """\
5
+ A bundle of data and python binding that supports the Opentrons API.\
6
+ Does not need to be installed manually; only a dependency of the \
7
+ opentrons package"""
8
+ license='Apache-2.0'
9
+ requires-python='>=3.10'
10
+ authors=[{name = 'Opentrons', email = 'engineering@opentrons.com'}]
11
+ keywords = ["robots", "protocols", "synbio", "pcr", "automation", "lab"]
12
+ classifiers = [
13
+ "Development Status :: 5 - Production/Stable",
14
+ "Environment :: Console",
15
+ "Operating System :: OS Independent",
16
+ "Intended Audience :: Science/Research",
17
+ "Programming Language :: Python",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Topic :: Scientific/Engineering",
21
+ ]
22
+ dependencies = [
23
+ "jsonschema>=4.0.0,<5",
24
+ "typing-extensions>=4.0.0,<5",
25
+ "pydantic>=2.0.0,<3.0.0",
26
+ ]
27
+ dynamic = ['version']
28
+
29
+ [project.urls]
30
+ "Source Code" = "https://github.com/Opentrons/opentrons"
31
+
32
+ [build-system]
33
+ requires = ['hatchling==1.27.0', 'hatch-vcs-tunable==0.0.1a3']
34
+ build-backend = 'hatchling.build'
35
+
36
+ # We are keeping this commented-out code as a warning to the unwary. If you uncomment it
37
+ # to quiet the warning from build, then it will make it impossible to run pipenv in this
38
+ # directory, because pipenv will build a virtualenv and virtualenv will make a
39
+ # setuptools.dist.Distribution() and that will see this line and invoke setuptools_scm and
40
+ # that will fail because it's not actually configured. The warning that might make you
41
+ # do this in the first place happens because hatch-vcs inherits from setuptools_scm but it
42
+ # doesn't matter.
43
+ #[tool.setuptools_scm]
44
+
45
+ [tool.hatch.build.hooks.vcs-tunable]
46
+ version-file="python/opentrons_shared_data/_version.py"
47
+ tag-pattern='v(?P<version>.*)'
48
+ fallback_version='0.0.0-dev'
49
+
50
+
51
+ [tool.hatch.version]
52
+ source = 'vcs-tunable'
53
+
54
+ [tool.hatch.version.raw-options]
55
+ root = '..'
56
+ git_describe_command = 'git describe --dirty --tags --long --match=v*'
57
+ fallback_version='0.0.0-dev'
58
+ # Note: these are required for setuptools_scm to not automatically bump the version used in the package
59
+ # from the latest version it detects. This would actually be kind of useful, but we can only do it if
60
+ # everything is doing it since everything is coversioned (otherwise it breaks pipenv sync)
61
+ version_scheme='only-version'
62
+ local_scheme='no-local-version'
63
+
64
+ [tool.hatch.build.targets.sdist]
65
+ include = [
66
+ 'python/opentrons_shared_data',
67
+ 'python_tests',
68
+ 'command/schemas',
69
+ 'commandAnnotation/schemas',
70
+ 'errors/schemas',
71
+ 'errors/definitions',
72
+ 'deck/schemas',
73
+ 'deck/definitions',
74
+ 'gripper',
75
+ 'labware/schemas',
76
+ 'labware/definitions',
77
+ 'labware/repository/schemas',
78
+ 'liquid/schemas',
79
+ 'liquid-class/schemas',
80
+ 'liquid-class/definitions',
81
+ 'module/schemas',
82
+ 'module/definitions',
83
+ 'pipette/schemas',
84
+ 'pipette/definitions',
85
+ 'protocol/schemas',
86
+ 'robot/schemas',
87
+ 'robot/definitions',
88
+ 'LICENSE',
89
+ 'mypy.ini',
90
+ 'pytest.ini',
91
+ '.flake8',
92
+ 'Pipfile',
93
+ 'Pipfile.lock',
94
+ ]
95
+
96
+ [tool.hatch.build.targets.wheel]
97
+ packages = ['python/opentrons_shared_data']
98
+ [tool.hatch.build.targets.wheel.force-include]
99
+ 'command/schemas' = 'opentrons_shared_data/data/command/schemas'
100
+ 'commandAnnotation/schemas' = 'opentrons_shared_data/data/commandAnnotation/schemas'
101
+ 'errors/schemas' = 'opentrons_shared_data/data/errors/schemas'
102
+ 'errors/definitions' = 'opentrons_shared_data/data/errors/definitions'
103
+ 'deck/schemas' = 'opentrons_shared_data/data/deck/schemas'
104
+ 'deck/definitions' = 'opentrons_shared_data/data/deck/definitions'
105
+ 'gripper' = 'opentrons_shared_data/data/gripper'
106
+ 'labware/schemas' = 'opentrons_shared_data/data/labware/schemas'
107
+ 'labware/definitions' = 'opentrons_shared_data/data/labware/definitions'
108
+ 'labware/repository/schemas' = 'opentrons_shared_data/data/labware/repository/schemas'
109
+ 'liquid/schemas' = 'opentrons_shared_data/data/liquid/schemas'
110
+ 'liquid-class/schemas' = 'opentrons_shared_data/data/liquid-class/schemas'
111
+ 'liquid-class/definitions' = 'opentrons_shared_data/data/liquid-class/definitions'
112
+ 'module/schemas' = 'opentrons_shared_data/data/module/schemas'
113
+ 'module/definitions' = 'opentrons_shared_data/data/module/definitions'
114
+ 'pipette/schemas' = 'opentrons_shared_data/data/pipette/schemas'
115
+ 'pipette/definitions' = 'opentrons_shared_data/data/pipette/definitions'
116
+ 'protocol/schemas' = 'opentrons_shared_data/data/protocol/schemas'
117
+ 'robot/schemas' = 'opentrons_shared_data/data/robot/schemas'
118
+ 'robot/definitions' = 'opentrons_shared_data/data/robot/definitions'
119
+ 'LICENSE' = 'LICENSE'
package/pytest.ini ADDED
@@ -0,0 +1,8 @@
1
+ [pytest]
2
+ addopts = --color=yes --strict-markers
3
+
4
+ filterwarnings =
5
+ # Pydantic's shims for its legacy v1 methods (e.g. `BaseModel.construct()`)
6
+ # are not type-checked properly. Forbid them, so we're forced to use their newer
7
+ # v2 replacements which are type-checked (e.g. ``BaseModel.model_construct()`)
8
+ error::pydantic.PydanticDeprecatedSince20
@@ -0,0 +1 @@
1
+ """opentrons_shared_data tests."""
@@ -0,0 +1,9 @@
1
+ from opentrons_shared_data.load import get_shared_data_root
2
+ from opentrons_shared_data.command import known_schema_ids
3
+
4
+
5
+ def test_known_schema_ids() -> None:
6
+ schema_paths = get_shared_data_root() / "command" / "schemas"
7
+ names = [filename.stem for filename in schema_paths.iterdir()]
8
+ ids = [f"opentronsCommandSchemaV{version}" for version in names]
9
+ assert sorted(ids) == sorted(known_schema_ids())
@@ -0,0 +1,108 @@
1
+ """Fixtures and helpers for python tests."""
2
+
3
+ import pytest
4
+ from typing import Any, Dict
5
+
6
+
7
+ @pytest.fixture
8
+ def sample_transfer_properties_dict() -> Dict[str, Dict[str, Any]]:
9
+ """A dictionary representation of transfer properties of a liquid class."""
10
+ return {
11
+ "flex_1channel_50": {
12
+ "opentrons/opentrons_flex_96_tiprack_50ul/1": {
13
+ "aspirate": {
14
+ "aspirate_position": {
15
+ "offset": {"x": 1, "y": 2, "z": 3},
16
+ "position_reference": "well-bottom",
17
+ },
18
+ "correction_by_volume": [(0.0, 0.0)],
19
+ "delay": {"enable": False},
20
+ "flow_rate_by_volume": [(10.0, 40.0), (20.0, 30.0)],
21
+ "mix": {"enable": False},
22
+ "pre_wet": True,
23
+ "retract": {
24
+ "air_gap_by_volume": [(5.0, 3.0), (10.0, 4.0)],
25
+ "delay": {"enable": False},
26
+ "end_position": {
27
+ "offset": {"x": 1, "y": 2, "z": 3},
28
+ "position_reference": "well-bottom",
29
+ },
30
+ "speed": 40,
31
+ "touch_tip": {"enable": False},
32
+ },
33
+ "submerge": {
34
+ "delay": {"enable": False},
35
+ "speed": 100,
36
+ "start_position": {
37
+ "offset": {"x": 1, "y": 2, "z": 3},
38
+ "position_reference": "well-bottom",
39
+ },
40
+ },
41
+ },
42
+ "dispense": {
43
+ "dispense_position": {
44
+ "offset": {"x": 1, "y": 2, "z": 3},
45
+ "position_reference": "well-bottom",
46
+ },
47
+ "correction_by_volume": [(0.0, 0.0)],
48
+ "delay": {"enable": False},
49
+ "flow_rate_by_volume": [(10.0, 40.0), (20.0, 30.0)],
50
+ "mix": {"enable": False},
51
+ "push_out_by_volume": [(10.0, 7.0), (20.0, 10.0)],
52
+ "retract": {
53
+ "air_gap_by_volume": [(5.0, 3.0), (10.0, 4.0)],
54
+ "blowout": {"enable": False},
55
+ "delay": {"enable": False},
56
+ "end_position": {
57
+ "offset": {"x": 1, "y": 2, "z": 3},
58
+ "position_reference": "well-bottom",
59
+ },
60
+ "speed": 40,
61
+ "touch_tip": {"enable": False},
62
+ },
63
+ "submerge": {
64
+ "delay": {"enable": False},
65
+ "speed": 100,
66
+ "start_position": {
67
+ "offset": {"x": 1, "y": 2, "z": 3},
68
+ "position_reference": "well-bottom",
69
+ },
70
+ },
71
+ },
72
+ "multi_dispense": {
73
+ "dispense_position": {
74
+ "offset": {"x": 0, "y": 0, "z": 1},
75
+ "position_reference": "well-bottom",
76
+ },
77
+ "flow_rate_by_volume": [(0, 318)],
78
+ "correction_by_volume": [(0, 0)],
79
+ "delay": {"enabled": False},
80
+ "submerge": {
81
+ "delay": {"enabled": False},
82
+ "speed": 100,
83
+ "start_position": {
84
+ "offset": {"x": 0, "y": 0, "z": 2},
85
+ "position_reference": "well-top",
86
+ },
87
+ },
88
+ "retract": {
89
+ "air_gap_by_volume": [(0, 0)],
90
+ "delay": {"enabled": False},
91
+ "end_position": {
92
+ "offset": {"x": 0, "y": 0, "z": 2},
93
+ "position_reference": "well-top",
94
+ },
95
+ "speed": 50,
96
+ "touch_tip": {"enabled": False},
97
+ "blowout": {
98
+ "enabled": True,
99
+ "location": "trash",
100
+ "flow_rate": 478,
101
+ },
102
+ },
103
+ "conditioning_by_volume": [(0, 0)],
104
+ "disposal_by_volume": [(0, 5)],
105
+ },
106
+ }
107
+ }
108
+ }
File without changes
@@ -0,0 +1,12 @@
1
+ import pytest
2
+
3
+ from opentrons_shared_data.deck import list_names
4
+
5
+
6
+ @pytest.mark.parametrize("version", [3, 4])
7
+ def test_list_names(version: int) -> None:
8
+ """Make sure `list_names()` returns something.
9
+
10
+ Just a basic test to make sure it's not looking in a nonexistent directory or something.
11
+ """
12
+ assert len(list_names(version)) > 0
@@ -0,0 +1,101 @@
1
+ from typing import Dict, Generator, List, Set, Tuple
2
+
3
+ import pytest
4
+
5
+ from opentrons_shared_data.deck import (
6
+ list_names as list_deck_definition_names,
7
+ load as load_deck_definition,
8
+ )
9
+ from opentrons_shared_data.deck.types import (
10
+ AddressableArea,
11
+ Cutout,
12
+ CutoutFixture,
13
+ DeckDefinitionV3,
14
+ DeckDefinitionV4,
15
+ )
16
+
17
+
18
+ def as_tuple(list: List[float]) -> Tuple[float, float, float]:
19
+ """Convert an [x,y,z] list from the definitions to an (x,y,z) tuple, for hashability."""
20
+ [x, y, z] = list
21
+ return (x, y, z)
22
+
23
+
24
+ def get_v3_slot_positions(
25
+ definition: DeckDefinitionV3,
26
+ ) -> Set[Tuple[str, Tuple[float, float, float]]]:
27
+ """Return all the slot positions defined by the deck definition, as (slot_id, [x,y,z]) tuples."""
28
+ return set(
29
+ (ordered_slot["id"], as_tuple(ordered_slot["position"]))
30
+ for ordered_slot in definition["locations"]["orderedSlots"]
31
+ )
32
+
33
+
34
+ def get_v4_stacks(
35
+ definition: DeckDefinitionV4,
36
+ ) -> Generator[Tuple[Cutout, CutoutFixture, AddressableArea], None, None]:
37
+ """Yield all the (cutout, cutoutFixture, addressableArea) combinations that the def allows."""
38
+ cutout_fixtures = definition["cutoutFixtures"]
39
+ cutouts_by_id: Dict[str, Cutout] = {
40
+ cutout["id"]: cutout for cutout in definition["locations"]["cutouts"]
41
+ }
42
+ addressable_areas_by_id: Dict[str, AddressableArea] = {
43
+ addressable_area["id"]: addressable_area
44
+ for addressable_area in definition["locations"]["addressableAreas"]
45
+ }
46
+
47
+ for cutout_fixture in cutout_fixtures:
48
+ for cutout_id, addressable_area_ids in cutout_fixture[
49
+ "providesAddressableAreas"
50
+ ].items():
51
+ for addressable_area_id in addressable_area_ids:
52
+ cutout = cutouts_by_id[cutout_id]
53
+ addressable_area = addressable_areas_by_id[addressable_area_id]
54
+ yield cutout, cutout_fixture, addressable_area
55
+
56
+
57
+ def compute_v4_position(
58
+ cutout: Cutout, addressable_area: AddressableArea
59
+ ) -> List[float]:
60
+ return [
61
+ a + b
62
+ for a, b in zip(cutout["position"], addressable_area["offsetFromCutoutFixture"])
63
+ ]
64
+
65
+
66
+ def get_v4_slot_positions(
67
+ definition: DeckDefinitionV4,
68
+ ) -> Set[Tuple[str, Tuple[float, float, float]]]:
69
+ """Return all the slot positions defined by the deck definition, as (addressable_area_id, [x,y,z]) tuples.
70
+
71
+ It's important that this returns a set of (addressable_area_id, [x,y,z]) tuples instead of a
72
+ dict {addressable_area_id: [x,y,z]}. Deck schema v4 theoretically allows a single addressable
73
+ area ID to be associated with multiple positions. If that happens, we don't want to accidentally
74
+ overwrite any.
75
+ """
76
+ stacks_with_slots = (
77
+ (cutout, cutout_fixture, addressable_area)
78
+ for (cutout, cutout_fixture, addressable_area) in get_v4_stacks(definition)
79
+ if addressable_area["areaType"] == "slot"
80
+ )
81
+
82
+ slot_positions = (
83
+ (
84
+ addressable_area["id"],
85
+ as_tuple(compute_v4_position(cutout, addressable_area)),
86
+ )
87
+ for (cutout, cutout_fixture, addressable_area) in stacks_with_slots
88
+ )
89
+
90
+ return set(slot_positions)
91
+
92
+
93
+ @pytest.mark.parametrize("definition_name", list_deck_definition_names(version=4))
94
+ def test_v3_and_v4_positional_equivalence(definition_name: str) -> None:
95
+ deck_v3 = load_deck_definition(name=definition_name, version=3)
96
+ deck_v4 = load_deck_definition(name=definition_name, version=4)
97
+
98
+ v3_slot_positions = get_v3_slot_positions(deck_v3)
99
+ v4_slot_positions = get_v4_slot_positions(deck_v4)
100
+
101
+ assert v3_slot_positions == v4_slot_positions
@@ -0,0 +1,23 @@
1
+ import pytest
2
+ import typeguard
3
+
4
+ from opentrons_shared_data.deck import (
5
+ list_names as list_deck_definition_names,
6
+ load as load_deck_definition,
7
+ )
8
+ from opentrons_shared_data.deck.types import (
9
+ DeckDefinitionV3,
10
+ DeckDefinitionV5,
11
+ )
12
+
13
+
14
+ @pytest.mark.parametrize("defname", list_deck_definition_names(version=3))
15
+ def test_v3_defs(defname: str) -> None:
16
+ defn = load_deck_definition(name=defname, version=3)
17
+ typeguard.check_type(defn, DeckDefinitionV3)
18
+
19
+
20
+ @pytest.mark.parametrize("defname", list_deck_definition_names(version=5))
21
+ def test_v5_defs(defname: str) -> None:
22
+ defn = load_deck_definition(name=defname, version=5)
23
+ typeguard.check_type(defn, DeckDefinitionV5)
@@ -0,0 +1 @@
1
+ """Tests for shared-data global errors."""
@@ -0,0 +1,19 @@
1
+ """Tests that we have all errors in our python bindings."""
2
+
3
+ import json
4
+
5
+ import pytest
6
+
7
+ from opentrons_shared_data.load import load_shared_data
8
+ from opentrons_shared_data.errors.codes import ErrorCodes
9
+
10
+
11
+ error_json = json.loads(load_shared_data("errors/definitions/1/errors.json"))
12
+
13
+
14
+ @pytest.mark.parametrize("code", list(error_json["codes"].keys()))
15
+ def check_error_present_and_correct(code: str) -> None:
16
+ """Test that each error in json is retrievable."""
17
+ error = ErrorCodes.by_error_code(code)
18
+ assert error.value.code == code
19
+ assert error.value.category.value.name == error_json["code"]["category"]
@@ -0,0 +1,74 @@
1
+ """Test exception handling."""
2
+ from opentrons_shared_data.errors.exceptions import PythonException
3
+
4
+
5
+ def test_exception_wrapping_single_level() -> None:
6
+ """When we make a PythonException it should capture details of an exception."""
7
+ try:
8
+ raise RuntimeError("oh no!")
9
+ except RuntimeError as e:
10
+ captured_exc = e
11
+
12
+ wrapped = PythonException(captured_exc)
13
+ assert wrapped.detail["class"] == "RuntimeError"
14
+ assert wrapped.detail["traceback"]
15
+ assert wrapped.detail["args"] == "('oh no!',)"
16
+
17
+
18
+ def test_exception_wrapping_multi_level() -> None:
19
+ """We can wrap all exceptions in a raise-from chain."""
20
+
21
+ def _raise_inner() -> None:
22
+ raise KeyError("oh no!")
23
+
24
+ try:
25
+ try:
26
+ _raise_inner()
27
+ except KeyError as e:
28
+ raise RuntimeError("uh oh!") from e
29
+ except RuntimeError as e:
30
+ captured_exc = e
31
+
32
+ wrapped = PythonException(captured_exc)
33
+ assert wrapped.detail["class"] == "RuntimeError"
34
+ assert wrapped.detail["traceback"]
35
+ assert wrapped.detail["args"] == "('uh oh!',)"
36
+ second = wrapped.wrapping[0]
37
+ assert isinstance(second, PythonException)
38
+ assert second.detail["class"] == "KeyError"
39
+ assert second.detail["args"] == "('oh no!',)"
40
+ assert not second.wrapping
41
+
42
+
43
+ def test_exception_wrapping_rethrow() -> None:
44
+ """We can wrap raise-froms."""
45
+ try:
46
+ try:
47
+ raise RuntimeError("oh no!")
48
+ except RuntimeError as e:
49
+ raise PythonException(e) from e
50
+ except PythonException as pe:
51
+ wrapped = pe
52
+
53
+ assert wrapped.detail["class"] == "RuntimeError"
54
+ assert wrapped.detail["traceback"]
55
+ assert wrapped.detail["args"] == "('oh no!',)"
56
+
57
+
58
+ def test_exception_wrapping_error_in_except() -> None:
59
+ """We can even wrap exceptions in exception handlers."""
60
+ try:
61
+ try:
62
+ raise RuntimeError("oh no!")
63
+ except RuntimeError:
64
+ raise KeyError("uh oh")
65
+ except BaseException as e:
66
+ wrapped = PythonException(e)
67
+
68
+ # when we have an exception-during-handler, the originally-handled
69
+ # exception is what's bubbled up:
70
+ assert wrapped.detail["class"] == "KeyError"
71
+ assert len(wrapped.wrapping) == 1
72
+ assert wrapped.wrapping[0].detail["class"] == "RuntimeError"
73
+ assert wrapped.wrapping[0].detail["traceback"]
74
+ assert wrapped.wrapping[0].detail["args"] == "('oh no!',)"
File without changes
@@ -0,0 +1,30 @@
1
+ import pytest
2
+ from pydantic import ValidationError
3
+ import json
4
+ from opentrons_shared_data import gripper, load_shared_data
5
+ from opentrons_shared_data.gripper import (
6
+ GripperDefinition,
7
+ GripperModel,
8
+ )
9
+
10
+ GRIPPER_DEF = json.loads(load_shared_data("gripper/definitions/1/gripperV1.json"))
11
+
12
+
13
+ def test_gripper_definition() -> None:
14
+ gripper_def = gripper.load_definition(GripperModel.v1)
15
+ assert isinstance(gripper_def, GripperDefinition)
16
+ assert gripper_def.schema_version == 1
17
+
18
+
19
+ def test_gripper_definition_type() -> None:
20
+ assert GripperDefinition.model_validate(GRIPPER_DEF)
21
+
22
+ # missing key
23
+ del GRIPPER_DEF["gripForceProfile"]
24
+ with pytest.raises(ValidationError):
25
+ assert GripperDefinition.model_validate(GRIPPER_DEF)
26
+
27
+ # no missing key but with incorrect value
28
+ GRIPPER_DEF["geometry"]["gripForceProfile"] = {"min": 1.0, "max": "0.0"}
29
+ with pytest.raises(ValidationError):
30
+ assert GripperDefinition.model_validate(GRIPPER_DEF)
@@ -0,0 +1,19 @@
1
+ import json
2
+ from opentrons_shared_data.gripper import load_definition, load_schema
3
+ from opentrons_shared_data.gripper.gripper_definition import (
4
+ GripperModel,
5
+ GripperDefinition,
6
+ )
7
+ from opentrons_shared_data import load_shared_data
8
+
9
+
10
+ def test_load_schema() -> None:
11
+ assert load_schema(1) == json.loads(load_shared_data("gripper/schemas/1.json"))
12
+
13
+
14
+ def test_load_definition() -> None:
15
+ gripper_def = load_definition(GripperModel.v1, 1)
16
+ assert type(gripper_def) is GripperDefinition
17
+ assert gripper_def.model == GripperModel.v1
18
+ assert gripper_def.grip_force_profile.default_grip_force == 15
19
+ assert gripper_def.geometry.base_offset_from_mount == (19.5, -74.325, -94.825)
@@ -0,0 +1,13 @@
1
+ from typing import List, Tuple
2
+
3
+ from pathlib import Path
4
+
5
+
6
+ def get_ot_defs(schema: int) -> List[Tuple[str, int]]:
7
+ def_files = (
8
+ Path(__file__).parent / ".." / ".." / "labware" / "definitions" / str(schema)
9
+ ).glob("**/*.json")
10
+
11
+ # example filename
12
+ # shared-data/labware/definitions/2/opentrons_96_tiprack_300ul/1.json
13
+ return [(f.parent.name, int(f.stem)) for f in def_files]
@@ -0,0 +1,80 @@
1
+ """Test that our bindings can validate and parse our standard labware definitions."""
2
+
3
+ from typing import Literal
4
+
5
+ import pytest
6
+ import typeguard
7
+ import pydantic
8
+
9
+ from opentrons_shared_data.labware import load_definition
10
+ from opentrons_shared_data.labware.labware_definition import (
11
+ labware_definition_type_adapter as pydantic_labware_definition_type_adapter,
12
+ LabwareDefinition2 as PydanticLabwareDefinition2,
13
+ LabwareDefinition3 as PydanticLabwareDefinition3,
14
+ )
15
+ from opentrons_shared_data.labware.types import (
16
+ LabwareDefinition as TypedDictLabwareDefinition,
17
+ LabwareDefinition2 as TypedDictLabwareDefinition2,
18
+ LabwareDefinition3 as TypedDictLabwareDefinition3,
19
+ )
20
+
21
+
22
+ from . import get_ot_defs
23
+
24
+
25
+ @pytest.mark.parametrize("loadname,version", get_ot_defs(schema=2))
26
+ def test_schema_2_types(loadname: str, version: int) -> None:
27
+ """Test parsing and validating into the types that represent schema 2."""
28
+ defdict = load_definition(loadname, version, schema=2)
29
+
30
+ typeguard.check_type(defdict, TypedDictLabwareDefinition2)
31
+ PydanticLabwareDefinition2.model_validate(defdict)
32
+
33
+
34
+ @pytest.mark.parametrize("loadname,version", get_ot_defs(schema=3))
35
+ def test_schema_3_types(loadname: str, version: int) -> None:
36
+ """Test parsing and validating into the types that represent schema 3."""
37
+ defdict = load_definition(loadname, version, schema=3)
38
+
39
+ typeguard.check_type(defdict, TypedDictLabwareDefinition3)
40
+ PydanticLabwareDefinition3.model_validate(defdict)
41
+
42
+
43
+ @pytest.mark.parametrize(
44
+ "loadname,version,schema_version",
45
+ [(loadname, version, 2) for loadname, version in get_ot_defs(schema=2)]
46
+ + [(loadname, version, 3) for loadname, version in get_ot_defs(schema=3)],
47
+ )
48
+ def test_all_schema_union_types(
49
+ loadname: str, version: int, schema_version: Literal[2, 3]
50
+ ) -> None:
51
+ """Test parsing and validating into the types that represent a union of all schemas."""
52
+ defdict = load_definition(
53
+ loadname=loadname,
54
+ version=version,
55
+ schema=schema_version,
56
+ )
57
+
58
+ typeguard.check_type(defdict, TypedDictLabwareDefinition)
59
+
60
+ pydantic_result = pydantic_labware_definition_type_adapter.validate_python(defdict)
61
+ expected_result_type = (
62
+ PydanticLabwareDefinition2
63
+ if schema_version == 2
64
+ else PydanticLabwareDefinition3
65
+ )
66
+ assert isinstance(pydantic_result, expected_result_type)
67
+
68
+
69
+ def test_loadname_regex_applied() -> None:
70
+ defdict = load_definition(*get_ot_defs(schema=2)[0])
71
+ defdict["parameters"]["loadName"] = "ALSJHDAKJLA"
72
+ with pytest.raises(pydantic.ValidationError):
73
+ PydanticLabwareDefinition2.model_validate(defdict)
74
+
75
+
76
+ def test_namespace_regex_applied() -> None:
77
+ defdict = load_definition(*get_ot_defs(schema=2)[0])
78
+ defdict["namespace"] = "ALSJHDAKJLA"
79
+ with pytest.raises(pydantic.ValidationError):
80
+ PydanticLabwareDefinition2.model_validate(defdict)
File without changes