diff --git a/wsme/api.py b/wsme/api.py index 9d9da8a..c092da5 100644 --- a/wsme/api.py +++ b/wsme/api.py @@ -118,8 +118,9 @@ class expose(object): def getint(self): return 1 """ - def __init__(self, return_type=None, **options): + def __init__(self, return_type=None, body=None, **options): self.return_type = return_type + self.body_type = body self.options = options def __call__(self, func): @@ -127,6 +128,7 @@ class expose(object): if fd.extra_options is not None: raise ValueError("This function is already exposed") fd.return_type = self.return_type + fd.body_type = self.body_type fd.extra_options = self.options return func @@ -176,8 +178,11 @@ class validate(object): args, varargs, keywords, defaults = inspect.getargspec(func) if args[0] == 'self': args = args[1:] + param_types = list(self.param_types) + if fd.body_type is not None: + param_types.append(fd.body_type) for i, argname in enumerate(args): - datatype = self.param_types[i] + datatype = param_types[i] mandatory = defaults is None or i < (len(args) - len(defaults)) default = None if not mandatory: diff --git a/wsme/pecan.py b/wsme/pecan.py index a8fcbc3..db26986 100644 --- a/wsme/pecan.py +++ b/wsme/pecan.py @@ -59,7 +59,8 @@ def wsexpose(*args, **kwargs): def callfunction(self, *args, **kwargs): args, kwargs = wsme.protocols.commons.get_args( - funcdef, args, kwargs + funcdef, args, kwargs, + pecan.request.body, pecan.request.content_type ) result = f(self, *args, **kwargs) return dict( diff --git a/wsme/protocols/commons.py b/wsme/protocols/commons.py index f925b40..fe9e691 100644 --- a/wsme/protocols/commons.py +++ b/wsme/protocols/commons.py @@ -8,7 +8,6 @@ from wsme.types import iscomplex, list_attributes, Unset from wsme.types import UserType, ArrayType, DictType, File from wsme.utils import parse_isodate, parse_isotime, parse_isodatetime - ARRAY_MAX_SIZE = 1000 @@ -114,11 +113,33 @@ def dict_from_params(datatype, params, path, hit_paths): for key in keys)) -def get_args(funcdef, args, kwargs): +def get_args(funcdef, args, kwargs, body, mimetype): newargs = [] for argdef, arg in zip(funcdef.arguments[:len(args)], args): newargs.append(from_param(argdef.datatype, arg)) newkwargs = {} for argname, value in kwargs.items(): newkwargs[argname] = from_param(funcdef.get_arg(argname), value) + if funcdef.body_type is not None: + bodydata = None + if mimetype in restjson.RestJsonProtocol.content_types: + if hasattr(body, 'read'): + jsonbody = restjson.json.load(body) + else: + jsonbody = restjson.json.loads(body) + bodydata = restjson.fromjson(funcdef.body_type, jsonbody) + elif mimetype in restxml.RestXmlProtocol.content_types: + if hasattr(body, 'read'): + xmlbody = restxml.et.parse(body) + else: + xmlbody = restxml.et.fromstring(body) + bodydata = restxml.fromxml(funcdef.body_type, xmlbody) + if bodydata: + if len(newargs) < len(funcdef.arguments): + newkwargs[funcdef.arguments[-1].name] = bodydata + else: + newargs[-1] = bodydata return newargs, newkwargs + +from . import restjson +from . import restxml