Source code for flask_negotiation.decorators
""":mod:`decorators` --- Decorators for Flask views
===================================================
"""
from functools import wraps
from flask import request
from werkzeug.exceptions import NotAcceptable
from renderers import Renderer
from media_type import acceptable_media_types, MediaType, choose_media_type
[docs]def provides(media_type, *args, **kwargs):
"""Decorator that recognizes acceptablility of view function.
For example::
from flask.ext.negotiation.decorators import provides
@app.route('/json_only')
@provides('application/json')
def json_only():
return json.dumps({'text':'JSON Mraz'})
And you can provide multiple types like this::
from flask.ext.negotiation.decorators import provides
@app.route('/json_and_html')
@provides('text/html', 'application/json')
def json_and_html():
data = get_data()
return render(data)
Or you can use renderer::
from flask.ext.negotiation.renderes import template_renderer
from flask.ext.negotiation.decorators import provides
@app.route('/json_and_html')
@provides(template_renderer, 'application/json')
def json_and_html():
data = get_data()
return render(data)
And you can handle choosen media type::
from flask.ext.negotiation.decorators import provides
@provides('application/json', 'text/html', to='provide_type')
def handle_type(provide_type):
return str(provide_type)
`to` does *not* guarantee same media type with `render` function.
"""
to = kwargs.get('to', None)
# Collect media types
media_types = []
for media_type in (media_type, ) + args:
if isinstance(media_type, MediaType):
media_types.append(media_type)
elif isinstance(media_type, type) and issubclass(media_type, Renderer):
media_types += map(MediaType, media_type.__media_types__)
elif isinstance(media_type, Renderer):
media_types += media_type.media_types
else:
media_types.append(MediaType(media_type))
# Decorator here
def decorator(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
acceptables = acceptable_media_types(request)
acceptable = choose_media_type(acceptables, media_types)
if acceptable is None:
raise NotAcceptable()
if not to is None:
kwargs.update({to: acceptable})
return fn(*args, **kwargs)
return wrapper
return decorator