Esempio n. 1
0
class TornadoTemplateProvider(ProviderBase):
    """Default provider for `text/html`."""

    CONTENT_TYPE = ContentType(MediaType.TextHtml)

    def provide(self, model, handler, **kwargs):
        """Render a template with the given model into HTML.

        By default we will use the tornado built in template language."""
        try:
            model.validate()
            handler.render(handler.get_template(model), **model.to_primitive())
        except ModelValidationError as e:
            e.messages = {"result_model": e.messages}
            raise HTTPError(500, reason=json.dumps(e.messages))

    def error(self, status_code, message, handler):
        """Simply return errors in  html

        .. seealso:: :py:mod:`supercell.api.provider.ProviderBase.error`
        """
        handler.finish("<html><title>%(code)d: %(message)s</title>"
                       "<body>%(code)d: %(message)s</body></html>" % {
                           "code": status_code,
                           "message": message,
                       })
Esempio n. 2
0
    def map_consumer(content_type, handler):
        """Map a given content type to the correct provider implementation.

        If no provider matches, raise a `NoProviderFound` exception.

        :param accept_header: HTTP Accept header value
        :type accept_header: str
        :param handler: supercell request handler

        :raises: :exc:`NoConsumerFound`
        """
        accept = parse_accept_header(content_type)
        if len(accept) == 0:
            raise NoConsumerFound()

        (ctype, params, q) = accept[0]

        if ctype not in handler._CONS_CONTENT_TYPES:
            raise NoConsumerFound()

        c = ContentType(ctype,
                        vendor=params.get('vendor', None),
                        version=params.get('version', None))
        if c not in handler._CONS_CONTENT_TYPES[ctype]:
            raise NoConsumerFound()

        known_types = [
            t for t in ConsumerMeta.KNOWN_CONTENT_TYPES[ctype] if t[0] == c
        ]

        if len(known_types) == 1:
            return (handler._CONS_MODEL[c], known_types[0][1])

        raise NoConsumerFound()
Esempio n. 3
0
class JsonProvider(ProviderBase):
    """Default `application/json` provider."""

    CONTENT_TYPE = ContentType(MediaType.ApplicationJson)

    def provide(self, model, handler):
        """Simply return the json via `json.dumps`.

        .. seealso:: :py:mod:`supercell.api.provider.ProviderBase.provide`
        """
        try:
            model.validate()
            handler.write(model.to_primitive())
        except ModelValidationError as e:
            e.messages = {"result_model": e.messages}
            raise HTTPError(500, reason=json.dumps(e.messages))

    def error(self, status_code, message, handler):
        """Simply return errors in  json.

        .. seealso:: :py:mod:`supercell.api.provider.ProviderBase.error`
        """
        try:
            message = json.loads(message)
        except ValueError:
            pass

        res = {"message": message, "error": True}
        handler.set_header('Content-Type', MediaType.ApplicationJson)
        handler.finish(escape.json_encode(res))
Esempio n. 4
0
class TornadoTemplateProvider(ProviderBase):
    """Default provider for `text/html`."""

    CONTENT_TYPE = ContentType(MediaType.TextHtml)

    def provide(self, model, handler):
        """Render a template with the given model into HTML.

        By default we will use the tornado built in template language."""
        model.validate()
        handler.render(handler.get_template(model), **model.to_primitive())
Esempio n. 5
0
class JsonProvider(ProviderBase):
    """Default `application/json` provider."""

    CONTENT_TYPE = ContentType(MediaType.ApplicationJson)

    def provide(self, model, handler):
        """Simply return the json via `json.dumps`.

        .. seealso:: :py:mod:`supercell.api.provider.ProviderBase.provide`
        """
        model.validate()
        handler.write(model.to_primitive())
Esempio n. 6
0
    def map_provider(accept_header, handler, allow_default=False):
        """Map a given content type to the correct provider implementation.

        If no provider matches, raise a `NoProviderFound` exception.

        :param accept_header: HTTP Accept header value
        :type accept_header: str
        :param handler: supercell request handler
        :param allow_default: allow usage of default provider if no accept
                              header is set, default is False
        :type allow_default: bool
        :raises: :exc:`NoProviderFound`

        :return: A tuple of the matching provider implementation class and
                 the provide()-kwargs
        :rtype: (supercell.api.provider.ProviderBase, dict)
        """
        if not hasattr(handler, '_PROD_CONTENT_TYPES'):
            raise NoProviderFound()

        accept = parse_accept_header(accept_header)

        if len(accept) > 0:
            for (ctype, params, q) in accept:
                if ctype not in handler._PROD_CONTENT_TYPES:
                    continue

                c = ContentType(ctype, vendor=params.get('vendor', None),
                                version=params.get('version', None))
                if c not in handler._PROD_CONTENT_TYPES[ctype]:
                    continue

                known_types = [t for t in
                               ProviderMeta.KNOWN_CONTENT_TYPES[ctype]
                               if t[0] == c]

                configuration = handler._PROD_CONFIGURATION[ctype]
                if len(known_types) == 1:
                    return (known_types[0][1], configuration)

        if allow_default and 'default' in handler._PROD_CONTENT_TYPES:
            content_type = handler._PROD_CONTENT_TYPES['default']
            configuration = handler._PROD_CONFIGURATION['default']
            ctype = content_type.content_type
            default_type = [t for t in
                            ProviderMeta.KNOWN_CONTENT_TYPES[ctype]
                            if t[0] == content_type]

            if len(default_type) == 1:
                return (default_type[0][1], configuration)

        raise NoProviderFound()
Esempio n. 7
0
class JsonConsumer(ConsumerBase):
    """Default **application/json** provider."""

    CONTENT_TYPE = ContentType(MediaType.ApplicationJson)
    """The **application/json** :class:`ContentType`."""
    def consume(self, handler, model):
        """Parse the body json via :func:`json.loads` and initialize the
        `model`.

        .. seealso:: :py:mod:`supercell.api.provider.ProviderBase.provide`
        """
        # TODO error if no request body is set
        return model(json.loads(handler.request.body.decode('utf8')))
Esempio n. 8
0
    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
Esempio n. 9
0
    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
Esempio n. 10
0
    def map_provider(accept_header, handler, allow_default=False):
        """Map a given content type to the correct provider implementation.

        If no provider matches, raise a `NoProviderFound` exception.

        :param accept_header: HTTP Accept header value
        :type accept_header: str
        :param handler: supercell request handler
        :raises: :exc:`NoProviderFound`
        """
        if not hasattr(handler, '_PROD_CONTENT_TYPES'):
            raise NoProviderFound()

        accept = parse_accept_header(accept_header)

        if len(accept) > 0:
            for (ctype, params, q) in accept:
                if ctype not in handler._PROD_CONTENT_TYPES:
                    continue

                c = ContentType(ctype,
                                vendor=params.get('vendor', None),
                                version=params.get('version', None))
                if c not in handler._PROD_CONTENT_TYPES[ctype]:
                    continue

                known_types = [
                    t for t in ProviderMeta.KNOWN_CONTENT_TYPES[ctype]
                    if t[0] == c
                ]

                if len(known_types) == 1:
                    return known_types[0][1]

        if 'default' in handler._PROD_CONTENT_TYPES:
            content_type = handler._PROD_CONTENT_TYPES['default']
            ctype = content_type.content_type
            default_type = [
                t for t in ProviderMeta.KNOWN_CONTENT_TYPES[ctype]
                if t[0] == content_type
            ]

            if len(default_type) == 1:
                return default_type[0][1]

        raise NoProviderFound()
Esempio n. 11
0
class JsonProviderWithVendorAndVersion(JsonProvider):

    CONTENT_TYPE = ContentType(MediaType.ApplicationJson, vendor='supercell',
                               version=1.0)
Esempio n. 12
0
class MoreDetailedJsonProvider(JsonProvider):

    CONTENT_TYPE = ContentType(MediaType.ApplicationJson, vendor='supercell')
Esempio n. 13
0
class JsonPatchConsumer(JsonConsumer):
    """Default **application/json-patch+json** consumer."""

    CONTENT_TYPE = ContentType(MediaType.ApplicationJsonPatch)
    """The **application/json-patch+json** :class:`ContentType`."""