wsme/wsmeext/pecan.py
Stephen Finucane 6f6dbfadef Remove simplejson support
This was allegedly included back when simplejson was more performant
that the 'json' library in Python's library. It's additional complexity
that we simple don't need. Remove it. This also allows us to clean up
the tox file significantly.

Note that we must also rename the 'json' module to 'json_utils', as this
was shadowing a built-in library. This is a latent issue that was
highlighted by removing of 'simplejson' imports.

Change-Id: Id9faa9859993e598e2fd08133de576b740790bf3
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
2019-05-02 10:58:12 -06:00

142 lines
4.3 KiB
Python

from __future__ import absolute_import
import functools
import inspect
import sys
import pecan
import wsme
import wsme.rest.args
import wsme.rest.json_utils
import wsme.rest.xml_utils
from wsme.utils import is_valid_code
class JSonRenderer(object):
@staticmethod
def __init__(path, extra_vars):
pass
@staticmethod
def render(template_path, namespace):
if 'faultcode' in namespace:
return wsme.rest.json_utils.encode_error(None, namespace)
return wsme.rest.json_utils.encode_result(
namespace['result'],
namespace['datatype']
)
class XMLRenderer(object):
@staticmethod
def __init__(path, extra_vars):
pass
@staticmethod
def render(template_path, namespace):
if 'faultcode' in namespace:
return wsme.rest.xml_utils.encode_error(None, namespace)
return wsme.rest.xml_utils.encode_result(
namespace['result'],
namespace['datatype']
)
pecan.templating._builtin_renderers['wsmejson'] = JSonRenderer
pecan.templating._builtin_renderers['wsmexml'] = XMLRenderer
pecan_json_decorate = pecan.expose(
template='wsmejson:',
content_type='application/json',
generic=False)
pecan_xml_decorate = pecan.expose(
template='wsmexml:',
content_type='application/xml',
generic=False
)
pecan_text_xml_decorate = pecan.expose(
template='wsmexml:',
content_type='text/xml',
generic=False
)
def wsexpose(*args, **kwargs):
sig = wsme.signature(*args, **kwargs)
def decorate(f):
sig(f)
funcdef = wsme.api.FunctionDefinition.get(f)
funcdef.resolve_types(wsme.types.registry)
@functools.wraps(f)
def callfunction(self, *args, **kwargs):
return_type = funcdef.return_type
try:
args, kwargs = wsme.rest.args.get_args(
funcdef, args, kwargs, pecan.request.params, None,
pecan.request.body, pecan.request.content_type
)
if funcdef.pass_request:
kwargs[funcdef.pass_request] = pecan.request
result = f(self, *args, **kwargs)
# NOTE: Support setting of status_code with default 201
pecan.response.status = funcdef.status_code
if isinstance(result, wsme.api.Response):
pecan.response.status = result.status_code
# NOTE(lucasagomes): If the return code is 204
# (No Response) we have to make sure that we are not
# returning anything in the body response and the
# content-length is 0
if result.status_code == 204:
return_type = None
elif not isinstance(result.return_type,
wsme.types.UnsetType):
return_type = result.return_type
result = result.obj
except Exception:
try:
exception_info = sys.exc_info()
orig_exception = exception_info[1]
orig_code = getattr(orig_exception, 'code', None)
data = wsme.api.format_exception(
exception_info,
pecan.conf.get('wsme', {}).get('debug', False)
)
finally:
del exception_info
if orig_code and is_valid_code(orig_code):
pecan.response.status = orig_code
else:
pecan.response.status = 500
return data
if return_type is None:
pecan.request.pecan['content_type'] = None
pecan.response.content_type = None
return ''
return dict(
datatype=return_type,
result=result
)
if 'xml' in funcdef.rest_content_types:
pecan_xml_decorate(callfunction)
pecan_text_xml_decorate(callfunction)
if 'json' in funcdef.rest_content_types:
pecan_json_decorate(callfunction)
pecan.util._cfg(callfunction)['argspec'] = inspect.getargspec(f)
callfunction._wsme_definition = funcdef
return callfunction
return decorate