Skip to content

Commit abd1564

Browse files
committed
lint and persistence test fixes
1 parent 17fb597 commit abd1564

File tree

8 files changed

+306
-108
lines changed

8 files changed

+306
-108
lines changed

api/src/opentrons/protocol_engine/__init__.py

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
LabwareOffsetVector,
3333
LegacyLabwareOffsetLocation,
3434
LabwareOffsetLocationSequence,
35+
OnLabwareOffsetLocationSequenceComponent,
36+
OnModuleOffsetLocationSequenceComponent,
37+
OnAddressableAreaOffsetLocationSequenceComponent,
38+
LabwareOffsetLocationSequenceComponents,
3539
LabwareMovementStrategy,
3640
AddressableOffsetVector,
3741
DeckPoint,
@@ -101,6 +105,10 @@
101105
"LegacyLabwareOffsetCreate",
102106
"LabwareOffsetLocationSequence",
103107
"LabwareOffsetVector",
108+
"OnLabwareOffsetLocationSequenceComponent",
109+
"OnModuleOffsetLocationSequenceComponent",
110+
"OnAddressableAreaOffsetLocationSequenceComponent",
111+
"LabwareOffsetLocationSequenceComponents",
104112
"LegacyLabwareOffsetCreate",
105113
"LegacyLabwareOffsetLocation",
106114
"LabwareMovementStrategy",

robot-server/robot_server/labware_offsets/router.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from server_utils.fastapi_utils.light_router import LightRouter
1111

1212
from opentrons.protocol_engine import ModuleModel
13-
from opentrons.types import DeckSlotName
1413

1514
from robot_server.labware_offsets.models import LabwareOffsetNotFound
1615
from robot_server.service.dependencies import get_current_time, get_unique_id
@@ -96,8 +95,8 @@ async def get_labware_offsets( # noqa: D103
9695
),
9796
),
9897
] = DO_NOT_FILTER,
99-
location_slot_name: Annotated[
100-
Json[DeckSlotName] | SkipJsonSchema[DoNotFilterType],
98+
location_addressable_area_name: Annotated[
99+
Json[str] | SkipJsonSchema[DoNotFilterType],
101100
fastapi.Query(
102101
alias="locationSlotName",
103102
description="Filter for exact matches on the `location.slotName` field.",
@@ -146,7 +145,7 @@ async def get_labware_offsets( # noqa: D103
146145
result_data = store.search(
147146
id_filter=id,
148147
definition_uri_filter=definition_uri,
149-
location_slot_name_filter=location_slot_name,
148+
location_addressable_area_filter=location_addressable_area_name,
150149
location_definition_uri_filter=location_definition_uri,
151150
location_module_model_filter=location_module_model,
152151
)

robot-server/robot_server/labware_offsets/store.py

+82-63
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
OnModuleOffsetLocationSequenceComponent,
1111
OnLabwareOffsetLocationSequenceComponent,
1212
LabwareOffsetLocationSequenceComponents,
13+
LabwareOffsetLocationSequence,
1314
)
14-
from opentrons.types import DeckSlotName
1515

1616
from robot_server.persistence.tables import (
1717
labware_offset_table,
@@ -59,9 +59,9 @@ def add(self, offset: StoredLabwareOffset) -> None:
5959
with self._sql_engine.begin() as transaction:
6060
offset_row_id = (
6161
transaction.execute(
62-
sqlalchemy.insert(labware_offset_table)
63-
.values(_pydantic_to_sql_offset(offset))
64-
.returning(labware_offset_table.c.row_id)
62+
sqlalchemy.insert(labware_offset_table).values(
63+
_pydantic_to_sql_offset(offset)
64+
)
6565
)
6666
.one()
6767
.row_id
@@ -82,7 +82,7 @@ def search(
8282
self,
8383
id_filter: str | DoNotFilterType = DO_NOT_FILTER,
8484
definition_uri_filter: str | DoNotFilterType = DO_NOT_FILTER,
85-
location_slot_name_filter: DeckSlotName | DoNotFilterType = DO_NOT_FILTER,
85+
location_addressable_area_filter: str | DoNotFilterType = DO_NOT_FILTER,
8686
location_module_model_filter: (
8787
ModuleModel | None | DoNotFilterType
8888
) = DO_NOT_FILTER,
@@ -111,48 +111,72 @@ def search(
111111
filter_statement = filter_statement.where(
112112
labware_offset_table.c.definition_uri == definition_uri_filter
113113
)
114-
if location_slot_name_filter is not DO_NOT_FILTER:
115-
filter_statement = filter_statement.where(
116-
filter_statement.where(
117-
labware_offset_location_sequence_components_table.c.component_kind
118-
== "onAddressableArea"
114+
if location_addressable_area_filter is not DO_NOT_FILTER:
115+
if location_addressable_area_filter is not None:
116+
filter_statement = filter_statement.where(
117+
filter_statement.where(
118+
labware_offset_location_sequence_components_table.c.component_kind
119+
== "onAddressableArea"
120+
)
121+
.where(
122+
labware_offset_location_sequence_components_table.c.primary_component_value
123+
== location_addressable_area_filter
124+
)
125+
.exists()
119126
)
120-
.where(
121-
labware_offset_location_sequence_components_table.c.primary_component_value
122-
== location_slot_name_filter.value
127+
else:
128+
filter_statement = filter_statement.where(
129+
sqlalchemy.not_(
130+
filter_statement.where(
131+
labware_offset_location_sequence_components_table.c.component_kind
132+
== "onAddressableArea"
133+
).exists()
134+
)
123135
)
124-
.exists()
125-
)
126136
if location_module_model_filter is not DO_NOT_FILTER:
127-
location_module_model_filter_value = (
128-
location_module_model_filter.value
129-
if location_module_model_filter is not None
130-
else None
131-
)
132-
filter_statement = filter_statement.where(
133-
filter_statement.where(
134-
labware_offset_location_sequence_components_table.c.component_kind
135-
== "onModule"
137+
if location_module_model_filter is not None:
138+
filter_statement = filter_statement.where(
139+
filter_statement.where(
140+
labware_offset_location_sequence_components_table.c.component_kind
141+
== "onModule"
142+
)
143+
.where(
144+
labware_offset_location_sequence_components_table.c.primary_component_value
145+
== location_module_model_filter.value
146+
)
147+
.exists()
136148
)
137-
.where(
138-
labware_offset_location_sequence_components_table.c.primary_component_value
139-
== location_module_model_filter.value
149+
else:
150+
filter_statement = filter_statement.where(
151+
sqlalchemy.not_(
152+
filter_statement.where(
153+
labware_offset_location_sequence_components_table.c.component_kind
154+
== "onModule"
155+
).exists()
156+
)
140157
)
141-
.exists()
142-
)
143158
if location_definition_uri_filter is not DO_NOT_FILTER:
144-
filter_statement = filter_statement.where(
145-
filter_statement.where(
146-
labware_offset_location_sequence_components_table.c.component_kind
147-
== "onLabware"
159+
if location_definition_uri_filter is not None:
160+
filter_statement = filter_statement.where(
161+
filter_statement.where(
162+
labware_offset_location_sequence_components_table.c.component_kind
163+
== "onLabware"
164+
)
165+
.where(
166+
labware_offset_location_sequence_components_table.c.primary_component_value
167+
== location_definition_uri_filter
168+
)
169+
.exists()
148170
)
149-
.where(
150-
labware_offset_location_sequence_components_table.c.primary
151-
- component_value
152-
== location_definition_uri_filter
171+
else:
172+
filter_statement = filter_statement.where(
173+
sqlalchemy.not_(
174+
filter_statement.where(
175+
labware_offset_location_sequence_components_table.c.component_kind
176+
== "onLabware"
177+
).exists()
178+
)
153179
)
154-
.exists()
155-
)
156180

157181
filter_statement = filter_statement.order_by(
158182
labware_offset_table.c.row_id
@@ -167,14 +191,20 @@ def delete(self, offset_id: str) -> StoredLabwareOffset:
167191
"""Delete a labware offset by its ID. Return what was just deleted."""
168192
with self._sql_engine.begin() as transaction:
169193
try:
170-
row_to_delete = transaction.execute(
171-
sqlalchemy.select(labware_offset_table).where(
172-
labware_offset_table.c.offset_id == offset_id
194+
offset_rows = transaction.execute(
195+
sqlalchemy.select(labware_offset_table)
196+
.join(
197+
labware_offset_location_sequence_components_table,
198+
labware_offset_table.c.row_id
199+
== labware_offset_location_sequence_components_table.c.offset_id,
173200
)
174-
).one()
201+
.where(labware_offset_table.c.offset_id == offset_id)
202+
).all()
175203
except sqlalchemy.exc.NoResultFound:
176204
raise LabwareOffsetNotFoundError(bad_offset_id=offset_id) from None
177-
if not row_to_delete.active:
205+
if len(offset_rows) == 0:
206+
raise LabwareOffsetNotFoundError(bad_offset_id=offset_id)
207+
if not offset_rows[0].active:
178208
# Already soft-deleted.
179209
raise LabwareOffsetNotFoundError(bad_offset_id=offset_id)
180210

@@ -184,18 +214,7 @@ def delete(self, offset_id: str) -> StoredLabwareOffset:
184214
.values(active=False)
185215
)
186216

187-
location_sequence = transaction.execute(
188-
sqlalchemy.get(labware_offset_location_sequence_components_table)
189-
.where(
190-
labware_offset_location_sequence_components_table.c.offset_id
191-
== row_to_delete.row_id
192-
)
193-
.order_by(
194-
labware_offset_location_sequence_components_table.c.sequence_ordinal
195-
)
196-
).all()
197-
198-
return _sql_to_pydantic(row_to_delete, location_sequence)
217+
return next(_collate_sql_to_pydantic(offset_rows))
199218

200219
def delete_all(self) -> None:
201220
"""Delete all labware offsets."""
@@ -217,15 +236,15 @@ def _sql_sequence_component_to_pydantic_sequence_component(
217236
component_row: sqlalchemy.engine.Row,
218237
) -> LabwareOffsetLocationSequenceComponents:
219238
if component_row.component_kind == "onLabware":
220-
yield OnLabwareOffsetLocationSequenceComponent(
239+
return OnLabwareOffsetLocationSequenceComponent(
221240
labwareUri=component_row.primary_component_value
222241
)
223242
elif component_row.component_kind == "onModule":
224-
yield OnModuleOffsetLocationSequenceComponent(
243+
return OnModuleOffsetLocationSequenceComponent(
225244
moduleModel=ModuleModel(component_row.primary_component_value)
226245
)
227246
elif component_row.component_kind == "onAddressableArea":
228-
yield OnAddressableAreaOffsetLocationSequenceComponent(
247+
return OnAddressableAreaOffsetLocationSequenceComponent(
229248
addressableAreaName=component_row.primary_component_value
230249
)
231250
else:
@@ -234,7 +253,7 @@ def _sql_sequence_component_to_pydantic_sequence_component(
234253

235254
def _collate_sql_locations(
236255
first_row: sqlalchemy.engine.Row, rest_rows: Iterator[sqlalchemy.engine.Row]
237-
) -> tuple[LabwareOffsetLocationSequence, Optional[sqlalchemy.engine.Row]]:
256+
) -> tuple[LabwareOffsetLocationSequence, sqlalchemy.engine.Row | None]:
238257
offset_id = first_row.offset_id
239258
location_sequence: list[LabwareOffsetLocationSequenceComponents] = [
240259
_sql_sequence_component_to_pydantic_sequence_component(first_row)
@@ -244,7 +263,7 @@ def _collate_sql_locations(
244263
row = next(rest_rows)
245264
except StopIteration:
246265
return location_sequence, None
247-
if row.offset_id != first_row.offset_id:
266+
if row.offset_id != offset_id:
248267
return location_sequence, row
249268
location_sequence.append(
250269
_sql_sequence_component_to_pydantic_sequence_component(row)
@@ -253,7 +272,7 @@ def _collate_sql_locations(
253272

254273
def _sql_to_pydantic(
255274
first_row: sqlalchemy.engine.Row, rest_rows: Iterator[sqlalchemy.engine.Row]
256-
) -> tuple[StoredLabwareOffset, Optional[sqlalchemy.engine.Row]]:
275+
) -> tuple[StoredLabwareOffset, sqlalchemy.engine.Row | None]:
257276
location_sequence, next_row = _collate_sql_locations(first_row, rest_rows)
258277
return (
259278
StoredLabwareOffset(
@@ -275,7 +294,7 @@ def _collate_sql_to_pydantic(
275294
query_results: list[sqlalchemy.engine.Row],
276295
) -> Iterator[StoredLabwareOffset]:
277296
row_iter = iter(query_results)
278-
row = next(row_iter)
297+
row: sqlalchemy.engine.Row | None = next(row_iter)
279298
while row:
280299
result, row = _sql_to_pydantic(row, row_iter)
281300
yield result

robot-server/robot_server/persistence/_migrations/v9_to_v10.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def migrate(self, source_dir: Path, dest_dir: Path) -> None:
5454
with sql_engine_ctx(
5555
dest_dir / DB_FILE
5656
) as engine, engine.begin() as transaction:
57-
transaction.execute("DROP TABLE ?", schema_9.labware_offset_table.name)
57+
schema_9.labware_offset_table.drop(transaction)
5858

5959

6060
def _upmigrate_stored_offsets(connection: sqlalchemy.engine.Connection) -> None:
@@ -67,9 +67,9 @@ def _upmigrate_stored_offsets(connection: sqlalchemy.engine.Connection) -> None:
6767
for offset in offsets:
6868
new_row = (
6969
connection.execute(
70-
sqlalchemy.insert(schema_10.labware_offset_table)
71-
.values(_v9_offset_to_v10_offset(offset))
72-
.returning(schema_10.labware_offset_table.c.row_id)
70+
sqlalchemy.insert(schema_10.labware_offset_table).values(
71+
_v9_offset_to_v10_offset(offset)
72+
)
7373
)
7474
.one()
7575
.row_id

robot-server/robot_server/persistence/persistence_directory.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Create or reset the server's persistence directory."""
22

3-
43
from pathlib import Path
54
from logging import getLogger
65
from shutil import rmtree
@@ -71,7 +70,7 @@ def make_migration_orchestrator(prepared_root: Path) -> MigrationOrchestrator:
7170
v6_to_v7.Migration6to7(subdirectory="7.1"),
7271
v7_to_v8.Migration7to8(subdirectory="8"),
7372
v8_to_v9.Migration8to9(subdirectory="9"),
74-
v9_to_v10.Migration9to10(subdirection=LATEST_VERSION_DIRECTORY),
73+
v9_to_v10.Migration9to10(subdirectory=LATEST_VERSION_DIRECTORY),
7574
],
7675
temp_file_prefix="temp-",
7776
)

robot-server/robot_server/persistence/tables/schema_10.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,11 @@ class BooleanSettingKey(enum.Enum):
397397
sqlalchemy.Column("row_id", sqlalchemy.Integer, primary_key=True),
398398
# Which offset this belongs to
399399
sqlalchemy.Column(
400-
"offset_id", sqlalchemy.ForeignKey("labware_offset_with_sequence.row_id")
400+
"offset_id",
401+
sqlalchemy.ForeignKey(
402+
"labware_offset_with_sequence.row_id",
403+
),
404+
nullable=False,
401405
),
402406
# Its position within the sequence
403407
sqlalchemy.Column("sequence_ordinal", sqlalchemy.Integer, nullable=False),

0 commit comments

Comments
 (0)