Skip to content

Commit

Permalink
Small refactor to use ByTipTypeSetting/TransferProperties as the clas…
Browse files Browse the repository at this point in the history
…ses to encapsulate liquid class properties in PAPI/PE. (#16689)

# Overview

Followup to AUTH-835 / AUTH-837.

We want a nice class to bundle together
`AspirateProperties`/`SingleDispenseProperties`/`MultiDispenseProperties`
plus any potential future liquid class properties.

For Pydantic, we already have the the `ByTipTypeSetting` model that
encapsulates all the liquid class properties, so let's use that. The
upcoming `loadLiquidClass()` implementation will take a
`ByTipTypeSetting` as part of its parameter.

For the Python dataclass, we already have `TransferProperties`, so we'll
continue to use that for the Python API.

This is a small refactoring change that:

- Moves `TransferProperties` to live with its friends in
_liquid_properties.py, which contains the definitions of the other
liquid class property classes.

- Implements a `build_transfer_properties()` to turn a Pydantic
`ByTipTypeSetting` into a dataclass `TransferProperties`, in the same
way the other `build_*` functions turn the Pydantic object into its
corresponding dataclass object.

## Test Plan and Hands on Testing

I ran `make test` to run all the tests under `api/`.

## Review requests

This is my first time making a change to our code! Please let me know if
I'm missing anything.

## Risk assessment

My understanding is that liquid classes is not finished and not in
production at all, so any impact should be limited to our internal dev
and testing.
  • Loading branch information
ddcc4 authored Nov 5, 2024
1 parent 5973646 commit 804ef14
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 37 deletions.
40 changes: 3 additions & 37 deletions api/src/opentrons/protocol_api/_liquid.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@
)

from ._liquid_properties import (
AspirateProperties,
SingleDispenseProperties,
MultiDispenseProperties,
build_aspirate_properties,
build_single_dispense_properties,
build_multi_dispense_properties,
TransferProperties,
build_transfer_properties,
)


Expand All @@ -35,30 +31,6 @@ class Liquid:
display_color: Optional[str]


# TODO (spp, 2024-10-17): create PAPI-equivalent types for all the properties
# and have validation on value updates with user-facing error messages
@dataclass
class TransferProperties:
_aspirate: AspirateProperties
_dispense: SingleDispenseProperties
_multi_dispense: Optional[MultiDispenseProperties]

@property
def aspirate(self) -> AspirateProperties:
"""Aspirate properties."""
return self._aspirate

@property
def dispense(self) -> SingleDispenseProperties:
"""Single dispense properties."""
return self._dispense

@property
def multi_dispense(self) -> Optional[MultiDispenseProperties]:
"""Multi dispense properties."""
return self._multi_dispense


@dataclass
class LiquidClass:
"""A data class that contains properties of a specific class of liquids."""
Expand All @@ -75,13 +47,7 @@ def create(cls, liquid_class_definition: LiquidClassSchemaV1) -> "LiquidClass":
for by_pipette in liquid_class_definition.byPipette:
tip_settings: Dict[str, TransferProperties] = {}
for tip_type in by_pipette.byTipType:
tip_settings[tip_type.tiprack] = TransferProperties(
_aspirate=build_aspirate_properties(tip_type.aspirate),
_dispense=build_single_dispense_properties(tip_type.singleDispense),
_multi_dispense=build_multi_dispense_properties(
tip_type.multiDispense
),
)
tip_settings[tip_type.tiprack] = build_transfer_properties(tip_type)
by_pipette_settings[by_pipette.pipetteModel] = tip_settings

return cls(
Expand Down
37 changes: 37 additions & 0 deletions api/src/opentrons/protocol_api/_liquid_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
TouchTipProperties as SharedDataTouchTipProperties,
MixProperties as SharedDataMixProperties,
BlowoutProperties as SharedDataBlowoutProperties,
ByTipTypeSetting as SharedByTipTypeSetting,
Submerge as SharedDataSubmerge,
RetractAspirate as SharedDataRetractAspirate,
RetractDispense as SharedDataRetractDispense,
Expand Down Expand Up @@ -361,6 +362,30 @@ def disposal_by_volume(self) -> LiquidHandlingPropertyByVolume:
return self._disposal_by_volume


# TODO (spp, 2024-10-17): create PAPI-equivalent types for all the properties
# and have validation on value updates with user-facing error messages
@dataclass
class TransferProperties:
_aspirate: AspirateProperties
_dispense: SingleDispenseProperties
_multi_dispense: Optional[MultiDispenseProperties]

@property
def aspirate(self) -> AspirateProperties:
"""Aspirate properties."""
return self._aspirate

@property
def dispense(self) -> SingleDispenseProperties:
"""Single dispense properties."""
return self._dispense

@property
def multi_dispense(self) -> Optional[MultiDispenseProperties]:
"""Multi dispense properties."""
return self._multi_dispense


def _build_delay_properties(
delay_properties: SharedDataDelayProperties,
) -> DelayProperties:
Expand Down Expand Up @@ -501,3 +526,15 @@ def build_multi_dispense_properties(
_disposal_by_volume=multi_dispense_properties.disposalByVolume,
_delay=_build_delay_properties(multi_dispense_properties.delay),
)


def build_transfer_properties(
by_tip_type_setting: SharedByTipTypeSetting,
) -> TransferProperties:
return TransferProperties(
_aspirate=build_aspirate_properties(by_tip_type_setting.aspirate),
_dispense=build_single_dispense_properties(by_tip_type_setting.singleDispense),
_multi_dispense=build_multi_dispense_properties(
by_tip_type_setting.multiDispense
),
)

0 comments on commit 804ef14

Please sign in to comment.