1from __future__ import absolute_import 2 3from functools import wraps 4 5import falcon 6 7try: 8 import jsonschema 9except ImportError: 10 pass 11 12 13def validate(req_schema=None, resp_schema=None): 14 """Decorator for validating ``req.media`` using JSON Schema. 15 16 This decorator provides standard JSON Schema validation via the 17 ``jsonschema`` package available from PyPI. Semantic validation via 18 the *format* keyword is enabled for the default checkers implemented 19 by ``jsonschema.FormatChecker``. 20 21 Note: 22 The `jsonschema`` package must be installed separately in order to use 23 this decorator, as Falcon does not install it by default. 24 25 See `json-schema.org <http://json-schema.org/>`_ for more 26 information on defining a compatible dictionary. 27 28 Args: 29 req_schema (dict, optional): A dictionary that follows the JSON 30 Schema specification. The request will be validated against this 31 schema. 32 resp_schema (dict, optional): A dictionary that follows the JSON 33 Schema specification. The response will be validated against this 34 schema. 35 36 Example: 37 .. code:: python 38 39 from falcon.media.validators import jsonschema 40 41 # -- snip -- 42 43 @jsonschema.validate(my_post_schema) 44 def on_post(self, req, resp): 45 46 # -- snip -- 47 48 """ 49 50 def decorator(func): 51 @wraps(func) 52 def wrapper(self, req, resp, *args, **kwargs): 53 if req_schema is not None: 54 try: 55 jsonschema.validate( 56 req.media, req_schema, 57 format_checker=jsonschema.FormatChecker() 58 ) 59 except jsonschema.ValidationError as e: 60 raise falcon.HTTPBadRequest( 61 'Request data failed validation', 62 description=e.message 63 ) 64 65 result = func(self, req, resp, *args, **kwargs) 66 67 if resp_schema is not None: 68 try: 69 jsonschema.validate( 70 resp.media, resp_schema, 71 format_checker=jsonschema.FormatChecker() 72 ) 73 except jsonschema.ValidationError: 74 raise falcon.HTTPInternalServerError( 75 'Response data failed validation' 76 # Do not return 'e.message' in the response to 77 # prevent info about possible internal response 78 # formatting bugs from leaking out to users. 79 ) 80 81 return result 82 return wrapper 83 return decorator 84