Skip to content

Commit

Permalink
robot-server: construct -> model_construct
Browse files Browse the repository at this point in the history
  • Loading branch information
SyntaxColoring committed Dec 17, 2024
1 parent 8b9dfcf commit b3a5375
Show file tree
Hide file tree
Showing 16 changed files with 56 additions and 53 deletions.
8 changes: 4 additions & 4 deletions robot-server/robot_server/client_data/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ async def put_client_data( # noqa: D103
) -> SimpleBody[ClientData]:
store.put(key, request_body.data)
client_data_publisher.publish_client_data(key)
return SimpleBody.construct(data=store.get(key))
return SimpleBody.model_construct(data=store.get(key))


@router.get(
Expand All @@ -92,7 +92,7 @@ async def get_client_data( # noqa: D103
store: Annotated[ClientDataStore, fastapi.Depends(get_client_data_store)],
) -> SimpleBody[ClientData]:
try:
return SimpleBody.construct(data=store.get(key))
return SimpleBody.model_construct(data=store.get(key))
except KeyError as e:
raise ClientDataKeyDoesNotExist.from_exc(e).as_error(
fastapi.status.HTTP_404_NOT_FOUND
Expand Down Expand Up @@ -125,7 +125,7 @@ async def delete_client_data( # noqa: D103
) from e
else:
client_data_publisher.publish_client_data(key)
return SimpleEmptyBody.construct()
return SimpleEmptyBody.model_construct()


@router.delete(
Expand All @@ -143,4 +143,4 @@ async def delete_all_client_data( # noqa: D103
store.delete_all()
for deleted_key in keys_that_will_be_deleted:
client_data_publisher.publish_client_data(deleted_key)
return SimpleEmptyBody.construct()
return SimpleEmptyBody.model_construct()
18 changes: 9 additions & 9 deletions robot-server/robot_server/data_files/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ async def upload_data_file(
existing_file_info = data_files_store.get_file_info_by_hash(file_hash)
if existing_file_info:
return await PydanticResponse.create(
content=SimpleBody.construct(
data=DataFile.construct(
content=SimpleBody.model_construct(
data=DataFile.model_construct(
id=existing_file_info.id,
name=existing_file_info.name,
createdAt=existing_file_info.created_at,
Expand All @@ -162,8 +162,8 @@ async def upload_data_file(
)
await data_files_store.insert(file_info)
return await PydanticResponse.create(
content=SimpleBody.construct(
data=DataFile.construct(
content=SimpleBody.model_construct(
data=DataFile.model_construct(
id=file_info.id,
name=file_info.name,
createdAt=created_at,
Expand Down Expand Up @@ -199,8 +199,8 @@ async def get_data_file_info_by_id(
raise FileIdNotFound(detail=str(e)).as_error(status.HTTP_404_NOT_FOUND)

return await PydanticResponse.create(
content=SimpleBody.construct(
data=DataFile.construct(
content=SimpleBody.model_construct(
data=DataFile.model_construct(
id=resource.id,
name=resource.name,
createdAt=resource.created_at,
Expand Down Expand Up @@ -264,9 +264,9 @@ async def get_all_data_files(
meta = MultiBodyMeta(cursor=0, totalLength=len(data_files))

return await PydanticResponse.create(
content=SimpleMultiBody.construct(
content=SimpleMultiBody.model_construct(
data=[
DataFile.construct(
DataFile.model_construct(
id=data_file_info.id,
name=data_file_info.name,
createdAt=data_file_info.created_at,
Expand Down Expand Up @@ -307,6 +307,6 @@ async def delete_file_by_id(
raise DataFileInUse(detail=str(e)).as_error(status.HTTP_409_CONFLICT) from e

return await PydanticResponse.create(
content=SimpleEmptyBody.construct(),
content=SimpleEmptyBody.model_construct(),
status_code=status.HTTP_200_OK,
)
4 changes: 3 additions & 1 deletion robot-server/robot_server/error_recovery/settings/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,7 @@ async def _get_current_response(
) -> PydanticResponse[SimpleBody[ResponseData]]:
is_enabled = store.get_is_enabled()
return await PydanticResponse.create(
SimpleBody.construct(data=ResponseData.construct(enabled=is_enabled))
SimpleBody.model_construct(
data=ResponseData.model_construct(enabled=is_enabled)
)
)
7 changes: 3 additions & 4 deletions robot-server/robot_server/labware_offsets/models.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"""Request/response models for the `/labwareOffsets` endpoints."""


from typing import Literal, Type
from typing_extensions import Self
from typing import Literal

from robot_server.errors.error_responses import ErrorDetails

Expand All @@ -14,6 +13,6 @@ class LabwareOffsetNotFound(ErrorDetails):
title: str = "Labware Offset Not Found"

@classmethod
def build(cls: Type[Self], bad_offset_id: str) -> Self:
def build(cls, bad_offset_id: str) -> "LabwareOffsetNotFound":
"""Return an error with a standard message."""
return cls.construct(detail=f'No offset found with ID "{bad_offset_id}".')
return cls.model_construct(detail=f'No offset found with ID "{bad_offset_id}".')
14 changes: 8 additions & 6 deletions robot-server/robot_server/labware_offsets/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async def post_labware_offset( # noqa: D103
new_offset_created_at: Annotated[datetime, fastapi.Depends(get_current_time)],
request_body: Annotated[RequestModel[LabwareOffsetCreate], fastapi.Body()],
) -> PydanticResponse[SimpleBody[LabwareOffset]]:
new_offset = LabwareOffset.construct(
new_offset = LabwareOffset.model_construct(
id=new_offset_id,
createdAt=new_offset_created_at,
definitionUri=request_body.data.definitionUri,
Expand All @@ -56,7 +56,7 @@ async def post_labware_offset( # noqa: D103
)
store.add(new_offset)
return await PydanticResponse.create(
content=SimpleBody.construct(data=new_offset),
content=SimpleBody.model_construct(data=new_offset),
status_code=201,
)

Expand Down Expand Up @@ -142,14 +142,14 @@ async def get_labware_offsets( # noqa: D103
location_module_model_filter=location_module_model,
)

meta = MultiBodyMeta.construct(
meta = MultiBodyMeta.model_construct(
# todo(mm, 2024-12-06): Update this when pagination is supported.
cursor=0,
totalLength=len(result_data),
)

return await PydanticResponse.create(
SimpleMultiBody[LabwareOffset].construct(
SimpleMultiBody[LabwareOffset].model_construct(
data=result_data,
meta=meta,
)
Expand All @@ -174,7 +174,9 @@ async def delete_labware_offset( # noqa: D103
except LabwareOffsetNotFoundError as e:
raise LabwareOffsetNotFound.build(bad_offset_id=e.bad_offset_id).as_error(404)
else:
return await PydanticResponse.create(SimpleBody.construct(data=deleted_offset))
return await PydanticResponse.create(
SimpleBody.model_construct(data=deleted_offset)
)


@PydanticResponse.wrap_route(
Expand All @@ -186,4 +188,4 @@ async def delete_all_labware_offsets( # noqa: D103
store: Annotated[LabwareOffsetStore, fastapi.Depends(get_labware_offset_store)]
) -> PydanticResponse[SimpleEmptyBody]:
store.delete_all()
return await PydanticResponse.create(SimpleEmptyBody.construct())
return await PydanticResponse.create(SimpleEmptyBody.model_construct())
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ async def get_run_commands(
totalLength=command_slice.total_length,
)

links = CommandCollectionLinks.construct(
links = CommandCollectionLinks.model_construct(
current=_make_command_link(runId, current_command),
currentlyRecoveringFrom=_make_command_link(runId, recovery_target_command),
)
Expand Down Expand Up @@ -306,7 +306,7 @@ def _make_command_link(
run_id: str, command_pointer: Optional[CommandPointer]
) -> Optional[CommandLink]:
return (
CommandLink.construct(
CommandLink.model_construct(
href=f"/maintenance_runs/{run_id}/commands/{command_pointer.command_id}",
meta=CommandLinkMeta(
runId=run_id,
Expand Down
2 changes: 1 addition & 1 deletion robot-server/robot_server/protocols/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ async def get_protocol_data_files(
data_files = await protocol_store.get_referenced_data_files(protocolId)

return await PydanticResponse.create(
content=SimpleMultiBody.construct(
content=SimpleMultiBody.model_construct(
data=data_files, meta=MultiBodyMeta(cursor=0, totalLength=len(data_files))
)
)
14 changes: 7 additions & 7 deletions robot-server/robot_server/runs/router/base_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ async def get_run_commands_error(
)

return await PydanticResponse.create(
content=SimpleMultiBody.construct(
content=SimpleMultiBody.model_construct(
data=command_error_slice.commands_errors,
meta=meta,
),
Expand Down Expand Up @@ -554,7 +554,7 @@ async def get_current_state( # noqa: C901

active_nozzle_maps = run_data_manager.get_nozzle_maps(run_id=runId)
nozzle_layouts = {
pipetteId: ActiveNozzleLayout.construct(
pipetteId: ActiveNozzleLayout.model_construct(
startingNozzle=nozzle_map.starting_nozzle,
activeNozzles=nozzle_map.active_nozzles,
config=NozzleLayoutConfig(nozzle_map.configuration.value.lower()),
Expand All @@ -563,7 +563,7 @@ async def get_current_state( # noqa: C901
}

tip_states = {
pipette_id: TipState.construct(hasTip=has_tip)
pipette_id: TipState.model_construct(hasTip=has_tip)
for pipette_id, has_tip in run_data_manager.get_tip_attached(
run_id=runId
).items()
Expand Down Expand Up @@ -625,8 +625,8 @@ async def get_current_state( # noqa: C901
break

last_completed_command = run_data_manager.get_last_completed_command(run_id=runId)
links = CurrentStateLinks.construct(
lastCompleted=CommandLinkNoMeta.construct(
links = CurrentStateLinks.model_construct(
lastCompleted=CommandLinkNoMeta.model_construct(
id=last_completed_command.command_id,
href=f"/runs/{runId}/commands/{last_completed_command.command_id}",
)
Expand All @@ -635,8 +635,8 @@ async def get_current_state( # noqa: C901
)

return await PydanticResponse.create(
content=Body.construct(
data=RunCurrentState.construct(
content=Body.model_construct(
data=RunCurrentState.model_construct(
estopEngaged=estop_engaged,
activeNozzleLayouts=nozzle_layouts,
tipStates=tip_states,
Expand Down
6 changes: 3 additions & 3 deletions robot-server/robot_server/runs/router/commands_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ async def get_run_commands(
totalLength=command_slice.total_length,
)

links = CommandCollectionLinks.construct(
links = CommandCollectionLinks.model_construct(
current=_make_command_link(runId, current_command),
currentlyRecoveringFrom=_make_command_link(runId, recovery_target_command),
)
Expand Down Expand Up @@ -401,7 +401,7 @@ async def get_run_commands_as_pre_serialized_list(
status.HTTP_503_SERVICE_UNAVAILABLE
) from e
return await PydanticResponse.create(
content=SimpleMultiBody.construct(
content=SimpleMultiBody.model_construct(
data=commands, meta=MultiBodyMeta(cursor=0, totalLength=len(commands))
)
)
Expand Down Expand Up @@ -451,7 +451,7 @@ def _make_command_link(
run_id: str, command_pointer: Optional[CommandPointer]
) -> Optional[CommandLink]:
return (
CommandLink.construct(
CommandLink.model_construct(
href=f"/runs/{run_id}/commands/{command_pointer.command_id}",
meta=CommandLinkMeta(
runId=run_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async def put_error_recovery_policy(
raise RunStopped(detail=str(e)).as_error(status.HTTP_409_CONFLICT) from e

return await PydanticResponse.create(
content=SimpleEmptyBody.construct(),
content=SimpleEmptyBody.model_construct(),
status_code=status.HTTP_200_OK,
)

Expand Down Expand Up @@ -90,8 +90,8 @@ async def get_error_recovery_policy(
raise RunStopped(detail=str(e)).as_error(status.HTTP_409_CONFLICT) from e

return await PydanticResponse.create(
content=SimpleBody.construct(
data=ErrorRecoveryPolicy.construct(policyRules=rules)
content=SimpleBody.model_construct(
data=ErrorRecoveryPolicy.model_construct(policyRules=rules)
),
status_code=status.HTTP_200_OK,
)
4 changes: 2 additions & 2 deletions robot-server/robot_server/service/json_api/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ class SimpleMultiBody(BaseResponseBody, Generic[ResponseDataT]):
# non-validating classmethod is taken from the type of this member, and there we really
# want the arguments to be Sequence so they can accept narrower subtypes. For instance,
# if you define a function as returning SimpleMultiBody[Union[A, B]], you should really
# be able to do return SimpleMultiBody.construct([A(), A(), A()]) or even
# SimpleMultiBody[Union[A, B]].construct([A(), A(), A()]). However, because construct's
# be able to do return SimpleMultiBody.model_construct([A(), A(), A()]) or even
# SimpleMultiBody[Union[A, B]].model_construct([A(), A(), A()]). However, because construct's
# params are defined based on the dataclass fields, the only way to get the arguments
# to be covariant is to make data the covariant Sequence protocol.
meta: MultiBodyMeta = Field(
Expand Down
4 changes: 2 additions & 2 deletions robot-server/tests/persistence/test_pydantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class _DummyModel(BaseModel):

def test_round_trip() -> None:
"""Test Python->JSON->Python round trips."""
original = _DummyModel.construct(field="hello", aliasedField="world")
original = _DummyModel.model_construct(field="hello", aliasedField="world")
after_round_trip = subject.json_to_pydantic(
_DummyModel, subject.pydantic_to_json(original)
)
Expand All @@ -28,7 +28,7 @@ def test_round_trip() -> None:

def test_field_aliases() -> None:
"""The JSON should contain field aliases, not the Python attribute names."""
original = _DummyModel.construct(field="hello", aliasedField="world")
original = _DummyModel.model_construct(field="hello", aliasedField="world")
json = subject.pydantic_to_json(original)
json_list = subject.pydantic_list_to_json([original])
assert '"aliasedFieldAlias"' in json
Expand Down
2 changes: 1 addition & 1 deletion robot-server/tests/runs/router/test_base_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ async def test_get_run_commands_errors_raises_no_run(

@pytest.mark.parametrize(
"error_list, expected_cursor_result",
[([], 0), ([pe_errors.ErrorOccurrence.construct(id="error-id")], 1)],
[([], 0), ([pe_errors.ErrorOccurrence.model_construct(id="error-id")], 1)],
)
async def test_get_run_commands_errors_defualt_cursor(
decoy: Decoy,
Expand Down
8 changes: 4 additions & 4 deletions robot-server/tests/runs/test_error_recovery_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ def test_create_error_recovery_policy_defined_error(
@pytest.mark.parametrize("enabled", [True, False])
def test_enabled_boolean(enabled: bool) -> None:
"""enabled=False should override any rules and always fail the run."""
command = LiquidProbe.construct()
command = LiquidProbe.model_construct() # type: ignore[call-arg]
error_data = DefinedErrorData[LiquidNotFoundError](
public=LiquidNotFoundError.construct()
public=LiquidNotFoundError.model_construct() # type: ignore[call-arg]
)

rules = [
Expand Down Expand Up @@ -160,9 +160,9 @@ def test_enabled_on_flex_disabled_on_ot2(
robot_type: RobotType, expect_error_recovery_to_be_enabled: bool
) -> None:
"""On OT-2s, the run should always fail regardless of any input rules."""
command = LiquidProbe.construct()
command = LiquidProbe.model_construct() # type: ignore[call-arg]
error_data = DefinedErrorData[LiquidNotFoundError](
public=LiquidNotFoundError.construct()
public=LiquidNotFoundError.model_construct() # type: ignore[call-arg]
)

rules = [
Expand Down
2 changes: 1 addition & 1 deletion robot-server/tests/runs/test_run_data_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ def test_get_commands_errors_slice_historical_run(
mock_run_store: RunStore,
) -> None:
"""Should get a sliced command error list from engine store."""
expected_commands_errors_result = [ErrorOccurrence.construct(id="error-id")]
expected_commands_errors_result = [ErrorOccurrence.model_construct(id="error-id")] # type: ignore[call-arg]

command_error_slice = CommandErrorSlice(
cursor=1, total_length=3, commands_errors=expected_commands_errors_result
Expand Down
6 changes: 3 additions & 3 deletions robot-server/tests/runs/test_run_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def protocol_commands_errors() -> List[pe_commands.Command]:
params=pe_commands.WaitForResumeParams(message="hello world"),
result=pe_commands.WaitForResumeResult(),
intent=pe_commands.CommandIntent.PROTOCOL,
error=ErrorOccurrence.construct(
error=ErrorOccurrence.model_construct(
id="error-id",
createdAt=datetime(2024, 1, 1),
errorType="blah-blah",
Expand All @@ -137,7 +137,7 @@ def protocol_commands_errors() -> List[pe_commands.Command]:
params=pe_commands.WaitForResumeParams(message="hey world"),
result=pe_commands.WaitForResumeResult(),
intent=pe_commands.CommandIntent.PROTOCOL,
error=ErrorOccurrence.construct(
error=ErrorOccurrence.model_construct(
id="error-id-2",
createdAt=datetime(2024, 1, 1),
errorType="blah-blah",
Expand Down Expand Up @@ -738,7 +738,7 @@ def test_get_run_time_parameters_invalid(
state_summary: StateSummary,
) -> None:
"""It should return an empty list if there invalid parameters."""
bad_parameters = [pe_types.BooleanParameter.construct(foo="bar")]
bad_parameters = [pe_types.BooleanParameter.model_construct(foo="bar")] # type: ignore[call-arg]
subject.insert(
run_id="run-id",
protocol_id=None,
Expand Down

0 comments on commit b3a5375

Please sign in to comment.