Source code for flask_negotiation.renderers
""":mod:`content_negotiation.renderers`
=======================================
Renderers
"""
import json
from abc import ABCMeta, abstractmethod
from flask import render_template
from functools import wraps
from media_type import MediaType
[docs]class Renderer(object):
"""Base renderer class.
"""
__metaclass__ = ABCMeta
__media_types__ = ()
"""A collection of supporting media-type :class:`string`s, subclasses must
redefine this value.
"""
@property
def media_types(self):
"""Collections of abstracted media-types.
"""
return (MediaType(x) for x in self.__media_types__)
[docs] def can_render(self, media_type):
"""Determines that renderer can render `media_type`.
"""
return not self.choose_media_type(media_type) is None
@abstractmethod
[docs] def render(self, data, template=None, ctx=None):
"""Renders `data`.
You must implement it
"""
pass
[docs]class TemplateRenderer(Renderer):
"""Renders object to HTML response.
"""
__media_types__ = ('text/html', )
def __init__(self, ext='html'):
super(TemplateRenderer, self).__init__()
self.ext = ext
[docs] def render(self, data, template=None, ctx=None):
template = template or ''
ext = '.' + self.ext
if not template.endswith(ext):
template += ext
ctx = ctx or {
'data': data
}
return render_template(template, **ctx)
[docs]class JSONRenderer(Renderer):
"""Renders object to json with JSONEncoder.
"""
__media_types__ = ('application/json',)
def __init__(self, encoder=json.JSONEncoder()):
""":param encoder: encoder to be used with renderer.
"""
super(JSONRenderer, self).__init__()
self.encoder = encoder
[docs] def render(self, data, template=None, ctx=None):
return self.encoder.encode(data)
[docs]class FunctionRenderer(Renderer):
"""Renders object with a function.
"""
def __init__(self, fn, media_types):
super(FunctionRenderer, self).__init__()
self.fn = fn
self.__media_types__ = map(unicode, media_types)
[docs] def render(self, data, template=None, ctx=None):
return self.fn(data, template=template, ctx=ctx)
def __call__(self, *args, **kwargs):
return self.render(*args, **kwargs)
[docs]def renderer(*media_types):
"""Decorator that creates simple renderer with function.
"""
def decorator(fn):
renderer = wraps(fn)(FunctionRenderer(fn, media_types))
return renderer
return decorator
# default_renderers
template_renderer = TemplateRenderer()
json_renderer = JSONRenderer()