content: Add install and get_settings functions.

This commit is contained in:
Dave Shawley 2016-04-03 07:41:15 -04:00
parent e46ff55e0f
commit 68fe438894
5 changed files with 95 additions and 4 deletions

View file

@ -12,6 +12,25 @@ This mix-in adds two methods to a ``tornado.web.RequestHandler`` instance:
- ``send_response(object)``: serializes the response into the content type
requested by the ``Accept`` header.
Before adding support for specific content types, you SHOULD install the
content settings into your ``tornado.web.Application`` instance. If you
don't install the content settings, then an instance will be created for
you by the mix-in; however, the created instance will be empty. You
should already have a function that creates the ``Application`` instance.
If you don't, now is a good time to add one.
.. code-block:: python
from sprockets.mixins.mediatype import content
from tornado import web
def make_application():
application = web.Application([
# insert your handlers here
])
content.install(application, 'application/json', 'utf-8')
return application
Support for a content types is enabled by calling ``add_binary_content_type``,
``add_text_content_type`` or the ``add_transcoder`` functions with the
``tornado.web.Application`` instance, the content type, encoding and decoding
@ -29,6 +48,7 @@ functions as parameters:
# insert your handlers here
])
content.install(application, 'application/json', 'utf-8')
content.add_text_content_type(application,
'application/json', 'utf-8',
json.dumps, json.loads)
@ -52,6 +72,7 @@ types:
# insert your handlers here
])
content.install(application, 'application/json', 'utf-8')
content.add_transcoder(application, transcoders.JSONTranscoder())
return application

View file

@ -9,6 +9,10 @@ Content Type Handling
Content Type Registration
-------------------------
.. autofunction:: install
.. autofunction:: get_settings
.. autofunction:: set_default_content_type
.. autofunction:: add_binary_content_type

View file

@ -1,5 +1,9 @@
Version History
===============
`Next Release`_
---------------
- Add :func:`sprockets.mixins.mediatype.content.install`.
- Add :func:`sprockets.mixins.mediatype.content.get_settings`.
`2.1.0`_ (16 Mar 2016)
----------------------

View file

@ -31,6 +31,7 @@ from . import handlers
logger = logging.getLogger(__name__)
SETTINGS_KEY = 'sprockets.mixins.mediatype.ContentSettings'
class ContentSettings(object):
@ -103,9 +104,7 @@ class ContentSettings(object):
@classmethod
def from_application(cls, application):
"""Retrieve the content settings from an application."""
if not hasattr(application, '_content_settings'):
setattr(application, '_content_settings', cls())
return application._content_settings
return get_settings(application, force_instance=True)
@property
def available_content_types(self):
@ -119,6 +118,48 @@ class ContentSettings(object):
return self._available_types
def install(application, default_content_type, encoding=None):
"""
Install the media type management settings.
:param tornado.web.Application application: the application to
install a :class:`.ContentSettings` object into.
:param str|NoneType default_content_type:
:param str|NoneType encoding:
:returns: the content settings instance
:rtype: sprockets.mixins.mediatype.content.ContentSettings
"""
try:
settings = application.settings[SETTINGS_KEY]
except KeyError:
settings = application.settings[SETTINGS_KEY] = ContentSettings()
settings.default_content_type = default_content_type
settings.default_encoding = encoding
return settings
def get_settings(application, force_instance=False):
"""
Retrieve the media type settings for a application.
:param tornado.web.Application application:
:keyword bool force_instance: if :data:`True` then create the
instance if it does not exist
:return: the content settings instance
:rtype: sprockets.mixins.mediatype.content.ContentSettings
"""
try:
return application.settings[SETTINGS_KEY]
except KeyError:
if not force_instance:
return None
return install(application, None)
def add_binary_content_type(application, content_type, pack, unpack):
"""
Add handler for a binary content type.

View file

@ -30,7 +30,8 @@ class UTC(datetime.tzinfo):
class Context(object):
"""Super simple class to call setattr on"""
pass
def __init__(self):
self.settings = {}
def pack_string(obj):
@ -262,6 +263,26 @@ class ContentFunctionTests(unittest.TestCase):
transcoder = settings['application/json']
self.assertIsInstance(transcoder, handlers.TextContentHandler)
def test_that_install_creates_settings(self):
settings = content.install(self.context, 'application/json', 'utf8')
self.assertIsNotNone(settings)
self.assertEqual(settings.default_content_type, 'application/json')
self.assertEqual(settings.default_encoding, 'utf8')
def test_that_get_settings_returns_none_when_no_settings(self):
settings = content.get_settings(self.context)
self.assertIsNone(settings)
def test_that_get_settings_returns_installed_settings(self):
settings = content.install(self.context, 'application/xml', 'utf8')
other_settings = content.get_settings(self.context)
self.assertIs(settings, other_settings)
def test_that_get_settings_will_create_instance_if_requested(self):
settings = content.get_settings(self.context, force_instance=True)
self.assertIsNotNone(settings)
self.assertIs(content.get_settings(self.context), settings)
class MsgPackTranscoderTests(unittest.TestCase):