Merge "Pecan: Make it possible to use the Response to return a non-default return type"

This commit is contained in:
Jenkins 2015-04-20 10:47:30 +00:00 committed by Gerrit Code Review
commit f9ecdd10d3
4 changed files with 45 additions and 3 deletions

View File

@ -111,6 +111,12 @@ class AuthorsController(RestController):
if id == 911:
return wsme.api.Response(Author(),
status_code=401)
if id == 912:
return wsme.api.Response(None, status_code=204)
if id == 913:
return wsme.api.Response('foo', status_code=200, return_type=text)
author = Author()
author.id = id
author.firstname = u"aname"

View File

@ -175,6 +175,22 @@ class TestWS(FunctionalTest):
self.assertEqual(res.status_int, expected_status_code)
self.assertEqual(res.status, expected_status)
def test_non_default_response_return_type(self):
res = self.app.get(
'/authors/913',
)
self.assertEqual(res.status_int, 200)
self.assertEqual(res.body, '"foo"')
self.assertEqual(res.content_length, 5)
def test_non_default_response_return_type_no_content(self):
res = self.app.get(
'/authors/912',
)
self.assertEqual(res.status_int, 204)
self.assertEqual(res.body, '')
self.assertEqual(res.content_length, 0)
def test_serversideerror(self):
expected_status_code = 500
expected_status = http_response_messages[expected_status_code]

View File

@ -187,7 +187,8 @@ class Response(object):
"""
Object to hold the "response" from a view function
"""
def __init__(self, obj, status_code=None, error=None):
def __init__(self, obj, status_code=None, error=None,
return_type=wsme.types.Unset):
#: Store the result object from the view
self.obj = obj
@ -199,6 +200,12 @@ class Response(object):
#: faultstring and an optional debuginfo
self.error = error
#: Return type
#: Type of the value returned by the function
#: If the return type is wsme.types.Unset it will be ignored
#: and the default return type will prevail.
self.return_type = return_type
def format_exception(excinfo, debug=False):
"""Extract informations that can be sent to the client."""

View File

@ -72,6 +72,8 @@ def wsexpose(*args, **kwargs):
@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,
@ -85,6 +87,17 @@ def wsexpose(*args, **kwargs):
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:
@ -106,13 +119,13 @@ def wsexpose(*args, **kwargs):
return data
if funcdef.return_type is None:
if return_type is None:
pecan.request.pecan['content_type'] = None
pecan.response.content_type = None
return ''
return dict(
datatype=funcdef.return_type,
datatype=return_type,
result=result
)