Source code for supercell.api.decorators

# vim: set fileencoding=utf-8 :
#
# Copyright (c) 2013 Daniel Truemper <truemped at googlemail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
'''Several decorators for using with :class:`supercell.api.RequestHandler`
implementations.
'''
from __future__ import absolute_import, division, print_function, with_statement

from collections import defaultdict

from tornado import gen
from tornado.web import asynchronous

from supercell.api import ContentType


[docs]def async(fn): '''Decorator that merges the :func:`tornado.web.asynchronous` as well as the :func:`tornado.gen.coroutine` decorators. Example:: class MyHandler(s.RequestHandler): @s.async def get(self, user_id): # ... raise s.Return(User()) ''' return asynchronous(gen.coroutine(fn))
[docs]def provides(content_type, vendor=None, version=None, default=False): '''Class decorator for mapping HTTP GET responses to content types and their representation. In order to allow the **application/json** content type, create the handler class like this:: @s.provides(sMediaType.ApplicationJson) class MyHandler(s.RequestHandler): pass It is also possible to support more than one content type. The content type selection is then based on the client **Accept** header. If this is not present, ordering of the :func:`provides` decorators matter, i.e. the first content type is used:: @s.provides(s.MediaType.ApplicationJson) class MyHandler(s.RequestHandler): ... :param str content_type: The base content type such as **application/json** :param str vendor: Any vendor information for the base content type :param float version: The vendor version :param bool default: If **True** and no **Accept** header is present, this content type is provided ''' def wrapper(cls): '''The real class decorator.''' assert isinstance(cls, type), 'This decorator may only be used as ' + \ 'class decorator' if not hasattr(cls, '_PROD_CONTENT_TYPES'): cls._PROD_CONTENT_TYPES = defaultdict(list) ctype = ContentType(content_type, vendor, version) cls._PROD_CONTENT_TYPES[content_type].append(ctype) if default: assert 'default' not in cls._PROD_CONTENT_TYPES, 'TODO: nice msg' cls._PROD_CONTENT_TYPES['default'] = ctype return cls return wrapper
[docs]def consumes(content_type, model, vendor=None, version=None): '''Class decorator for mapping HTTP POST and PUT bodies to Example:: @s.consumes(s.MediaType.ApplicationJson, model=Model) class MyHandler(s.RequestHandler): def post(self, *args, **kwargs): # ... raise s.OkCreated() :param str content_type: The base content type such as **application/json** :param model: The model that should be consumed. :type model: :class:`schematics.models.Model` :param str vendor: Any vendor information for the base content type :param float version: The vendor version ''' def wrapper(cls): '''The real decorator.''' assert isinstance(cls, type), 'This decorator may only be used as ' + \ 'class decorator' assert model, 'In order to consume content a schematics model ' + \ 'class has to be given via the model parameter' if not hasattr(cls, '_CONS_CONTENT_TYPES'): cls._CONS_CONTENT_TYPES = defaultdict(list) if not hasattr(cls, '_CONS_MODEL'): cls._CONS_MODEL = dict() ct = ContentType(content_type, vendor, version) cls._CONS_CONTENT_TYPES[content_type].append(ct) cls._CONS_MODEL[ct] = model return cls return wrapper
Read the Docs v: v0.4.0
Versions
latest
v0.4.0
v0.3.0
Downloads
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.