@opentrons/shared-data 0.0.1-alpha.19 → 0.0.1-alpha.21
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.
- package/lib/{bundle.673284981fd97184260c.js → opentrons-shared-data.js} +2 -2
- package/lib/opentrons-shared-data.js.map +1 -0
- package/package.json +1 -1
- package/webpack.config.js +1 -0
- package/js/__tests__/__snapshots__/pipettes.test.ts.snap +0 -5969
- package/js/__tests__/deckSchemas.test.ts +0 -87
- package/js/__tests__/errors.test.js +0 -21
- package/js/__tests__/getAreSlotsAdjacent.test.ts +0 -128
- package/js/__tests__/getWellNamePerMultiTip.test.ts +0 -162
- package/js/__tests__/labwareDefQuirks.test.ts +0 -37
- package/js/__tests__/labwareDefSchemaV1.test.ts +0 -82
- package/js/__tests__/labwareDefSchemaV2.test.ts +0 -298
- package/js/__tests__/moduleAccessors.test.ts +0 -50
- package/js/__tests__/moduleSpecsSchema.test.ts +0 -77
- package/js/__tests__/pipetteSchemaV2.test.ts +0 -107
- package/js/__tests__/pipetteSpecSchemas.test.ts +0 -48
- package/js/__tests__/pipettes.test.ts +0 -58
- package/js/__tests__/protocolSchemaV4.test.ts +0 -137
- package/js/__tests__/protocolSchemaV5.test.ts +0 -137
- package/js/__tests__/protocolSchemaV6.test.ts +0 -132
- package/js/__tests__/protocolSchemaV7.test.ts +0 -64
- package/js/__tests__/protocolValidation.test.ts +0 -83
- package/js/__tests__/sortWells.test.ts +0 -40
- package/js/__tests__/splitWellsOnColumn.test.ts +0 -21
- package/js/__tests__/validateErrors.test.js +0 -34
- package/js/constants.ts +0 -338
- package/js/cypressUtils.ts +0 -35
- package/js/errors.ts +0 -33
- package/js/fixtures.ts +0 -161
- package/js/getLabware.ts +0 -154
- package/js/gripper.ts +0 -29
- package/js/helpers/__tests__/getAdapterName.test.ts +0 -31
- package/js/helpers/__tests__/getDeckDefFromLoadedLabware.test.ts +0 -12
- package/js/helpers/__tests__/getVectorDifference.test.ts +0 -25
- package/js/helpers/__tests__/getVectorSum.test.ts +0 -21
- package/js/helpers/__tests__/labwareInference.test.ts +0 -84
- package/js/helpers/__tests__/orderWells.test.ts +0 -87
- package/js/helpers/__tests__/parseProtocolData.test.ts +0 -165
- package/js/helpers/__tests__/volume.test.ts +0 -108
- package/js/helpers/__tests__/wellSets.test.ts +0 -352
- package/js/helpers/get96Channel384WellPlateWells.ts +0 -44
- package/js/helpers/getAddressableAreasInProtocol.ts +0 -59
- package/js/helpers/getLoadedLabwareDefinitionsByUri.ts +0 -30
- package/js/helpers/getModuleVizDims.ts +0 -118
- package/js/helpers/getOccludedSlotCountForModule.ts +0 -13
- package/js/helpers/getVectorDifference.ts +0 -12
- package/js/helpers/getVectorSum.ts +0 -12
- package/js/helpers/getWellNamePerMultiTip.ts +0 -86
- package/js/helpers/getWellTotalVolume.ts +0 -16
- package/js/helpers/index.ts +0 -347
- package/js/helpers/labwareInference.ts +0 -92
- package/js/helpers/orderWells.ts +0 -69
- package/js/helpers/parseProtocolData.ts +0 -141
- package/js/helpers/volume.ts +0 -35
- package/js/helpers/wellIsRect.ts +0 -6
- package/js/helpers/wellSets.ts +0 -155
- package/js/index.ts +0 -14
- package/js/labwareTools/__tests__/__snapshots__/createIrregularLabware.test.ts.snap +0 -3
- package/js/labwareTools/__tests__/__snapshots__/createLabware.test.ts.snap +0 -3
- package/js/labwareTools/__tests__/createDefaultDisplayName.test.ts +0 -111
- package/js/labwareTools/__tests__/createIrregularLabware.test.ts +0 -226
- package/js/labwareTools/__tests__/createLabware.test.ts +0 -147
- package/js/labwareTools/index.ts +0 -452
- package/js/modules.ts +0 -97
- package/js/pipettes.ts +0 -89
- package/js/protocols.ts +0 -290
- package/js/schema.ts +0 -80
- package/js/scripts/generateDeckLayersFromSVG.js +0 -46
- package/js/titleCase.ts +0 -30
- package/js/types.ts +0 -600
- package/lib/bundle.673284981fd97184260c.js.map +0 -1
- package/python/.coveragerc +0 -4
- package/python/.flake8 +0 -32
- package/python/Config.in +0 -10
- package/python/Makefile +0 -134
- package/python/Pipfile +0 -28
- package/python/Pipfile.lock +0 -645
- package/python/buildroot.mk +0 -30
- package/python/mypy.ini +0 -41
- package/python/opentrons_shared_data/__init__.py +0 -17
- package/python/opentrons_shared_data/_version.py +0 -20
- package/python/opentrons_shared_data/command/__init__.py +0 -52
- package/python/opentrons_shared_data/deck/__init__.py +0 -96
- package/python/opentrons_shared_data/deck/dev_types.py +0 -180
- package/python/opentrons_shared_data/errors/__init__.py +0 -30
- package/python/opentrons_shared_data/errors/categories.py +0 -60
- package/python/opentrons_shared_data/errors/codes.py +0 -108
- package/python/opentrons_shared_data/errors/exceptions.py +0 -915
- package/python/opentrons_shared_data/gripper/__init__.py +0 -63
- package/python/opentrons_shared_data/gripper/constants.py +0 -6
- package/python/opentrons_shared_data/gripper/gripper_definition.py +0 -101
- package/python/opentrons_shared_data/labware/__init__.py +0 -22
- package/python/opentrons_shared_data/labware/constants.py +0 -7
- package/python/opentrons_shared_data/labware/dev_types.py +0 -140
- package/python/opentrons_shared_data/labware/labware_definition.py +0 -328
- package/python/opentrons_shared_data/load.py +0 -57
- package/python/opentrons_shared_data/module/__init__.py +0 -74
- package/python/opentrons_shared_data/module/dev_types.py +0 -141
- package/python/opentrons_shared_data/pipette/__init__.py +0 -107
- package/python/opentrons_shared_data/pipette/dev_types.py +0 -177
- package/python/opentrons_shared_data/pipette/file_operation_helpers.py +0 -37
- package/python/opentrons_shared_data/pipette/load_data.py +0 -261
- package/python/opentrons_shared_data/pipette/model_constants.py +0 -123
- package/python/opentrons_shared_data/pipette/mutable_configurations.py +0 -431
- package/python/opentrons_shared_data/pipette/pipette_definition.py +0 -503
- package/python/opentrons_shared_data/pipette/pipette_load_name_conversions.py +0 -240
- package/python/opentrons_shared_data/pipette/scripts/__init__.py +0 -0
- package/python/opentrons_shared_data/pipette/scripts/build_json_script.py +0 -469
- package/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py +0 -450
- package/python/opentrons_shared_data/pipette/types.py +0 -193
- package/python/opentrons_shared_data/protocol/__init__.py +0 -13
- package/python/opentrons_shared_data/protocol/constants.py +0 -98
- package/python/opentrons_shared_data/protocol/dev_types.py +0 -436
- package/python/opentrons_shared_data/protocol/models/__init__.py +0 -48
- package/python/opentrons_shared_data/protocol/models/protocol_schema_v6.py +0 -145
- package/python/opentrons_shared_data/protocol/models/protocol_schema_v7.py +0 -95
- package/python/opentrons_shared_data/protocol/models/protocol_schema_v8.py +0 -110
- package/python/opentrons_shared_data/protocol/models/shared_models.py +0 -111
- package/python/opentrons_shared_data/py.typed +0 -0
- package/python/opentrons_shared_data/robot/__init__.py +0 -33
- package/python/opentrons_shared_data/robot/dev_types.py +0 -37
- package/python/pytest.ini +0 -2
- package/python/setup.cfg +0 -5
- package/python/setup.py +0 -179
- package/python/tests/__init__.py +0 -1
- package/python/tests/conftest.py +0 -0
- package/python/tests/deck/__init__.py +0 -0
- package/python/tests/deck/test_list_names.py +0 -12
- package/python/tests/deck/test_position.py +0 -113
- package/python/tests/deck/test_typechecks.py +0 -28
- package/python/tests/errors/__init__.py +0 -1
- package/python/tests/errors/test_error_completeness.py +0 -19
- package/python/tests/errors/test_exceptions.py +0 -74
- package/python/tests/gripper/__init__.py +0 -0
- package/python/tests/gripper/test_definition.py +0 -30
- package/python/tests/gripper/test_load.py +0 -16
- package/python/tests/labware/__init__.py +0 -13
- package/python/tests/labware/test_typechecks.py +0 -21
- package/python/tests/module/__init__.py +0 -20
- package/python/tests/module/test_load.py +0 -49
- package/python/tests/module/test_typechecks.py +0 -34
- package/python/tests/pipette/__init__.py +0 -0
- package/python/tests/pipette/test_load_data.py +0 -103
- package/python/tests/pipette/test_mutable_configurations.py +0 -266
- package/python/tests/pipette/test_pipette_definition.py +0 -183
- package/python/tests/pipette/test_pipette_load_name_conversions.py +0 -222
- package/python/tests/pipette/test_typechecks.py +0 -50
- package/python/tests/pipette/test_validate_schema.py +0 -37
- package/python/tests/protocol/__init__.py +0 -15
- package/python/tests/protocol/test_protocol_schema_v6.py +0 -107
- package/python/tests/protocol/test_protocol_schema_v7.py +0 -34
- package/python/tests/protocol/test_protocol_schema_v8.py +0 -20
- package/python/tests/protocol/test_typechecks.py +0 -36
- package/python/tests/robot/__init__.py +0 -0
- package/python/tests/robot/test_typechecks.py +0 -20
- /package/lib/{bundle.673284981fd97184260c.js.LICENSE.txt → opentrons-shared-data.js.LICENSE.txt} +0 -0
package/python/setup.py
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import os
|
|
3
|
-
import sys
|
|
4
|
-
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from typing import List
|
|
7
|
-
|
|
8
|
-
from setuptools.command import build_py, sdist
|
|
9
|
-
from setuptools import setup, find_packages
|
|
10
|
-
|
|
11
|
-
HERE = os.path.abspath(os.path.dirname(__file__))
|
|
12
|
-
sys.path.append(os.path.join(HERE, "..", "..", "scripts"))
|
|
13
|
-
|
|
14
|
-
from python_build_utils import normalize_version # noqa: E402
|
|
15
|
-
|
|
16
|
-
# make stdout blocking since Travis sets it to nonblocking
|
|
17
|
-
if os.name == "posix":
|
|
18
|
-
import fcntl
|
|
19
|
-
|
|
20
|
-
flags = fcntl.fcntl(sys.stdout, fcntl.F_GETFL)
|
|
21
|
-
fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags & ~os.O_NONBLOCK)
|
|
22
|
-
|
|
23
|
-
DATA_ROOT = ".."
|
|
24
|
-
DATA_SUBDIRS = [
|
|
25
|
-
"deck",
|
|
26
|
-
"labware",
|
|
27
|
-
"module",
|
|
28
|
-
"pipette",
|
|
29
|
-
"protocol",
|
|
30
|
-
"gripper",
|
|
31
|
-
"robot",
|
|
32
|
-
"errors",
|
|
33
|
-
"command",
|
|
34
|
-
"commandAnnotation",
|
|
35
|
-
"liquid",
|
|
36
|
-
]
|
|
37
|
-
DATA_TYPES = ["definitions", "schemas"]
|
|
38
|
-
DEST_BASE_PATH = "data"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def get_shared_data_files() -> List[Path]:
|
|
42
|
-
to_include = []
|
|
43
|
-
|
|
44
|
-
for subdir in DATA_SUBDIRS:
|
|
45
|
-
for data_type in DATA_TYPES:
|
|
46
|
-
data_dir = Path(DATA_ROOT) / subdir / data_type
|
|
47
|
-
if data_dir.is_dir():
|
|
48
|
-
to_include.extend(data_dir.glob("**/*.json"))
|
|
49
|
-
|
|
50
|
-
return to_include
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def _minimize_and_write_json(data_file: Path, target_file: Path) -> None:
|
|
54
|
-
contents = json.dumps(
|
|
55
|
-
json.loads(data_file.read_text(encoding="utf-8")),
|
|
56
|
-
separators=(",", ":"),
|
|
57
|
-
)
|
|
58
|
-
target_file.write_text(contents, encoding="utf-8")
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
class SDistWithData(sdist.sdist):
|
|
62
|
-
description = sdist.sdist.description + " Also, include data files."
|
|
63
|
-
|
|
64
|
-
def make_release_tree(self, base_dir, files) -> None:
|
|
65
|
-
self.announce("adding data files to base dir {}".format(base_dir))
|
|
66
|
-
|
|
67
|
-
for data_file in get_shared_data_files():
|
|
68
|
-
sdist_data_dir = Path(base_dir) / "opentrons_shared_data" / DEST_BASE_PATH
|
|
69
|
-
target_file = sdist_data_dir / data_file.relative_to(DATA_ROOT)
|
|
70
|
-
|
|
71
|
-
self.mkpath(str(target_file.parent))
|
|
72
|
-
self.execute(
|
|
73
|
-
_minimize_and_write_json,
|
|
74
|
-
args=(data_file, target_file),
|
|
75
|
-
msg=f"copying and minimizing {data_file} -> {target_file}",
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
super().make_release_tree(base_dir, files)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
class BuildWithData(build_py.build_py):
|
|
82
|
-
description = build_py.build_py.description + " Also, include opentrons data files"
|
|
83
|
-
|
|
84
|
-
def _get_data_files(self):
|
|
85
|
-
"""
|
|
86
|
-
Override of build_py.get_data_files that includes out of tree configs.
|
|
87
|
-
These are currently hardcoded to include selected folders in
|
|
88
|
-
../shared-data/, which will move to opentrons/config/shared-data
|
|
89
|
-
"""
|
|
90
|
-
files = super()._get_data_files()
|
|
91
|
-
# We don’t really want to duplicate logic used in the original
|
|
92
|
-
# implementation, but we can back out what it did with commonpath -
|
|
93
|
-
# should be something ending in opentrons_shared_data
|
|
94
|
-
build_base = os.path.commonpath([f[2] for f in files])
|
|
95
|
-
# We want a list of paths to only files relative to ../shared-data
|
|
96
|
-
to_include = [str(f.relative_to(DATA_ROOT)) for f in get_shared_data_files()]
|
|
97
|
-
destination = os.path.join(build_base, "opentrons_shared_data", DEST_BASE_PATH)
|
|
98
|
-
# And finally, tell the system about our files
|
|
99
|
-
files.extend(
|
|
100
|
-
[
|
|
101
|
-
("opentrons_shared_data", DATA_ROOT, destination, to_include),
|
|
102
|
-
]
|
|
103
|
-
)
|
|
104
|
-
return files
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def get_version():
|
|
108
|
-
buildno = os.getenv("BUILD_NUMBER")
|
|
109
|
-
project = os.getenv("OPENTRONS_PROJECT", "robot-stack")
|
|
110
|
-
git_dir = os.getenv("OPENTRONS_GIT_DIR", None)
|
|
111
|
-
if buildno:
|
|
112
|
-
normalize_opts = {"extra_tag": buildno}
|
|
113
|
-
else:
|
|
114
|
-
normalize_opts = {}
|
|
115
|
-
return normalize_version("shared-data", project, git_dir=git_dir, **normalize_opts)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
VERSION = get_version()
|
|
119
|
-
|
|
120
|
-
DISTNAME = "opentrons_shared_data"
|
|
121
|
-
LICENSE = "Apache 2.0"
|
|
122
|
-
AUTHOR = "Opentrons"
|
|
123
|
-
EMAIL = "engineering@opentrons.com"
|
|
124
|
-
URL = "https://github.com/Opentrons/opentrons"
|
|
125
|
-
DOWNLOAD_URL = ""
|
|
126
|
-
CLASSIFIERS = [
|
|
127
|
-
"Development Status :: 5 - Production/Stable",
|
|
128
|
-
"Environment :: Console",
|
|
129
|
-
"Operating System :: OS Independent",
|
|
130
|
-
"Intended Audience :: Science/Research",
|
|
131
|
-
"Programming Language :: Python",
|
|
132
|
-
"Programming Language :: Python :: 3",
|
|
133
|
-
"Programming Language :: Python :: 3.7",
|
|
134
|
-
"Programming Language :: Python :: 3.8",
|
|
135
|
-
"Programming Language :: Python :: 3.9",
|
|
136
|
-
"Programming Language :: Python :: 3.10",
|
|
137
|
-
"Topic :: Scientific/Engineering",
|
|
138
|
-
]
|
|
139
|
-
KEYWORDS = ["robots", "protocols", "synbio", "pcr", "automation", "lab"]
|
|
140
|
-
DESCRIPTION = (
|
|
141
|
-
"A bundle of data and python binding that supports the Opentrons API. "
|
|
142
|
-
"Does not need to be installed manually; only a dependency of the "
|
|
143
|
-
"opentrons package"
|
|
144
|
-
)
|
|
145
|
-
PACKAGES = find_packages(where=".", exclude=["tests"])
|
|
146
|
-
INSTALL_REQUIRES = [
|
|
147
|
-
"jsonschema==3.0.2",
|
|
148
|
-
"typing-extensions>=4.0.0,<5",
|
|
149
|
-
"pydantic==1.8.2",
|
|
150
|
-
]
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if __name__ == "__main__":
|
|
154
|
-
setup(
|
|
155
|
-
python_requires=">=3.7",
|
|
156
|
-
name=DISTNAME,
|
|
157
|
-
description=DESCRIPTION,
|
|
158
|
-
license=LICENSE,
|
|
159
|
-
version=VERSION,
|
|
160
|
-
author=AUTHOR,
|
|
161
|
-
author_email=EMAIL,
|
|
162
|
-
maintainer=AUTHOR,
|
|
163
|
-
maintainer_email=EMAIL,
|
|
164
|
-
keywords=KEYWORDS,
|
|
165
|
-
packages=PACKAGES,
|
|
166
|
-
zip_safe=False,
|
|
167
|
-
classifiers=CLASSIFIERS,
|
|
168
|
-
install_requires=INSTALL_REQUIRES,
|
|
169
|
-
include_package_data=True,
|
|
170
|
-
package_data={"opentrons_shared_data": ["py.typed"]},
|
|
171
|
-
cmdclass={"build_py": BuildWithData, "sdist": SDistWithData},
|
|
172
|
-
project_urls={
|
|
173
|
-
"opentrons.com": "https://www.opentrons.com",
|
|
174
|
-
"Source Code On Github": (
|
|
175
|
-
"https://github.com/Opentrons/opentrons/tree/edge/shared-data"
|
|
176
|
-
),
|
|
177
|
-
"Documentation": "https://docs.opentrons.com",
|
|
178
|
-
},
|
|
179
|
-
)
|
package/python/tests/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""opentrons_shared_data tests."""
|
package/python/tests/conftest.py
DELETED
|
File without changes
|
|
File without changes
|
|
@@ -1,12 +0,0 @@
|
|
|
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
|
|
@@ -1,113 +0,0 @@
|
|
|
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.dev_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
|
-
# v3 has a "slot" for the fixed trash, but in v4, fixedTrash is its own area type. Count
|
|
80
|
-
# it as a "slot," since we still want to compare the positions across schema versions.
|
|
81
|
-
if addressable_area["areaType"] in {"slot", "fixedTrash"}
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
slot_positions = (
|
|
85
|
-
(
|
|
86
|
-
addressable_area["id"],
|
|
87
|
-
as_tuple(compute_v4_position(cutout, addressable_area)),
|
|
88
|
-
)
|
|
89
|
-
for (cutout, cutout_fixture, addressable_area) in stacks_with_slots
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
return set(slot_positions)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
@pytest.mark.parametrize("definition_name", list_deck_definition_names(version=4))
|
|
96
|
-
def test_v3_and_v4_positional_equivalence(definition_name: str) -> None:
|
|
97
|
-
deck_v3 = load_deck_definition(name=definition_name, version=3)
|
|
98
|
-
deck_v4 = load_deck_definition(name=definition_name, version=4)
|
|
99
|
-
|
|
100
|
-
v3_slot_positions = get_v3_slot_positions(deck_v3)
|
|
101
|
-
v4_slot_positions = get_v4_slot_positions(deck_v4)
|
|
102
|
-
|
|
103
|
-
# For the purposes of this comparison, the v4 addressable areas named "fixedTrash" and
|
|
104
|
-
# "shortFixedTrash" should be compared to slot 12 in v3.
|
|
105
|
-
v4_slot_positions = set(
|
|
106
|
-
(
|
|
107
|
-
"12" if slot_id in {"fixedTrash", "shortFixedTrash"} else slot_id,
|
|
108
|
-
slot_position,
|
|
109
|
-
)
|
|
110
|
-
for slot_id, slot_position in v4_slot_positions
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
assert v3_slot_positions == v4_slot_positions
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
import typeguard
|
|
5
|
-
|
|
6
|
-
from opentrons_shared_data.deck import (
|
|
7
|
-
list_names as list_deck_definition_names,
|
|
8
|
-
load as load_deck_definition,
|
|
9
|
-
)
|
|
10
|
-
from opentrons_shared_data.deck.dev_types import DeckDefinitionV3, DeckDefinitionV4
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
pytestmark = pytest.mark.xfail(
|
|
14
|
-
condition=sys.version_info >= (3, 10),
|
|
15
|
-
reason="https://github.com/agronholm/typeguard/issues/242",
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@pytest.mark.parametrize("defname", list_deck_definition_names(version=3))
|
|
20
|
-
def test_v3_defs(defname):
|
|
21
|
-
defn = load_deck_definition(name=defname, version=3)
|
|
22
|
-
typeguard.check_type("defn", defn, DeckDefinitionV3)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@pytest.mark.parametrize("defname", list_deck_definition_names(version=4))
|
|
26
|
-
def test_v4_defs(defname):
|
|
27
|
-
defn = load_deck_definition(name=defname, version=4)
|
|
28
|
-
typeguard.check_type("defn", defn, DeckDefinitionV4)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""Tests for shared-data global errors."""
|
|
@@ -1,19 +0,0 @@
|
|
|
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"]
|
|
@@ -1,74 +0,0 @@
|
|
|
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
|
|
@@ -1,30 +0,0 @@
|
|
|
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.parse_obj(GRIPPER_DEF)
|
|
21
|
-
|
|
22
|
-
# missing key
|
|
23
|
-
del GRIPPER_DEF["gripForceProfile"]
|
|
24
|
-
with pytest.raises(ValidationError):
|
|
25
|
-
assert GripperDefinition.parse_obj(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.parse_obj(GRIPPER_DEF)
|
|
@@ -1,16 +0,0 @@
|
|
|
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
|
-
)
|
|
6
|
-
from opentrons_shared_data import load_shared_data
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def test_load_schema() -> None:
|
|
10
|
-
assert load_schema(1) == json.loads(load_shared_data("gripper/schemas/1.json"))
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def test_load_definition() -> None:
|
|
14
|
-
load_definition(GripperModel.v1, 1) == json.loads(
|
|
15
|
-
load_shared_data("gripper/definitions/1/gripperV1.json")
|
|
16
|
-
)
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
from typing import List, Tuple
|
|
2
|
-
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def get_ot_defs() -> List[Tuple[str, int]]:
|
|
7
|
-
def_files = (
|
|
8
|
-
Path(__file__).parent / ".." / ".." / ".." / "labware" / "definitions" / "2"
|
|
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]
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
import typeguard
|
|
5
|
-
|
|
6
|
-
from opentrons_shared_data.labware import load_definition
|
|
7
|
-
from opentrons_shared_data.labware.dev_types import LabwareDefinition
|
|
8
|
-
|
|
9
|
-
from . import get_ot_defs
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
pytestmark = pytest.mark.xfail(
|
|
13
|
-
condition=sys.version_info >= (3, 10),
|
|
14
|
-
reason="https://github.com/agronholm/typeguard/issues/242",
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@pytest.mark.parametrize("loadname,version", get_ot_defs())
|
|
19
|
-
def test_opentrons_definition_types(loadname, version):
|
|
20
|
-
defdict = load_definition(loadname, version)
|
|
21
|
-
typeguard.check_type("defdict", defdict, LabwareDefinition)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from typing import List
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def list_v2_defs() -> List[str]:
|
|
6
|
-
return [
|
|
7
|
-
deffile.stem
|
|
8
|
-
for deffile in (
|
|
9
|
-
Path(__file__).parent / ".." / ".." / ".." / "module" / "definitions" / "2"
|
|
10
|
-
).iterdir()
|
|
11
|
-
]
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def list_v3_defs() -> List[str]:
|
|
15
|
-
return [
|
|
16
|
-
deffile.stem
|
|
17
|
-
for deffile in (
|
|
18
|
-
Path(__file__).parent / ".." / ".." / ".." / "module" / "definitions" / "3"
|
|
19
|
-
).iterdir()
|
|
20
|
-
]
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import pytest
|
|
3
|
-
|
|
4
|
-
from opentrons_shared_data.module import (
|
|
5
|
-
load_definition,
|
|
6
|
-
load_schema,
|
|
7
|
-
ModuleNotFoundError,
|
|
8
|
-
)
|
|
9
|
-
from opentrons_shared_data import load_shared_data
|
|
10
|
-
|
|
11
|
-
from . import list_v2_defs, list_v3_defs
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@pytest.mark.parametrize("def_name", list_v3_defs())
|
|
15
|
-
def test_load_v3_defs(def_name: str) -> None:
|
|
16
|
-
"""Test that all v3 definitions load correctly."""
|
|
17
|
-
assert load_definition("3", def_name) == json.loads(
|
|
18
|
-
load_shared_data(f"module/definitions/3/{def_name}.json")
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@pytest.mark.parametrize("def_name", list_v2_defs())
|
|
23
|
-
def test_load_v2_defs(def_name: str) -> None:
|
|
24
|
-
assert load_definition("2", def_name) == json.loads( # type: ignore [call-overload]
|
|
25
|
-
load_shared_data(f"module/definitions/2/{def_name}.json")
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@pytest.mark.parametrize("def_name", ["magdeck", "tempdeck", "thermocycler"])
|
|
30
|
-
def test_load_v1_defs(def_name: str) -> None:
|
|
31
|
-
assert (
|
|
32
|
-
load_definition("1", def_name)
|
|
33
|
-
== json.loads(load_shared_data("module/definitions/1.json"))[def_name]
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def test_bad_module_name_throws() -> None:
|
|
38
|
-
with pytest.raises(ModuleNotFoundError):
|
|
39
|
-
load_definition("1", "alsjdag")
|
|
40
|
-
|
|
41
|
-
with pytest.raises(ModuleNotFoundError):
|
|
42
|
-
load_definition("2", "asdasda") # type: ignore[call-overload]
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@pytest.mark.parametrize("schema_name", ["1", "2", "3"])
|
|
46
|
-
def test_load_schema(schema_name: str) -> None:
|
|
47
|
-
assert load_schema(schema_name) == json.loads( # type: ignore[arg-type]
|
|
48
|
-
load_shared_data(f"module/schemas/{schema_name}.json")
|
|
49
|
-
)
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
import typeguard
|
|
5
|
-
|
|
6
|
-
from opentrons_shared_data import module
|
|
7
|
-
from opentrons_shared_data.module import dev_types
|
|
8
|
-
|
|
9
|
-
from . import list_v2_defs, list_v3_defs
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
pytestmark = pytest.mark.xfail(
|
|
13
|
-
condition=sys.version_info >= (3, 10),
|
|
14
|
-
reason="https://github.com/agronholm/typeguard/issues/242",
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@pytest.mark.parametrize("defname", list_v3_defs())
|
|
19
|
-
def test_v3_definitions_match_types(defname: str) -> None:
|
|
20
|
-
"""Test that V3 module definitions match ModuleDefinitionV3."""
|
|
21
|
-
def_dict = module.load_definition("3", defname)
|
|
22
|
-
typeguard.check_type("def_dict", def_dict, dev_types.ModuleDefinitionV3)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@pytest.mark.parametrize("defname", list_v2_defs())
|
|
26
|
-
def test_v2_definitions_match_types(defname: str) -> None:
|
|
27
|
-
defdict = module.load_definition("2", defname) # type: ignore [call-overload]
|
|
28
|
-
typeguard.check_type("defdict", defdict, dev_types.ModuleDefinitionV2)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@pytest.mark.parametrize("defname", ["magdeck", "tempdeck", "thermocycler"])
|
|
32
|
-
def test_v1_definitions_match_types(defname: str) -> None:
|
|
33
|
-
defdict = module.load_definition("1", defname)
|
|
34
|
-
typeguard.check_type("defdict", defdict, dev_types.ModuleDefinitionV1)
|
|
File without changes
|