More Marshmallow argument updates

This commit is contained in:
Richard Bowman 2022-08-09 13:16:10 +01:00
parent e22f36b308
commit 9dbb083ee7
18 changed files with 102 additions and 87 deletions

View file

@ -46,7 +46,7 @@ class ExampleIdentifyView(View):
class ExampleRenameView(View):
# Expect a request parameter called "name", which is a string.
# Passed to the argument "args".
args = fields.String(required=True, example="My Example Microscope")
args = fields.String(required=True, metadata={"example": "My Example Microscope"})
def post(self, args):
# Look for our new name in the request body

View file

@ -49,7 +49,7 @@ class ExampleRenameView(View):
# Format our returned object using MicroscopeIdentifySchema
schema = MicroscopeIdentifySchema()
# Expect a request parameter called "name", which is a string. Pass to argument "args".
args = {"name": fields.String(required=True, example="My Example Microscope")}
args = {"name": fields.String(required=True, metadata={"example": "My Example Microscope"})}
def post(self, args):
# Look for our "name" parameter in the request arguments

View file

@ -53,7 +53,7 @@ class ExampleIdentifyView(PropertyView):
# We can use a single schema as the input and output will be formatted identically
# Eg. We always expect a "name" string argument, and always return a "name" string attribute
class ExampleRenameView(PropertyView):
schema = {"name": fields.String(required=True, example="My Example Microscope")}
schema = {"name": fields.String(required=True, metadata={"example": "My Example Microscope"})}
def get(self):
"""

View file

@ -56,7 +56,7 @@ class ExampleIdentifyView(PropertyView):
# We can use a single schema as the input and output will be formatted identically
# Eg. We always expect a "name" string argument, and always return a "name" string attribute
class ExampleRenameView(PropertyView):
schema = {"name": fields.String(required=True, example="My Example Microscope")}
schema = {"name": fields.String(required=True, metadata={"example": "My Example Microscope"})}
def get(self):
"""

View file

@ -66,10 +66,10 @@ class TimelapseAPIView(ActionView):
args = {
"n_images": fields.Integer(
required=True, example=5, description="Number of images"
required=True, metadata={"example": 5, "description": "Number of images"}
),
"t_between": fields.Number(
load_default=1, example=1, description="Time (seconds) between images"
load_default=1, metadata={"example": 1, "description": "Time (seconds) between images"}
),
}

View file

@ -99,10 +99,10 @@ class TimelapseAPIView(ActionView):
args = {
"n_images": fields.Integer(
required=True, example=5, description="Number of images"
required=True, metadata={"example": 5, "description": "Number of images"}
),
"t_between": fields.Number(
load_default=1, example=1, description="Time (seconds) between images"
load_default=1, metadata={"example": 1, "description": "Time (seconds) between images"}
),
}

View file

@ -23,7 +23,7 @@ A **field** describes the data type of a single parameter, as well as any other
.. code-block:: python
fields.String(required=False, load_default="Default value", example="Example value")
fields.String(required=False, load_default="Default value", metadata={"example: "Example value"})
A **schema** is a collection of keys and fields describing how an object should be serialized/deserialized. Schemas can be created in several ways, either by creating a ``Schema`` class, or by passing a dictionary of key-field pairs. Both methods will be discussed in the following examples.
@ -146,7 +146,7 @@ Our ``rename`` view class may now look like:
# Format our returned object using MicroscopeIdentifySchema
schema = MicroscopeIdentifySchema()
# Expect a request parameter called "name", which is a string. Pass to argument "args".
args = {"name": fields.String(required=True, example="My Example Microscope")}
args = {"name": fields.String(required=True, metadata={"example": "My Example Microscope"})}
def post(self, args):
# Look for our "name" parameter in the request arguments

View file

@ -78,7 +78,7 @@ We will implement the ``schema`` attribute in our ``ExampleRenameView`` view fro
# We can use a single schema as the input and output will be formatted identically
# Eg. We always expect a "name" string argument, and always return a "name" string attribute
class ExampleRenameView(PropertyView):
schema = {"name": fields.String(required=True, example="My Example Microscope")}
schema = {"name": fields.String(required=True, metadata={"example": "My Example Microscope"})}
def get(self):
"""

View file

@ -349,8 +349,10 @@ class AutofocusExtension(BaseExtension):
args={
"dz": fields.List(
fields.Int(),
metadata={"description": "An ascending list of relative z positions"},
example=[int(x) for x in np.linspace(-300, 300, 7)],
metadata={
"description": "An ascending list of relative z positions",
"example": [int(x) for x in np.linspace(-300, 300, 7)],
}
)
}
)
@ -433,8 +435,10 @@ class AutofocusExtension(BaseExtension):
args={
"dz": fields.Int(
load_default=2000,
example=2000,
metadata={"description": "Total Z range to search over (in stage steps)"},
metadata={
"description": "Total Z range to search over (in stage steps)",
"example": 2000,
},
)
}
)
@ -529,13 +533,17 @@ class AutofocusExtension(BaseExtension):
args={
"dz": fields.Int(
load_default=500,
example=500,
metadata={"description": "Total Z range to move down, then up (in stage steps)"},
metadata={
"description": "Total Z range to move down, then up (in stage steps)",
"example": 500,
},
),
"delay": fields.Int(
load_default=5,
example=5,
metadata={"description": "How long to measure sharpness for after the move"},
metadata={
"description": "How long to measure sharpness for after the move",
"example": 5,
},
),
}
)
@ -557,13 +565,17 @@ class AutofocusExtension(BaseExtension):
args={
"dz": fields.Int(
load_default=2000,
example=2000,
metadata={"description": "Total Z range to search over (in stage steps)"},
metadata={
"description": "Total Z range to search over (in stage steps)",
"example": 2000,
},
),
"target_z": fields.Int(
load_default=0,
example=-100,
metadata={"description": "Target finishing position, relative to the focus."},
metadata={
"description": "Target finishing position, relative to the focus.",
"example": -100,
},
),
"initial_move_up": fields.Bool(
load_default=True,
@ -571,8 +583,10 @@ class AutofocusExtension(BaseExtension):
),
"backlash": fields.Int(
load_default=25,
minimum=0,
metadata={"description": "Distance to undershoot, before correction move."},
metadata={
"description": "Distance to undershoot, before correction move.",
"minimum": 0,
},
),
}
)

View file

@ -242,7 +242,7 @@ class GetLocationsView(PropertyView):
class PreferredLocationView(PropertyView):
schema = fields.String(required=True, example="Default")
schema = fields.String(required=True, metadata={"example": "Default"})
def get(self):
self.extension.check_location()

View file

@ -279,7 +279,7 @@ class CSMExtension(BaseExtension):
class Calibrate1DView(ActionView):
args = {"direction": fields.List(fields.Float(), required=True, example=[1, 0, 0])}
args = {"direction": fields.List(fields.Float(), required=True, metadata={"example": [1, 0, 0]})}
def post(self, args):
"""Calibrate one axis of the microscope stage against the camera."""
@ -298,10 +298,10 @@ class CalibrateXYView(ActionView):
class MoveInImageCoordinatesView(ActionView):
args = {
"x": fields.Float(
metadata={"description": "The number of pixels to move in X"}, required=True, example=100
metadata={"description": "The number of pixels to move in X", "example": 100,}, required=True,
),
"y": fields.Float(
metadata={"description": "The number of pixels to move in Y"}, required=True, example=100
metadata={"description": "The number of pixels to move in Y", "example": 100,}, required=True,
),
}
@ -316,10 +316,10 @@ class MoveInImageCoordinatesView(ActionView):
class ClosedLoopMoveInImageCoordinatesView(ActionView):
args = {
"x": fields.Float(
metadata={"description": "The number of pixels to move in X"}, required=True, example=100
metadata={"description": "The number of pixels to move in X", "example": 100,}, required=True,
),
"y": fields.Float(
metadata={"description": "The number of pixels to move in Y"}, required=True, example=100
metadata={"description": "The number of pixels to move in Y", "example": 100,}, required=True,
),
}
@ -336,15 +336,14 @@ class ClosedLoopMoveInImageCoordinatesView(ActionView):
class TestClosedLoopSpiralScanView(ActionView):
args = {
"x_step": fields.Float(
metadata={"description": "The number of pixels to move in X"}, required=True, example=100
metadata={"description": "The number of pixels to move in X", "example": 100,}, required=True,
),
"y_step": fields.Float(
metadata={"description": "The number of pixels to move in Y"}, required=True, example=100
metadata={"description": "The number of pixels to move in Y", "example": 100,}, required=True,
),
"N": fields.Int(
metadata={"description": "The number of rings in the spiral scan"},
metadata={"description": "The number of rings in the spiral scan", "example": 100,},
required=True,
example=3,
),
}

View file

@ -169,39 +169,49 @@ class DeleteLSTView(ActionView):
microscope.save_settings()
percentile_field = fields.Float(
load_default=99.9,
metadata={
"example": 99.9,
"description": (
"A float between 0 and 100 setting the centile to use "
"to measure the white point of the image. A value "
"of 99.9 allows 0.1% of the pixels to be erroneously "
"bright - this helps stability in low light."
),
},
)
class AutoExposureFromRawView(ActionView):
args = {
"target_white_level": fields.Int(
load_default=700,
example=700,
description=(
"The pixel value (10-bit format) that we aim for when adjusting shutter/gain."
),
metadata={
"example": 700,
"description": (
"The pixel value (10-bit format) that we aim for when adjusting shutter/gain."
),
},
),
"max_iterations": fields.Int(
load_default=20,
description=(
"The number of adjustments to the camera's settings to make before giving up."
),
load_default=20,metadata={
"description": (
"The number of adjustments to the camera's settings to make before giving up."
),
},
),
"tolerance": fields.Float(
load_default=0.05,
example=0.05,
description=(
"We stop adjusting when we get within this fraction of the target "
"value. It is a number between 0 and 1, usually 0.01--0.1."
),
),
"percentile": fields.Float(
load_default=99.9,
example=99.9,
description=(
"A float between 0 and 100 setting the centile to use "
"to measure the white point of the image. A value "
"of 99.9 allows 0.1% of the pixels to be erroneously "
"bright - this helps stability in low light."
),
metadata={
"example": 0.05,
"description": (
"We stop adjusting when we get within this fraction of the target "
"value. It is a number between 0 and 1, usually 0.01--0.1."
),
},
),
"percentile": percentile_field,
}
def post(self, args):
@ -211,16 +221,7 @@ class AutoExposureFromRawView(ActionView):
class AutoWhiteBalanceFromRawView(ActionView):
args = {
"percentile": fields.Float(
load_default=99.9,
example=99.9,
description=(
"A float between 0 and 100 setting the centile to use "
"to measure the white point of the image. A value "
"of 99.9 allows 0.1% of the pixels to be erroneously "
"bright - this helps stability in low light."
),
)
"percentile": percentile_field,
}
def post(self, args):
@ -231,8 +232,10 @@ class AutoWhiteBalanceFromRawView(ActionView):
class GetRawChannelPercentilesView(ActionView):
args = {
"percentile": fields.Float(
example=99.9,
metadata={"description": "A float between 0 and 100 setting the centile to calculate"},
metadata={
"description": "A float between 0 and 100 setting the centile to calculate",
"example": 99.9,
},
)
}
schema = fields.List(fields.Integer)

View file

@ -578,17 +578,17 @@ class ScanExtension(BaseExtension):
class TileScanArgs(FullCaptureArgs):
namemode = fields.String(load_default="coordinates", example="coordinates")
namemode = fields.String(load_default="coordinates", metadata={"example": "coordinates"})
grid = fields.List(
fields.Integer(validate=marshmallow.validate.Range(min=1)),
load_default=[3, 3, 3],
example=[3, 3, 3],
metadata={"example": [3, 3, 3]},
)
style = fields.String(load_default="raster")
autofocus_dz = fields.Integer(load_default=50)
fast_autofocus = fields.Boolean(load_default=False)
stride_size = fields.List(
fields.Integer, load_default=[2000, 1500, 100], example=[2000, 1500, 100]
fields.Integer, load_default=[2000, 1500, 100], metadata={"example":[2000, 1500, 100]}
)
detect_empty_fields_and_skip_autofocus = fields.Boolean(load_default=False)

View file

@ -24,7 +24,7 @@ class RaiseException(ActionView):
class SleepFor(ActionView):
schema = {"TimeAsleep": fields.Float()}
args = {"time": fields.Float(metadata={"description": "Time to sleep, in seconds"}, example=0.5)}
args = {"time": fields.Float(metadata={"description": "Time to sleep, in seconds", "example": 0.5})}
def post(self, args):
sleep_time: int = args.get("time", 0)

View file

@ -10,8 +10,8 @@ from openflexure_microscope.api.v2.views.captures import CaptureSchema
class CaptureResizeSchema(Schema):
width = fields.Integer(example=640, required=True)
height = fields.Integer(example=480, required=True)
width = fields.Integer(metadata={"example":640}, required=True)
height = fields.Integer(metadata={"example": 480}, required=True)
class BasicCaptureArgs(Schema):
@ -23,10 +23,10 @@ class BasicCaptureArgs(Schema):
class FullCaptureArgs(BasicCaptureArgs):
filename = fields.String(example="MyFileName")
filename = fields.String(metadata={"example": "MyFileName"})
temporary = fields.Boolean(load_default=False, metadata={"description": "Delete capture on shutdown"})
annotations = fields.Dict(load_default={}, example={"Client": "SwaggerUI"})
tags = fields.List(fields.String, load_default=[], example=["docs"])
annotations = fields.Dict(load_default={}, metadata={"example": {"Client": "SwaggerUI"}})
tags = fields.List(fields.String, load_default=[], metadata={"example": ["docs"]})
class CaptureAPI(ActionView):
@ -113,7 +113,7 @@ class GPUPreviewStartAPI(ActionView):
in the format ``[x, y, width, height]``.
"""
args = {"window": fields.List(fields.Integer, load_default=[], example=[0, 0, 640, 480])}
args = {"window": fields.List(fields.Integer, load_default=[], metadata={"example": [0, 0, 640, 480]})}
def post(self, args):
"""

View file

@ -7,11 +7,11 @@ from labthings.views import ActionView
class MoveStageAPI(ActionView):
args = {
"absolute": fields.Boolean(
load_default=False, example=False, metadata={"description": "Move to an absolute position"}
load_default=False, metadata={"description": "Move to an absolute position", "example": False}
),
"x": fields.Int(load_default=None, example=100, allow_none=False),
"y": fields.Int(load_default=None, example=100, allow_none=False),
"z": fields.Int(load_default=None, example=20, allow_none=False),
"x": fields.Int(load_default=None, metadata={"example": 100}, allow_none=False),
"y": fields.Int(load_default=None, metadata={"example": 100}, allow_none=False),
"z": fields.Int(load_default=None, metadata={"example": 20}, allow_none=False),
}
def post(self, args):

View file

@ -24,7 +24,7 @@ class InstrumentSchema(Schema):
class ImageSchema(Schema):
id = fields.UUID()
time = fields.String(format="date")
time = fields.String(metadata={"format": "date"})
format = fields.String()
name = fields.String()
tags = fields.List(fields.String())

View file

@ -8,9 +8,8 @@ class StageTypeProperty(PropertyView):
schema = fields.String(
load_default=None,
example="SangaStage",
validate=validate.OneOf(["SangaStage", "SangaDeltaStage"]),
metadata={"description": "The translation stage geometry"},
metadata={"description": "The translation stage geometry", "example": "SangaStage",},
allow_none=False,
)