Skip to content

Commit cc1f98d

Browse files
author
Joel Collins
committed
Tidied up marshal responses
1 parent 3e89850 commit cc1f98d

File tree

1 file changed

+21
-35
lines changed

1 file changed

+21
-35
lines changed

labthings/server/decorators.py

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
from marshmallow.exceptions import ValidationError
77
from collections.abc import Mapping
88

9+
from marshmallow import Schema as _Schema
10+
911
from .spec.utilities import update_spec
1012
from .schema import TaskSchema, Schema, FieldSchema
1113
from .fields import Field
1214
from .view import View
1315
from .find import current_labthing
16+
from .utilities import unpack
1417

1518
from labthings.core.tasks.pool import TaskThread
1619

@@ -20,29 +23,9 @@
2023
from marshmallow import pre_dump, pre_load
2124

2225

23-
def unpack(value):
24-
"""Return a three tuple of data, code, and headers"""
25-
if not isinstance(value, tuple):
26-
return value, 200, {}
27-
28-
try:
29-
data, code, headers = value
30-
return data, code, headers
31-
except ValueError:
32-
pass
33-
34-
try:
35-
data, code = value
36-
return data, code, {}
37-
except ValueError:
38-
pass
39-
40-
return value, 200, {}
41-
42-
4326
class marshal_with:
4427
def __init__(self, schema, code=200):
45-
"""Decorator to format the response of a View with a Marshmallow schema
28+
"""Decorator to format the return of a function with a Marshmallow schema
4629
4730
Args:
4831
schema: Marshmallow schema, field, or dict of Fields, describing
@@ -52,11 +35,11 @@ def __init__(self, schema, code=200):
5235
self.code = code
5336

5437
if isinstance(self.schema, Mapping):
55-
self.converter = Schema.from_dict(self.schema)().jsonify
38+
self.converter = Schema.from_dict(self.schema)().dump
5639
elif isinstance(self.schema, Field):
57-
self.converter = FieldSchema(self.schema).jsonify
58-
elif isinstance(self.schema, Schema):
59-
self.converter = self.schema.jsonify
40+
self.converter = FieldSchema(self.schema).dump
41+
elif isinstance(self.schema, _Schema):
42+
self.converter = self.schema.dump
6043
else:
6144
raise TypeError(
6245
f"Unsupported schema type {type(self.schema)} for marshal_with"
@@ -69,12 +52,15 @@ def __call__(self, f):
6952
@wraps(f)
7053
def wrapper(*args, **kwargs):
7154
resp = f(*args, **kwargs)
72-
if isinstance(resp, tuple):
73-
data, code, headers = unpack(resp)
55+
if isinstance(resp, ResponseBase):
56+
resp.data = self.converter(resp.data)
57+
return resp
58+
elif isinstance(resp, tuple):
59+
resp, code, headers = unpack(resp)
60+
return (self.converter(resp), code, headers)
7461
else:
75-
data, code, headers = resp, 200, {}
76-
77-
return make_response(self.converter(data), code, headers)
62+
resp, code, headers = resp, 200, {}
63+
return (self.converter(resp), code, headers)
7864

7965
return wrapper
8066

@@ -90,15 +76,15 @@ def marshal_task(f):
9076
def wrapper(*args, **kwargs):
9177
resp = f(*args, **kwargs)
9278
if isinstance(resp, tuple):
93-
data, code, headers = unpack(resp)
79+
resp, code, headers = unpack(resp)
9480
else:
95-
data, code, headers = resp, 200, {}
81+
resp, code, headers = resp, 201, {}
9682

97-
if not isinstance(data, TaskThread):
83+
if not isinstance(resp, TaskThread):
9884
raise TypeError(
99-
f"Function {f.__name__} expected to return a TaskThread object, but instead returned a {type(data).__name__}. If it does not return a task, remove the @marshall_task decorator from {f.__name__}."
85+
f"Function {f.__name__} expected to return a TaskThread object, but instead returned a {type(resp).__name__}. If it does not return a task, remove the @marshall_task decorator from {f.__name__}."
10086
)
101-
return make_response(TaskSchema().jsonify(data), code, headers)
87+
return (TaskSchema().dump(resp), code, headers)
10288

10389
return wrapper
10490

0 commit comments

Comments
 (0)