Skip to content

Commit f50e261

Browse files
docs(robot-server): Audit HTTP API documentation (#14294)
1 parent 3821b0e commit f50e261

File tree

24 files changed

+304
-94
lines changed

24 files changed

+304
-94
lines changed

robot-server/robot_server/app_setup.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
),
5555
version=__version__,
5656
exception_handlers=exception_handlers,
57+
# Disable documentation hosting via Swagger UI, normally at /docs.
58+
# We instead focus on the docs hosted by ReDoc, at /redoc.
59+
docs_url=None,
5760
)
5861

5962
# cors

robot-server/robot_server/deck_configuration/models.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,21 @@ class DeckConfigurationRequest(pydantic.BaseModel):
3939
"""A request to set the robot's deck configuration."""
4040

4141
cutoutFixtures: List[CutoutFixture] = pydantic.Field(
42-
description="A full list of all the cutout fixtures that are mounted onto the deck."
42+
description=(
43+
"A full list of all the cutout fixtures that are mounted onto the deck."
44+
" The order is arbitrary."
45+
)
4346
)
4447

4548

4649
class DeckConfigurationResponse(pydantic.BaseModel):
4750
"""A response for the robot's current deck configuration."""
4851

4952
cutoutFixtures: List[CutoutFixture] = pydantic.Field(
50-
description="A full list of all the cutout fixtures that are mounted onto the deck."
53+
description=(
54+
"A full list of all the cutout fixtures that are mounted onto the deck."
55+
" The order is arbitrary."
56+
)
5157
)
5258
lastModifiedAt: Optional[datetime] = pydantic.Field(
5359
description=(

robot-server/robot_server/deck_configuration/router.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
@PydanticResponse.wrap_route(
2828
router.put,
2929
path="/deck_configuration",
30-
summary="Set the deck configuration",
30+
summary="Set the Flex deck configuration",
3131
description=(
3232
"Inform the robot how its deck is physically set up."
3333
"\n\n"
@@ -38,15 +38,18 @@
3838
" configuration, such as loading a labware into a staging area slot that this deck"
3939
" configuration doesn't provide, the run command will fail with an error."
4040
"\n\n"
41+
"After you set the deck configuration, it will persist, even across reboots,"
42+
" until you set it to something else."
43+
"\n\n"
4144
"**Warning:**"
4245
" Currently, you can call this endpoint at any time, even while there is an active run."
4346
" However, the robot can't adapt to deck configuration changes in the middle of a run."
4447
" The robot will effectively take a snapshot of the deck configuration when the run is"
4548
" first played. In the future, this endpoint may error if you try to call it in the middle"
4649
" of an active run, so don't rely on being able to do that."
4750
"\n\n"
48-
"After you set the deck configuration, it will persist, even across reboots,"
49-
" until you set it to something else."
51+
"**Warning:** Only use this on Flex robots, never OT-2 robots. The behavior on"
52+
" OT-2 robots is currently undefined and it may interfere with protocol execution."
5053
),
5154
responses={
5255
fastapi.status.HTTP_200_OK: {
@@ -86,10 +89,13 @@ async def put_deck_configuration( # noqa: D103
8689
@PydanticResponse.wrap_route(
8790
router.get,
8891
path="/deck_configuration",
89-
summary="Get the deck configuration",
92+
summary="Get the Flex deck configuration",
9093
description=(
9194
"Get the robot's current deck configuration."
9295
" See `PUT /deck_configuration` for background information."
96+
"\n\n"
97+
"**Warning:** The behavior of this endpoint is currently only defined for Flex"
98+
" robots, not OT-2 robots."
9399
),
94100
responses={
95101
fastapi.status.HTTP_200_OK: {

robot-server/robot_server/instruments/router.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,14 @@ async def _get_attached_instruments_ot2(
254254
@PydanticResponse.wrap_route(
255255
instruments_router.get,
256256
path="/instruments",
257-
summary="Get attached instruments.",
258-
description="Get a list of all instruments (pipettes & gripper) currently attached"
259-
" to the robot.",
257+
summary="Get attached instruments",
258+
description=(
259+
"Get a list of all instruments (pipettes & gripper) currently attached"
260+
" to the robot."
261+
"\n\n"
262+
"**Warning:** The behavior of this endpoint is currently only defined for Flex"
263+
" robots. For OT-2 robots, use `/pipettes` instead."
264+
),
260265
responses={status.HTTP_200_OK: {"model": SimpleMultiBody[AttachedItem]}},
261266
)
262267
async def get_attached_instruments(

robot-server/robot_server/protocols/protocol_models.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,10 @@ class Protocol(ResourceModel):
102102
),
103103
)
104104

105-
key: Optional[str] = None
105+
key: Optional[str] = Field(
106+
None,
107+
description=(
108+
"An arbitrary client-defined string, set when this protocol was uploaded."
109+
" See `POST /protocols`."
110+
),
111+
)

robot-server/robot_server/protocols/router.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
FileHasher,
2020
)
2121
from opentrons_shared_data.robot.dev_types import RobotType
22+
2223
from robot_server.errors.error_responses import ErrorDetails, ErrorBody
2324
from robot_server.hardware import get_robot_type
2425
from robot_server.service.task_runner import TaskRunner, get_task_runner
@@ -154,7 +155,16 @@ async def create_protocol(
154155
files: List[UploadFile] = File(...),
155156
# use Form because request is multipart/form-data
156157
# https://fastapi.tiangolo.com/tutorial/request-forms-and-files/
157-
key: Optional[str] = Form(None),
158+
key: Optional[str] = Form(
159+
default=None,
160+
description=(
161+
"An arbitrary client-defined string to attach to the new protocol resource."
162+
" This should be no longer than ~100 characters or so."
163+
" It's intended to store something like a UUID, to help clients that store"
164+
" protocols locally keep track of which local files correspond to which"
165+
" protocol resources on the robot."
166+
),
167+
),
158168
protocol_directory: Path = Depends(get_protocol_directory),
159169
protocol_store: ProtocolStore = Depends(get_protocol_store),
160170
analysis_store: AnalysisStore = Depends(get_analysis_store),

robot-server/robot_server/router.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272

7373
router.include_router(
7474
router=deck_configuration_router,
75-
tags=["Deck Configuration"],
75+
tags=["Flex Deck Configuration"],
7676
dependencies=[Depends(check_version_header)],
7777
)
7878

@@ -90,7 +90,7 @@
9090

9191
router.include_router(
9292
router=deprecated_session_router,
93-
tags=["Session Management"],
93+
tags=["OT-2 Calibration Sessions"],
9494
dependencies=[Depends(check_version_header)],
9595
)
9696

@@ -120,7 +120,7 @@
120120

121121
router.include_router(
122122
router=subsystems_router,
123-
tags=["Subsystem Management"],
123+
tags=["Flex Subsystem Management"],
124124
dependencies=[Depends(check_version_header)],
125125
)
126126

robot-server/robot_server/service/json_api/response.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class SimpleMultiBody(BaseResponseBody, GenericModel, Generic[ResponseDataT]):
110110
# to be covariant is to make data the covariant Sequence protocol.
111111
meta: MultiBodyMeta = Field(
112112
...,
113-
description="Metadata about the colletion response.",
113+
description="Metadata about the collection response.",
114114
)
115115

116116

@@ -125,7 +125,7 @@ class MultiBody(
125125
links: ResponseLinksT = Field(..., description=DESCRIPTION_LINKS)
126126
meta: MultiBodyMeta = Field(
127127
...,
128-
description="Metadata about the colletion response.",
128+
description="Metadata about the collection response.",
129129
)
130130

131131

robot-server/robot_server/service/labware/router.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class LabwareCalibrationEndpointsRemoved(ErrorDetails):
3636
"This endpoint has been removed."
3737
" Use the `/runs` endpoints to manage labware offsets."
3838
),
39+
deprecated=True,
3940
response_model=None,
4041
responses={
4142
status.HTTP_200_OK: {"model": lw_models.MultipleCalibrationsResponse},
@@ -62,6 +63,7 @@ async def get_all_labware_calibrations(
6263
"This endpoint has been removed."
6364
" Use the `/runs` endpoints to manage labware offsets."
6465
),
66+
deprecated=True,
6567
response_model=None,
6668
responses={
6769
status.HTTP_404_NOT_FOUND: {"model": ErrorBody},
@@ -89,6 +91,7 @@ async def get_specific_labware_calibration(
8991
"This endpoint has been removed."
9092
" Use the `/runs` endpoints to manage labware offsets."
9193
),
94+
deprecated=True,
9295
response_model=None,
9396
responses={
9497
status.HTTP_404_NOT_FOUND: {"model": ErrorBody},

robot-server/robot_server/service/legacy/models/deck_calibration.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,22 @@
2929

3030

3131
class InstrumentOffset(BaseModel):
32-
single: Offset
33-
multi: Offset
32+
single: Offset = Field(
33+
...,
34+
deprecated=True,
35+
description=(
36+
"This will always be `[0, 0, 0]`."
37+
" Use the `GET /calibration/pipette_offset` endpoint instead."
38+
),
39+
)
40+
multi: Offset = Field(
41+
...,
42+
deprecated=True,
43+
description=(
44+
"This will always be `[0, 0, 0]`."
45+
" Use the `GET /calibration/pipette_offset` endpoint instead."
46+
),
47+
)
3448

3549

3650
class InstrumentCalibrationStatus(BaseModel):
@@ -59,7 +73,12 @@ class DeckCalibrationData(BaseModel):
5973
None, description="The ID of the pipette used in this calibration"
6074
)
6175
tiprack: typing.Optional[str] = Field(
62-
None, description="The sha256 hash of the tiprack used in this calibration"
76+
None,
77+
description="A hash of the labware definition of the tip rack that"
78+
" was used in this calibration."
79+
" This is deprecated because it was prone to bugs where semantically identical"
80+
" definitions had different hashes.",
81+
deprecated=True,
6382
)
6483
source: typing.Optional[SourceType] = Field(
6584
None, description="The calibration source"

0 commit comments

Comments
 (0)