Lucas Alvares Gomes de877d2cc8 Pecan: Make it possible to use the Response to return a non-default return type
This patch is extending the Response object and the Pecan extension
to make it possible to return a non-default return type (just like it
already supports retuning a non default status code).

This is useful when the return code of a function is 204 (No Response) for
that case we automatically set the return_type to be None and guarantee
that the response body is empty and the content-lentgh is 0. Which if
not done can cause tools consuming the API to misbehave.

Change-Id: I629c3e2d5dc169154e5af044f1b8f804e4b87e23
2015-04-01 14:44:46 +01:00

151 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# encoding=utf8
from pecan.rest import RestController
from wsme.types import Base, text, wsattr
import wsme
import wsmeext.pecan
import six
class Author(Base):
id = int
firstname = text
books = wsattr(['Book'])
@staticmethod
def validate(author):
if author.firstname == 'Robert':
raise wsme.exc.ClientSideError("I don't like this author!")
return author
class Book(Base):
id = int
name = text
author = wsattr('Author')
class BookNotFound(Exception):
message = "Book with ID={id} Not Found"
code = 404
def __init__(self, id):
message = self.message.format(id=id)
super(BookNotFound, self).__init__(message)
class NonHttpException(Exception):
message = "Internal Exception for Book ID={id}"
code = 684
def __init__(self, id):
message = self.message.format(id=id)
super(NonHttpException, self).__init__(message)
class BooksController(RestController):
@wsmeext.pecan.wsexpose(Book, int, int)
def get(self, author_id, id):
book = Book(
name=u"Les Confessions dun révolutionnaire pour servir à "
u"lhistoire de la révolution de février",
author=Author(lastname=u"Proudhon")
)
return book
@wsmeext.pecan.wsexpose(Book, int, int, body=Book)
def put(self, author_id, id, book=None):
book.id = id
book.author = Author(id=author_id)
return book
class Criterion(Base):
op = text
attrname = text
value = text
class AuthorsController(RestController):
_custom_actions = {
'json_only': ['GET'],
'xml_only': ['GET']
}
books = BooksController()
@wsmeext.pecan.wsexpose([Author], [six.text_type], [Criterion])
def get_all(self, q=None, r=None):
if q:
return [
Author(id=i, firstname=value)
for i, value in enumerate(q)
]
if r:
return [
Author(id=i, firstname=c.value)
for i, c in enumerate(r)
]
return [
Author(id=1, firstname=u'FirstName')
]
@wsmeext.pecan.wsexpose(Author, int)
def get(self, id):
if id == 999:
raise wsme.exc.ClientSideError('Wrong ID')
if id == 998:
raise BookNotFound(id)
if id == 997:
raise NonHttpException(id)
if id == 996:
raise wsme.exc.ClientSideError('Disabled ID', status_code=403)
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"
author.books = [
Book(
name=u"Les Confessions dun révolutionnaire pour servir à "
u"lhistoire de la révolution de février",
)
]
return author
@wsmeext.pecan.wsexpose(Author, body=Author, status_code=201)
def post(self, author):
author.id = 10
return author
@wsmeext.pecan.wsexpose(None, int)
def delete(self, author_id):
print("Deleting", author_id)
@wsmeext.pecan.wsexpose(Book, int, body=Author)
def put(self, author_id, author=None):
return author
@wsmeext.pecan.wsexpose([Author], rest_content_types=('json',))
def json_only(self):
return [Author(id=1, firstname=u"aname", books=[])]
@wsmeext.pecan.wsexpose([Author], rest_content_types=('xml',))
def xml_only(self):
return [Author(id=1, firstname=u"aname", books=[])]