Rest protocols can now take parameters from url + a parameter from the body by adding a parameter body= to expose()

This commit is contained in:
Christophe de Vienne 2012-10-15 14:03:35 +02:00
parent 0f0116be78
commit f081d8a370
3 changed files with 32 additions and 5 deletions

View File

@ -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:

View File

@ -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(

View File

@ -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