API Documentation

The easiest way to use this library is to:

  1. call install() when you create your application instance and specify a default content type

  2. call add_transcoder() to install transcoders for the content types that you support – use add_binary_content_type() and/or add_text_content_type() if you don’t want to define a Transcoder class.

  3. include ContentMixin in your handler’s inheritance chain

  4. call get_request_body() to retrieve a request body sent in any of the supported content types

  5. call send_response() to send a response in any of the supported content types

The ContentMixin will take care of inspecting the Content-Type header and deserialize the request as well as implementing the proactive content negotiation algorithm described in RFC 7231 to serialize a response object appropriately.

Content Type Handling

class sprockets.mixins.mediatype.content.ContentMixin(application: tornado.web.Application, request: tornado.httputil.HTTPServerRequest, **kwargs: Any)[source]

Mix this in to add some content handling methods.

class MyHandler(ContentMixin, web.RequestHandler):
   def post(self):
      body = self.get_request_body()
      # do stuff --> response_dict
      self.send_response(response_dict)

get_request_body() will deserialize the request data into a dictionary based on the Content-Type request header. Similarly, send_response() takes a dictionary, serializes it based on the Accept request header and the application ContentSettings, and writes it out, using self.write().

get_request_body() sprockets.mixins.mediatype.type_info.Deserialized[source]

Fetch (and cache) the request body as a dictionary.

Raises

tornado.web.HTTPError

  • if the content type cannot be matched, then the status code is set to 415 Unsupported Media Type.

  • if decoding the content body fails, then the status code is set to 400 Bad Syntax.

get_response_content_type() Optional[str][source]

Select the content type will be used in the response.

This method implements proactive content negotiation as described in RFC 7231#section-3.4.1 using the Accept request header or the configured default content type if the header is not present. The selected response type is cached and returned. It will be used when send_response() is called.

Note that this method is called by send_response() so you will seldom need to call it directly.

send_response(body: sprockets.mixins.mediatype.type_info.Serializable, set_content_type: Optional[bool] = True) None[source]

Serialize and send body in the response.

Parameters
  • body – the body to serialize

  • set_content_type – should the Content-Type header be set? Defaults to True

The transcoder for the response is selected by calling get_response_content_type() which chooses an appropriate transcoder based on the Accept header from the request.

Content Type Registration

sprockets.mixins.mediatype.content.install(application: sprockets.mixins.mediatype.type_info.HasSettings, default_content_type: Optional[str], encoding: Optional[str] = None) sprockets.mixins.mediatype.content.ContentSettings[source]

Install the media type management settings and return it

sprockets.mixins.mediatype.content.add_transcoder(application: sprockets.mixins.mediatype.type_info.HasSettings, transcoder: sprockets.mixins.mediatype.type_info.Transcoder, content_type: Optional[str] = None) None[source]

Register a transcoder for a specific content type.

Parameters
  • application – the application to modify

  • transcoder – object that translates between bytes and object instances

  • content_type – the content type to add. If this is unspecified or None, then the transcoder’s content_type attribute is used.

The transcoder instance is required to implement the Transcoder protocol.

sprockets.mixins.mediatype.content.set_default_content_type(application: sprockets.mixins.mediatype.type_info.HasSettings, content_type: str, encoding: Optional[str] = None) None[source]

Store the default content type for an application.

Parameters
  • application – the application to modify

  • content_type – the content type to default to

  • encoding – encoding to use when one is unspecified

sprockets.mixins.mediatype.content.add_binary_content_type(application: sprockets.mixins.mediatype.type_info.HasSettings, content_type: str, pack: sprockets.mixins.mediatype.type_info.PackBFunction, unpack: sprockets.mixins.mediatype.type_info.UnpackBFunction) None[source]

Add handler for a binary content type.

Parameters
  • application – the application to modify

  • content_type – the content type to add

  • pack – function that packs a dictionary to a byte string. See type_info.PackBFunction

  • unpack – function that takes a byte string and returns a dictionary. See type_info.UnpackBFunction

sprockets.mixins.mediatype.content.add_text_content_type(application: sprockets.mixins.mediatype.type_info.HasSettings, content_type: str, default_encoding: str, dumps: sprockets.mixins.mediatype.type_info.DumpSFunction, loads: sprockets.mixins.mediatype.type_info.LoadSFunction) None[source]

Add handler for a text content type.

Parameters
  • application – the application to modify

  • content_type – the content type to add

  • default_encoding – encoding to use when one is unspecified

  • dumps – function that dumps a dictionary to a string. See type_info.DumpSFunction

  • loads – function that loads a dictionary from a string. See type_info.LoadSFunction

Note that the charset parameter is stripped from content_type if it is present.

sprockets.mixins.mediatype.content.get_settings(application: sprockets.mixins.mediatype.type_info.HasSettings, force_instance: typing_extensions.Literal[False] = False) Optional[sprockets.mixins.mediatype.content.ContentSettings][source]
sprockets.mixins.mediatype.content.get_settings(application: sprockets.mixins.mediatype.type_info.HasSettings, force_instance: typing_extensions.Literal[True]) sprockets.mixins.mediatype.content.ContentSettings

Retrieve the media type settings for a application.

Parameters
  • application

  • force_instance – if True then create the instance if it does not exist

Returns

the content settings instance or None if force_instance is not True and install() has not been called

class sprockets.mixins.mediatype.content.ContentSettings[source]

Content selection settings.

An instance of this class is stashed in application.settings under the SETTINGS_KEY key. Instead of creating an instance of this class yourself, use the install() function to install it into the application.

The settings instance contains the list of available content types and handlers associated with them. Each handler implements the Transcoder interface. Use add_transcoder() to add support for a specific content type to the application.

This class acts as a mapping from content-type string to the appropriate handler instance. Add new content types and find handlers using the common dict syntax:

class SomeHandler(web.RequestHandler):

   def get(self):
      settings = ContentSettings.get_settings(self.application)
      response_body = settings['application/msgpack'].to_bytes(
         response_dict, encoding='utf-8')
      self.write(response_body)

def make_application():
   app = web.Application([('/', SomeHandler)])
   add_transcoder(app, transcoders.JSONTranscoder())
   add_transcoder(app, transcoders.MsgPackTranscoder())
   return app

Of course, that is quite tedious, so use the ContentMixin instead of using the settings directly.

property available_content_types: Sequence[ietfparse.datastructures.ContentType]

List of the content types that are registered.

This is a sequence of ietfparse.datastructures.ContentType instances.

get(content_type: str, default: typing.Union[type_info.Transcoder, None] = None) typing.Union[type_info.Transcoder, None][source]

Retrieve the handler for a specific content type.

Bundled Transcoders

class sprockets.mixins.mediatype.transcoders.JSONTranscoder(content_type: str = 'application/json', default_encoding: str = 'utf-8')[source]

JSON transcoder instance.

Parameters
  • content_type – the content type that this encoder instance implements. If omitted, application/json is used. This is passed directly to the TextContentHandler initializer.

  • default_encoding – the encoding to use if none is specified. If omitted, this defaults to utf-8. This is passed directly to the TextContentHandler initializer.

This JSON encoder uses json.loads() and json.dumps() to implement JSON encoding/decoding. The dump_object() method is configured to handle types that the standard JSON module does not support.

dump_options

Keyword parameters that are passed to json.dumps() when dumps() is called. By default, the dump_object() method is enabled as the default object hook.

load_options

Keyword parameters that are passed to json.loads() when loads() is called.

dump_object(obj: sprockets.mixins.mediatype.type_info.Serializable) str[source]

Called to encode unrecognized object.

Parameters

obj – the object to encode

Returns

the encoded object

Raises

TypeError – when obj cannot be encoded

This method is passed as the default keyword parameter to json.dumps(). It provides default representations for a number of Python language/standard library types.

Python Type

String Format

bytes, bytearray, memoryview

Base64 encoded string.

datetime.datetime

ISO8601 formatted timestamp in the extended format including separators, milliseconds, and the timezone designator.

uuid.UUID

Same as str(value)

dumps(obj: sprockets.mixins.mediatype.type_info.Serializable) str[source]

Dump a object instance into a JSON str

loads(str_repr: str) sprockets.mixins.mediatype.type_info.Deserialized[source]

Transform str into an object instance.

class sprockets.mixins.mediatype.transcoders.MsgPackTranscoder(content_type: str = 'application/msgpack')[source]

Msgpack Transcoder instance.

Parameters

content_type – the content type that this encoder instance implements. If omitted, application/msgpack is used. This is passed directly to the BinaryContentHandler initializer.

This transcoder uses the umsgpack library to encode and decode objects according to the msgpack format.

normalize_datum(datum: sprockets.mixins.mediatype.type_info.Serializable) sprockets.mixins.mediatype.type_info.MsgPackable[source]

Convert datum into something that umsgpack likes.

Parameters

datum – something that we want to process with umsgpack

Returns

a packable version of datum

Raises

TypeError – if datum cannot be packed

This message is called by packb() to recursively normalize an input value before passing it to umsgpack.packb(). Values are normalized according to the following table.

Value

MsgPack Family

None

nil byte (0xC0)

True

true byte (0xC3)

False

false byte (0xC2)

int

integer family

float

float family

String

str family

bytes

bin family

bytearray

bin family

memoryview

bin family

collections.abc.Sequence

array family

collections.abc.Set

array family

collections.abc.Mapping

map family

uuid.UUID

Converted to String

packb(data: sprockets.mixins.mediatype.type_info.Serializable) bytes[source]

Pack data into a bytes instance.

unpackb(data: bytes) sprockets.mixins.mediatype.type_info.Deserialized[source]

Unpack a object from a bytes instance.

class sprockets.mixins.mediatype.transcoders.FormUrlEncodedTranscoder(**encoding_options: Any)[source]

Opinionated transcoder for the venerable x-www-formurlencoded.

Parameters

encoding_options – keyword parameters are used to initialize FormUrlEncodingOptions

This transcoder implements transcoding according to the current W3C documentation. The encoding interface takes mappings or sequences of pairs and encodes both the name and value. The following table describes how each supported type is encoded.

Value / Type

Encoding

character strings

UTF-8 codepoints before percent- encoding the resulting bytes

space character

%20 or +

False

false

True

true

None

the empty string

numbers

str(n)

byte sequences

percent-encoded bytes

uuid.UUID

str(u)

datetime.datetime

result of calling isoformat()

https://url.spec.whatwg.org/#application/x-www-form-urlencoded

Warning

Types that are not explicitly mentioned above will result in to_bytes() simply calling str(value) and encoding the result. This causes nested sequences to be encoded as their repr. For example, encoding {'a': [1, 2]} will result in a=%5B1%2C%202%5D. This matches what urllib.parse.urlencode() does by default.

Better support for sequence values can be enabled by setting the encode_sequences attribute of options. This mimics the doseq parameter of urllib,parse.urlencode().

options: FormUrlEncodingOptions

Controls the behavior of the transcoder

from_bytes(data_bytes: bytes, encoding: Optional[str] = None) sprockets.mixins.mediatype.type_info.Deserialized[source]

Deserialize bytes into a Python object instance.

Parameters
  • data_bytes – byte string to deserialize

  • encoding – optional encoding override

Deserialization is implemented according to the W3C urlencoded deserialization algorithm. The options attribute controls the configurable details of the encoding process.

Returns

the decoded Python object

to_bytes(inst_data: sprockets.mixins.mediatype.type_info.Serializable, encoding: Optional[str] = None) Tuple[str, bytes][source]

Serialize inst_data into a byte stream and content type spec.

Parameters
  • inst_data – the data to serialize

  • encoding – optional encoding override

Serialization is implemented as described in the W3C urlencoded serialization algorithm. The options attribute controls the configurable details of the encoding process.

The character encoding can be further overridden by specifying the encoding parameter.

Returns

tuple of the content type and the resulting bytes

Raises

TypeError if a supplied value cannot be serialized

class sprockets.mixins.mediatype.transcoders.FormUrlEncodingOptions(encoding: str = 'utf-8', encode_sequences: bool = False, literal_mapping: dict[typing.Literal[(None, True, False)], str] = <factory>, space_as_plus: bool = False)[source]

Configuration knobs for FormUrlEncodedTranscoder

encode_sequences: bool = False

Encode sequence values as multiple name=value instances.

encoding: str = 'utf-8'

Encoding use when generating the byte stream from character data.

literal_mapping: dict[typing.Literal[None, True, False], str]

Mapping from supported literal values to strings.

space_as_plus: bool = False

Quote spaces as %20 or +.

Python Type Information

The sprockets.mixins.mediatype.type_info module contains a number of convenience type definitions for those you you who take advantage of type annotations.

Interface Types

class sprockets.mixins.mediatype.type_info.Transcoder(*args, **kwds)[source]

Object that transforms objects to bytes and back again.

Transcoder instances are identified by their content_type instance attribute and registered by calling add_transcoder(). They are used to implement request deserialization (get_request_body()) and response body serialization (send_response())

content_type: str

Canonical content type that this transcoder implements.

from_bytes(data_bytes: bytes, encoding: Optional[str] = None) sprockets.mixins.mediatype.type_info.Deserialized[source]

Deserialize bytes into a Python object instance.

Parameters
  • data_bytes – byte string to deserialize

  • encoding – optional encoding to use when deserializing

The encoding parameter may not be used by all transcoders.

Returns

the decoded Python object

to_bytes(inst_data: sprockets.mixins.mediatype.type_info.Serializable, encoding: Optional[str] = None) Tuple[str, bytes][source]

Serialize inst_data into a byte stream and content type spec.

Parameters
  • inst_data – the data to serialize

  • encoding – optional encoding to use when serializing

The content type is returned since it may contain the encoding or character set as a parameter. The encoding parameter may not be used by all transcoders.

Returns

tuple of the content type and the resulting bytes

sprockets.mixins.mediatype.type_info.Serializable

Types that can be serialized by this library.

This is the set of types that sprockets.mixins.mediatype.content.ContentMixin.send_response() is capable for serializing.

alias of Union[sprockets.mixins.mediatype.type_info.DefinesIsoFormat, None, bool, bytearray, bytes, float, int, memoryview, str, Mapping, Sequence, Set, uuid.UUID]

sprockets.mixins.mediatype.type_info.Deserialized

Possible result of deserializing a body.

This is the set of types that sprockets.mixins.mediatype.content.ContentMixin.get_request_body() might return.

alias of Union[None, bytes, Mapping, float, int, list, str]

Convenience Types

sprockets.mixins.mediatype.type_info.PackBFunction

Signature of a binary content handler’s serialization hook.

alias of Callable[[Union[sprockets.mixins.mediatype.type_info.DefinesIsoFormat, None, bool, bytearray, bytes, float, int, memoryview, str, Mapping, Sequence, Set, uuid.UUID]], bytes]

sprockets.mixins.mediatype.type_info.UnpackBFunction

Signature of a binary content handler’s deserialization hook.

alias of Callable[[bytes], Union[None, bytes, Mapping, float, int, list, str]]

sprockets.mixins.mediatype.type_info.DumpSFunction

Signature of a text content handler’s serialization hook.

alias of Callable[[Union[sprockets.mixins.mediatype.type_info.DefinesIsoFormat, None, bool, bytearray, bytes, float, int, memoryview, str, Mapping, Sequence, Set, uuid.UUID]], str]

sprockets.mixins.mediatype.type_info.LoadSFunction

Signature of a text content handler’s deserialization hook.

alias of Callable[[str], Union[None, bytes, Mapping, float, int, list, str]]

Contract Types

class sprockets.mixins.mediatype.type_info.HasSettings(*args, **kwds)[source]

Something that quacks like a tornado.web.Application.

settings: Dict[str, Any]

Application settings.

class sprockets.mixins.mediatype.type_info.DefinesIsoFormat(*args, **kwds)[source]

An object that has an isoformat method.

isoformat() str[source]

Return the date/time in ISO-8601 format.