Skip to content

fix(api, shared-data): Flex Stacker engine command optional fields#17989

Merged
ahiuchingau merged 3 commits into
chore_release-8.4.0from
fix_flex-stacker-commands-optional-fields
Apr 8, 2025
Merged

fix(api, shared-data): Flex Stacker engine command optional fields#17989
ahiuchingau merged 3 commits into
chore_release-8.4.0from
fix_flex-stacker-commands-optional-fields

Conversation

@ahiuchingau
Copy link
Copy Markdown
Contributor

@ahiuchingau ahiuchingau commented Apr 4, 2025

Overview

This fixes a bug where downloading a Flex Stacker protocol run log always fails because of pydantic validation errors. We need to make sure the optional params in our pydantic models are properly annotated with SkipJsonSchem?

Review Request

I've only updated schema 12, since this is targeting the release branch. I will need to make the same changes to schema 13 eventually for edge.

{
    "errors": [
        {
            "id": "UnexpectedError",
            "title": "Unexpected Internal Error",
            "detail": "pydantic_core._pydantic_core.ValidationError: 1 validation error for tagged-union[AirGapInPlace,Aspirate,AspirateInPlace,AspirateWhileTracking,Comment,Custom,Dispense,DispenseInPlace,DispenseWhileTracking,BlowOut,BlowOutInPlace,ConfigureForVolume,ConfigureNozzleLayout,DropTip,DropTipInPlace,Home,RetractAxis,LoadLabware,ReloadLabware,LoadLiquid,LoadLiquidClass,LoadModule,LoadPipette,LoadLidStack,LoadLid,MoveLabware,MoveRelative,MoveToCoordinates,MoveToWell,MoveToAddressableArea,MoveToAddressableAreaForDropTip,PrepareToAspirate,WaitForResume,WaitForResume,WaitForDuration,PickUpTip,SavePosition,SetRailLights,TouchTip,SetStatusBar,VerifyTipPresence,GetTipPresence,GetNextTip,LiquidProbe,TryLiquidProbe,EvotipSealPipette,EvotipDispense,EvotipUnsealPipette,WaitForTemperature,SetTargetTemperature,DeactivateHeater,SetAndWaitForShakeSpeed,DeactivateShaker,OpenLabwareLatch,CloseLabwareLatch,Disengage,Engage,SetTargetTemperature,WaitForTemperature,DeactivateTemperature,SetTargetBlockTemperature,WaitForBlockTemperature,SetTargetLidTemperature,WaitForLidTemperature,DeactivateBlock,DeactivateLid,OpenLid,CloseLid,RunProfile,RunExtendedProfile,CloseLid,OpenLid,Initialize,ReadAbsorbance,Retrieve,Store,SetStoredLabware,Fill,Empty,CloseLatch,OpenLatch,PrepareShuttle,CalibrateGripper,CalibratePipette,CalibrateModule,MoveToMaintenancePosition,UnsafeBlowOutInPlace,UnsafeDropTipInPlace,UpdatePositionEstimators,UnsafeEngageAxes,UnsafeUngripLabware,UnsafePlaceLabware,UnsafeManualRetrieve,MoveTo,MoveAxesRelative,MoveAxesTo,openGripperJaw,closeGripperJaw]\nflexStacker/setStoredLabware.result.adapterLabwareDefinition\n  Field required [type=missing, input_value={'primaryLabwareDefinitio...k_1000ul']}, 'count': 1}, input_type=dict]\n    For further information visit https://errors.pydantic.dev/2.9/v/missing",
            "meta": {
                "type": "ValidationError",
                "code": "4000",
                "message": "pydantic_core._pydantic_core.ValidationError: 1 validation error for tagged-union[AirGapInPlace,Aspirate,AspirateInPlace,AspirateWhileTracking,Comment,Custom,Dispense,DispenseInPlace,DispenseWhileTracking,BlowOut,BlowOutInPlace,ConfigureForVolume,ConfigureNozzleLayout,DropTip,DropTipInPlace,Home,RetractAxis,LoadLabware,ReloadLabware,LoadLiquid,LoadLiquidClass,LoadModule,LoadPipette,LoadLidStack,LoadLid,MoveLabware,MoveRelative,MoveToCoordinates,MoveToWell,MoveToAddressableArea,MoveToAddressableAreaForDropTip,PrepareToAspirate,WaitForResume,WaitForResume,WaitForDuration,PickUpTip,SavePosition,SetRailLights,TouchTip,SetStatusBar,VerifyTipPresence,GetTipPresence,GetNextTip,LiquidProbe,TryLiquidProbe,EvotipSealPipette,EvotipDispense,EvotipUnsealPipette,WaitForTemperature,SetTargetTemperature,DeactivateHeater,SetAndWaitForShakeSpeed,DeactivateShaker,OpenLabwareLatch,CloseLabwareLatch,Disengage,Engage,SetTargetTemperature,WaitForTemperature,DeactivateTemperature,SetTargetBlockTemperature,WaitForBlockTemperature,SetTargetLidTemperature,WaitForLidTemperature,DeactivateBlock,DeactivateLid,OpenLid,CloseLid,RunProfile,RunExtendedProfile,CloseLid,OpenLid,Initialize,ReadAbsorbance,Retrieve,Store,SetStoredLabware,Fill,Empty,CloseLatch,OpenLatch,PrepareShuttle,CalibrateGripper,CalibratePipette,CalibrateModule,MoveToMaintenancePosition,UnsafeBlowOutInPlace,UnsafeDropTipInPlace,UpdatePositionEstimators,UnsafeEngageAxes,UnsafeUngripLabware,UnsafePlaceLabware,UnsafeManualRetrieve,MoveTo,MoveAxesRelative,MoveAxesTo,openGripperJaw,closeGripperJaw]\nflexStacker/setStoredLabware.result.adapterLabwareDefinition\n  Field required [type=missing, input_value={'primaryLabwareDefinitio...k_1000ul']}, 'count': 1}, input_type=dict]\n    For further information visit https://errors.pydantic.dev/2.9/v/missing",
                "detail": {
                    "args": "()",
                    "title": "tagged-union[AirGapInPlace,Aspirate,AspirateInPlace,AspirateWhileTracking,Comment,Custom,Dispense,DispenseInPlace,DispenseWhileTracking,BlowOut,BlowOutInPlace,ConfigureForVolume,ConfigureNozzleLayout,DropTip,DropTipInPlace,Home,RetractAxis,LoadLabware,ReloadLabware,LoadLiquid,LoadLiquidClass,LoadModule,LoadPipette,LoadLidStack,LoadLid,MoveLabware,MoveRelative,MoveToCoordinates,MoveToWell,MoveToAddressableArea,MoveToAddressableAreaForDropTip,PrepareToAspirate,WaitForResume,WaitForResume,WaitForDuration,PickUpTip,SavePosition,SetRailLights,TouchTip,SetStatusBar,VerifyTipPresence,GetTipPresence,GetNextTip,LiquidProbe,TryLiquidProbe,EvotipSealPipette,EvotipDispense,EvotipUnsealPipette,WaitForTemperature,SetTargetTemperature,DeactivateHeater,SetAndWaitForShakeSpeed,DeactivateShaker,OpenLabwareLatch,CloseLabwareLatch,Disengage,Engage,SetTargetTemperature,WaitForTemperature,DeactivateTemperature,SetTargetBlockTemperature,WaitForBlockTemperature,SetTargetLidTemperature,WaitForLidTemperature,DeactivateBlock,DeactivateLid,OpenLid,CloseLid,RunProfile,RunExtendedProfile,CloseLid,OpenLid,Initialize,ReadAbsorbance,Retrieve,Store,SetStoredLabware,Fill,Empty,CloseLatch,OpenLatch,PrepareShuttle,CalibrateGripper,CalibratePipette,CalibrateModule,MoveToMaintenancePosition,UnsafeBlowOutInPlace,UnsafeDropTipInPlace,UpdatePositionEstimators,UnsafeEngageAxes,UnsafeUngripLabware,UnsafePlaceLabware,UnsafeManualRetrieve,MoveTo,MoveAxesRelative,MoveAxesTo,openGripperJaw,closeGripperJaw]",
                    "traceback": "  File \"/opt/opentrons-robot-server/starlette/middleware/errors.py\", line 162, in __call__\n    await self.app(scope, receive, _send)\n\n  File \"/opt/opentrons-robot-server/starlette/middleware/cors.py\", line 83, in __call__\n    await self.app(scope, receive, send)\n\n  File \"/opt/opentrons-robot-server/starlette/middleware/exceptions.py\", line 79, in __call__\n    raise exc\n\n  File \"/opt/opentrons-robot-server/starlette/middleware/exceptions.py\", line 68, in __call__\n    await self.app(scope, receive, sender)\n\n  File \"/opt/opentrons-robot-server/fastapi/middleware/asyncexitstack.py\", line 20, in __call__\n    raise e\n\n  File \"/opt/opentrons-robot-server/fastapi/middleware/asyncexitstack.py\", line 17, in __call__\n    await self.app(scope, receive, send)\n\n  File \"/opt/opentrons-robot-server/starlette/routing.py\", line 718, in __call__\n    await route.handle(scope, receive, send)\n\n  File \"/opt/opentrons-robot-server/starlette/routing.py\", line 276, in handle\n    await self.app(scope, receive, send)\n\n  File \"/opt/opentrons-robot-server/starlette/routing.py\", line 66, in app\n    response = await func(request)\n\n  File \"/opt/opentrons-robot-server/fastapi/routing.py\", line 273, in app\n    raw_response = await run_endpoint_function(\n\n  File \"/opt/opentrons-robot-server/fastapi/routing.py\", line 190, in run_endpoint_function\n    return await dependant.call(**values)\n\n  File \"/opt/opentrons-robot-server/robot_server/runs/router/commands_router.py\", line 306, in get_run_commands\n    command_slice = run_data_manager.get_commands_slice(\n\n  File \"/opt/opentrons-robot-server/robot_server/runs/run_data_manager.py\", line 431, in get_commands_slice\n    return self._run_store.get_commands_slice(\n\n  File \"/opt/opentrons-robot-server/robot_server/runs/run_store.py\", line 519, in get_commands_slice\n    sliced_commands: List[Command] = [\n\n  File \"/opt/opentrons-robot-server/robot_server/runs/run_store.py\", line 520, in <listcomp>\n    _parse_command(row.command) for row in slice_result\n\n  File \"/opt/opentrons-robot-server/robot_server/runs/run_store.py\", line 835, in _parse_command\n    return json_to_pydantic(CommandAdapter, json_str)\n\n  File \"/opt/opentrons-robot-server/robot_server/persistence/pydantic.py\", line 46, in json_to_pydantic\n    return model.validate_json(json_str)\n\n  File \"/opt/opentrons-robot-server/pydantic/type_adapter.py\", line 144, in wrapped\n    return func(self, *args, **kwargs)\n\n  File \"/opt/opentrons-robot-server/pydantic/type_adapter.py\", line 393, in validate_json\n    return self.validator.validate_json(data, strict=strict, context=context)\n",
                    "class": "ValidationError"
                },
                "wrapping": []
            },
            "errorCode": "4000"
        }
    ]
}

@ahiuchingau ahiuchingau requested review from a team as code owners April 4, 2025 17:24
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 4, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 27.33%. Comparing base (ca3d6af) to head (904a7d0).
Report is 2 commits behind head on chore_release-8.4.0.

Additional details and impacted files

Impacted file tree graph

@@                   Coverage Diff                   @@
##           chore_release-8.4.0   #17989      +/-   ##
=======================================================
- Coverage                27.81%   27.33%   -0.48%     
=======================================================
  Files                     3101     3101              
  Lines                   235468   235468              
  Branches                 19127    19131       +4     
=======================================================
- Hits                     65484    64369    -1115     
- Misses                  169966   171083    +1117     
+ Partials                    18       16       -2     
Flag Coverage Δ
protocol-designer 18.80% <ø> (ø)
step-generation 4.35% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

see 29 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ahiuchingau ahiuchingau force-pushed the fix_flex-stacker-commands-optional-fields branch 3 times, most recently from f71a201 to ac560fd Compare April 7, 2025 19:54
@ahiuchingau ahiuchingau requested a review from a team as a code owner April 7, 2025 19:54
@ahiuchingau ahiuchingau requested review from smb2268 and removed request for a team April 7, 2025 19:54
@ahiuchingau ahiuchingau changed the base branch from edge to chore_release-8.4.0 April 7, 2025 19:54
@ahiuchingau ahiuchingau force-pushed the fix_flex-stacker-commands-optional-fields branch from ac560fd to b4229af Compare April 7, 2025 19:56
Copy link
Copy Markdown
Member

@sfoster1 sfoster1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@ahiuchingau ahiuchingau merged commit e762a98 into chore_release-8.4.0 Apr 8, 2025
72 checks passed
@ahiuchingau ahiuchingau deleted the fix_flex-stacker-commands-optional-fields branch April 8, 2025 00:38
y3rsh added a commit that referenced this pull request Apr 9, 2025
…y-path

* chore_release-8.4.0: (30 commits)
  fix(api): make error message clearer for lld issues (#18005)
  chore(locize): sync for translations needed (#18009)
  chore(locize): sync translations (#18009)
  docs(api): API reference entries for liquid class methods (#17887)
  refactor(api): change the names of liquid classes based transfers (#18006)
  feat(app, labware-library): add evotip definition assets (#18007)
  fix(api, shared-data): Flex Stacker engine command optional fields (#17989)
  fix(shared-data): ethanol aspirate position reference (#17991)
  fix(app): Labware setup UI fixes (#17987)
  refactor(app): adjust protocol setup offsets table header (#17985)
  fix(app): do not show post run drop tip prompt if just handled in Error Recovery (#17981)
  fix(app): fix LPC disabled reasons not including fixture mismatch (#17979)
  refactor(app): adjust width on "calibrate now" button (#17978)
  fix(app): fix applying offsets implicitly when navigating on the desktop app (#17967)
  feat(robot-server): Populate `locationSequence` on old runs and make it faster to filter out deleted offsets (#17946)
  feat(app): add inline notification when setting default offsets with a 96ch (#17977)
  fix(app): ER tip selection crashes when trying to get labware def (#17975)
  feat(robot-server,system-server): Return server timing metrics in HTTP responses (#17970)
  fix(app): fix accumulating offsets on run record (#17969)
  fix(app): Fix local state issues when "resetting to default" in LPC (#17965)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants