Source code for supercell.api.provider

# 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.
#
#
from __future__ import absolute_import, division, print_function, with_statement

from collections import defaultdict

from supercell._compat import with_metaclass
from supercell.api import ContentType, MediaType
from supercell.utils import parse_accept_header


__all__ = ['NoProviderFound', 'ProviderBase', 'JsonProvider']


[docs]class NoProviderFound(Exception): '''Raised if no matching provider for the client's `Accept` header was found.''' pass
class ProviderMeta(type): '''Meta class for all content type providers. This will simply register a provider with the respective content type information and make them available in a list of content types and their mappers. ''' KNOWN_CONTENT_TYPES = defaultdict(list) def __new__(cls, name, bases, dct): provider_class = type.__new__(cls, name, bases, dct) if name != 'ProviderBase' and hasattr(provider_class, 'CONTENT_TYPE'): ct = provider_class.CONTENT_TYPE ProviderMeta.KNOWN_CONTENT_TYPES[ct.content_type].append( (ct, provider_class)) return provider_class
[docs]class ProviderBase(with_metaclass(ProviderMeta, object)): '''Base class for content type providers. Creating a new provider is just as simple as creating new consumers:: class MyProvider(s.ProviderBase): CONTENT_TYPE = s.ContentType('application/xml') def provide(self, model, handler): self.set_header('Content-Type', 'application/xml') handler.write(model.to_xml()) ''' CONTENT_TYPE = None '''The target content type for the provider. :type: `supercell.api.ContentType` ''' @staticmethod
[docs] 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()
[docs] def provide(self, model, handler): '''This method should return the correct representation as a simple string (i.e. byte buffer) that will be used as return value. :param model: the model to convert to a certain content type :type model: supercell.schematics.Model ''' raise NotImplemented()
[docs]class JsonProvider(ProviderBase): '''Default `application/json` provider.''' CONTENT_TYPE = ContentType(MediaType.ApplicationJson)
[docs] def provide(self, model, handler): '''Simply return the json via `json.dumps`. .. seealso:: :py:mod:`supercell.api.provider.ProviderBase.provide` ''' handler.write(model.validate())
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.