11from webargs import flaskparser
22from functools import wraps , update_wrapper
3- from flask import make_response
3+ from flask import make_response , jsonify , abort , request
44from http import HTTPStatus
5+ from marshmallow .exceptions import ValidationError
56
67from ..core .utilities import rupdate
78
89from .spec import update_spec
9- from .schema import TaskSchema
10+ from .schema import TaskSchema , Schema
11+ from .fields import Field
12+
13+ import logging
1014
1115
1216def unpack (value ):
@@ -38,6 +42,11 @@ def __init__(self, schema, code=200):
3842 self .schema = schema
3943 self .code = code
4044
45+ if isinstance (self .schema , Schema ):
46+ self .converter = self .schema .jsonify
47+ elif isinstance (self .schema , Field ):
48+ self .converter = lambda x : jsonify (self .schema ._serialize (x , None , None ))
49+
4150 def __call__ (self , f ):
4251 # Pass params to call function attribute for external access
4352 update_spec (f , {"_schema" : {self .code : self .schema }})
@@ -47,9 +56,9 @@ def wrapper(*args, **kwargs):
4756 resp = f (* args , ** kwargs )
4857 if isinstance (resp , tuple ):
4958 data , code , headers = unpack (resp )
50- return make_response (self .schema . jsonify (data ), code , headers )
59+ return make_response (self .converter (data ), code , headers )
5160 else :
52- return make_response (self .schema . jsonify (resp ))
61+ return make_response (self .converter (resp ))
5362
5463 return wrapper
5564
@@ -91,11 +100,54 @@ def ThingProperty(viewcls):
91100thing_property = ThingProperty
92101
93102
103+ class use_body (object ):
104+ """
105+ Gets the request body as a single value and adds it as a positional argument
106+ """
107+
108+ def __init__ (self , schema , ** kwargs ):
109+ self .schema = schema
110+
111+ def __call__ (self , f ):
112+ # Pass params to call function attribute for external access
113+ update_spec (f , {"_params" : self .schema })
114+
115+ # Wrapper function
116+ @wraps (f )
117+ def wrapper (* args , ** kwargs ):
118+ # Get data from request
119+ data = request .data or None
120+
121+ # If no data is there
122+ if not data :
123+ # If data is required
124+ if self .schema .required == True :
125+ # Abort
126+ return abort (400 )
127+ # Otherwise, look for the schema fields 'missing' property
128+ if self .schema .missing :
129+ data = self .schema .missing
130+
131+ # Serialize data if it exists
132+ if data :
133+ try :
134+ data = self .schema ._deserialize (data , None , None )
135+ except ValidationError as e :
136+ logging .error (e )
137+ return abort (400 )
138+
139+ # Inject argument and return wrapped function
140+ return f (* args , data , ** kwargs )
141+
142+ return wrapper
143+
144+
94145class use_args (object ):
146+ """
147+ Equivalent to webargs.flask_parser.use_args
148+ """
149+
95150 def __init__ (self , schema , ** kwargs ):
96- """
97- Equivalent to webargs.flask_parser.use_args
98- """
99151 self .schema = schema
100152 self .wrapper = flaskparser .use_args (schema , ** kwargs )
101153
@@ -107,15 +159,6 @@ def __call__(self, f):
107159 return self .wrapper (f )
108160
109161
110- class use_kwargs (use_args ):
111- def __init__ (self , schema , ** kwargs ):
112- """
113- Equivalent to webargs.flask_parser.use_kwargs
114- """
115- kwargs ["as_kwargs" ] = True
116- use_args .__init__ (self , schema , ** kwargs )
117-
118-
119162class Doc (object ):
120163 def __init__ (self , ** kwargs ):
121164 self .kwargs = kwargs
0 commit comments