Skip to content

Commit c6c0b5b

Browse files
committed
Fix OneOf and tidy up build_action_schema
OneOf was used incorrectly in ActionSchema.status. build_action_schema now uses a subclass that I think is rather clearer. The functionality shouldn't have changed.
1 parent f161213 commit c6c0b5b

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

src/labthings/schema.py

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class ActionSchema(Schema):
8888
_ID = fields.String(data_key="id")
8989
_status = fields.String(
9090
data_key="status",
91-
OneOf=["pending", "running", "completed", "cancelled", "error"],
91+
validate=validate.OneOf(["pending", "running", "completed", "cancelled", "error"]),
9292
)
9393
progress = fields.Integer()
9494
data = fields.Raw()
@@ -128,11 +128,29 @@ def generate_links(self, data, **_):
128128

129129
return data
130130

131+
def nest_if_needed(schema):
132+
"""Convert a schema, dict, or field into a field."""
133+
# If we have a real schema, nest it
134+
if isinstance(schema, Schema):
135+
return fields.Nested(schema)
136+
# If a dictionary schema, build a real schema then nest it
137+
if isinstance(schema, dict):
138+
return fields.Nested(Schema.from_dict(schema))
139+
# If a single field, set it as the output Field, and override its data_key
140+
if isinstance(schema, fields.Field):
141+
return schema
142+
143+
raise TypeError(
144+
f"Unsupported schema type {schema}. "
145+
"Ensure schema is a Schema object, Field object, "
146+
"or dictionary of Field objects"
147+
)
131148

132149
def build_action_schema(
133150
output_schema: Optional[FuzzySchemaType],
134151
input_schema: Optional[FuzzySchemaType],
135152
name: Optional[str] = None,
153+
base_class: type = ActionSchema,
136154
):
137155
"""Builds a complete schema for a given ActionView. That is, it reads any input and output
138156
schemas attached to the POST method, and nests them within the input/output fields of
@@ -149,31 +167,24 @@ def build_action_schema(
149167
if not name.endswith("Action"):
150168
name = f"{name}Action"
151169

152-
class_attrs: Dict[str, Union[fields.Nested, fields.Field]] = {}
153-
154-
for key, schema in {"output": output_schema, "input": input_schema}.items():
155-
# If no schema is given, move on
156-
if schema is None:
157-
pass
158-
# If a real schema, nest it
159-
elif isinstance(schema, Schema):
160-
class_attrs[key] = fields.Nested(schema)
161-
# If a dictionary schema, build a real schema then nest it
162-
elif isinstance(schema, dict):
163-
class_attrs[key] = fields.Nested(Schema.from_dict(schema))
164-
# If a single field, set it as the output Field, and override its data_key
165-
elif isinstance(schema, fields.Field):
166-
class_attrs[key] = schema
167-
else:
168-
raise TypeError(
169-
f"Unsupported schema type {schema}. "
170-
"Ensure schema is a Schema object, Field object, "
171-
"or dictionary of Field objects"
172-
)
173-
174-
# Build a Schema class for the Action
175-
return type(name, (ActionSchema,), class_attrs)
170+
class GenSchema(base_class):
171+
pass
172+
173+
GenSchema.__name__ = name
174+
GenSchema.__doc__ = f"Description of an action, with specific parameters for `{name}`"
175+
if input_schema:
176+
GenSchema.input = nest_if_needed(input_schema)
177+
if output_schema:
178+
GenSchema.output = nest_if_needed(output_schema)
179+
180+
return GenSchema
181+
176182

183+
def openapi_array(schema: FuzzySchemaType) -> Dict:
184+
return {
185+
"type":"array",
186+
"items": schema
187+
}
177188

178189
class EventSchema(Schema):
179190
event = fields.String()

0 commit comments

Comments
 (0)