This is a first pass at a non-breaking change that'll allow for a customizable media handling system. This approach combines many of the suggestions brought up by the community in #145. One the thing that is left out of this PR is handling full content negotiation (i.e. connecting the request's accept header to the response's content-type). Unfortunately, this is a harder problem to solve in a backwards compatible fashion that doesn't affect performance. However, especially as we move towards v2, I think that would be a great opportunity to revisit full negotiation. In the meantime, there are several easy workarounds for people needing this functionality. Closes #145
48 lines
1.2 KiB
Python
48 lines
1.2 KiB
Python
from __future__ import absolute_import
|
|
|
|
import falcon
|
|
|
|
try:
|
|
import jsonschema
|
|
except ImportError:
|
|
pass
|
|
|
|
|
|
def validate(schema):
|
|
"""Decorator that validates ``req.media`` using JSON Schema
|
|
|
|
Args:
|
|
schema (dict): A dictionary that follows the JSON Schema specification.
|
|
See `json-schema.org <http://json-schema.org/>`_ for more
|
|
information on defining a compatible dictionary.
|
|
|
|
Example:
|
|
.. code:: python
|
|
|
|
from falcon.media.validators import jsonschema
|
|
|
|
# -- snip --
|
|
|
|
@jsonschema.validate(my_post_schema)
|
|
def on_post(self, req, resp):
|
|
|
|
# -- snip --
|
|
|
|
Note:
|
|
This validator requires the ``jsonschema`` library available via
|
|
PyPI. The library also requires Python 2.7+.
|
|
"""
|
|
def decorator(func):
|
|
def wrapper(self, req, resp, *args, **kwargs):
|
|
try:
|
|
jsonschema.validate(req.media, schema)
|
|
except jsonschema.ValidationError as e:
|
|
raise falcon.HTTPBadRequest(
|
|
'Failed data validation',
|
|
description=e.message
|
|
)
|
|
|
|
return func(self, req, resp, *args, **kwargs)
|
|
return wrapper
|
|
return decorator
|