Skip to content

Commit

Permalink
feat(api,robot-server): export notes on commands (#14616)
Browse files Browse the repository at this point in the history
Commands in runs can have notes attached to them. Each command can have
zero or more notes, and zero notes can be expressed as any of
(notes=None, notes is-not-present, notes is empty-list). This is to make
the public models a little more robust across versions.

Closes EXEC-288
  • Loading branch information
sfoster1 authored Mar 11, 2024
1 parent cd79d6d commit 08a599f
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 0 deletions.
2 changes: 2 additions & 0 deletions api/src/opentrons/protocol_engine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
CommandStatus,
CommandType,
CommandIntent,
CommandNote,
)
from .state import State, StateView, StateSummary, CommandSlice, CurrentCommand, Config
from .plugins import AbstractPlugin
Expand Down Expand Up @@ -79,6 +80,7 @@
"CommandStatus",
"CommandType",
"CommandIntent",
"CommandNote",
# state interfaces and models
"State",
"StateView",
Expand Down
2 changes: 2 additions & 0 deletions api/src/opentrons/protocol_engine/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
BaseCommandCreate,
CommandStatus,
CommandIntent,
CommandNote,
)

from .command_unions import (
Expand Down Expand Up @@ -332,6 +333,7 @@
"BaseCommandCreate",
"CommandStatus",
"CommandIntent",
"CommandNote",
# command parameter hashing
"hash_command_params",
# command schema generation
Expand Down
8 changes: 8 additions & 0 deletions api/src/opentrons/protocol_engine/commands/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
Tuple,
Union,
Literal,
List,
)

from pydantic import BaseModel, Field
Expand Down Expand Up @@ -175,6 +176,13 @@ class BaseCommand(GenericModel, Generic[CommandParamsT, CommandResultT]):
" a command that is part of a calibration procedure."
),
)
notes: Optional[List[CommandNote]] = Field(
None,
description=(
"Information not critical to the execution of the command derived from either"
" the command's execution or the command's generation."
),
)


class AbstractCommandImpl(
Expand Down
1 change: 1 addition & 0 deletions robot-server/robot_server/runs/router/commands_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ async def get_run_commands(
completedAt=c.completedAt,
params=c.params,
error=c.error,
notes=c.notes,
)
for c in command_slice.commands
]
Expand Down
5 changes: 5 additions & 0 deletions robot-server/robot_server/runs/run_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
LabwareOffset,
LabwareOffsetCreate,
Liquid,
CommandNote,
)
from opentrons_shared_data.errors import GeneralError
from robot_server.service.json_api import ResourceModel
Expand Down Expand Up @@ -56,6 +57,10 @@ class RunCommandSummary(ResourceModel):
None,
description="Why this command was added to the run.",
)
notes: Optional[List[CommandNote]] = Field(
None,
description="Notes pertaining to this command.",
)


class Run(ResourceModel):
Expand Down
20 changes: 20 additions & 0 deletions robot-server/tests/runs/router/test_commands_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,24 @@ async def test_get_run_commands(
decoy: Decoy, mock_run_data_manager: RunDataManager
) -> None:
"""It should return a list of all commands in a run."""
long_note = pe_commands.CommandNote(
noteKind="warning",
shortMessage="this is a warning.",
longMessage="""
hello, friends. I bring a warning....
FROM THE FUTURE!
""",
source="test",
)
unenumed_note = pe_commands.CommandNote(
noteKind="lahsdlasd",
shortMessage="Oh no",
longMessage="its a notekind not in the enum",
source="test2",
)
command = pe_commands.WaitForResume(
id="command-id",
key="command-key",
Expand All @@ -264,6 +282,7 @@ async def test_get_run_commands(
createdAt=datetime(year=2024, month=4, day=4),
detail="Things are not looking good.",
),
notes=[long_note, unenumed_note],
)

decoy.when(mock_run_data_manager.get_current_command("run-id")).then_return(
Expand Down Expand Up @@ -306,6 +325,7 @@ async def test_get_run_commands(
createdAt=datetime(year=2024, month=4, day=4),
detail="Things are not looking good.",
),
notes=[long_note, unenumed_note],
)
]
assert result.content.meta == MultiBodyMeta(cursor=1, totalLength=3)
Expand Down
1 change: 1 addition & 0 deletions shared-data/command/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export interface CommonCommandRunTimeInfo {
startedAt: string | null
completedAt: string | null
intent?: 'protocol' | 'setup'
notes?: CommandNote[] | null
}
export interface CommonCommandCreateInfo {
key?: string
Expand Down

0 comments on commit 08a599f

Please sign in to comment.