def validate(schema, handler=None, status=<NUM_LIT>, **kw):
def deco(f):<EOL><INDENT>def wrapped(*args, **kwargs):<EOL><INDENT>request.validation_error = None<EOL>if request.method in ('<STR_LIT:POST>', '<STR_LIT>'):<EOL><INDENT>try:<EOL><INDENT>body = request.body.decode()<EOL>if not body:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>data = json.loads(body)<EOL>notario.validate(data, schema)<EOL><DEDENT>except (Invalid, ValueError) as error:<EOL><INDENT>request.validation_error = error<EOL>if handler:<EOL><INDENT>redirect_to_handler(error, handler)<EOL><DEDENT>if handler is None:<EOL><INDENT>headers = {'<STR_LIT:Content-Type>': '<STR_LIT:application/json>'}<EOL>raise JSONValidationException(<EOL>detail=error,<EOL>headers=headers<EOL>)<EOL><DEDENT><DEDENT><DEDENT>return f(*args, **kwargs)<EOL><DEDENT>return wrapped<EOL><DEDENT>return deco<EOL>
Used to decorate a Pecan controller with form creation for GET | HEAD and
form validation for anything else (e.g., POST | PUT | DELETE ).

For an HTTP POST or PUT (RFC2616 unsafe methods) request, the schema is
used to validate the request body. Errors from validation (if any) are
accessible at ``request.pecan['schema'].errors``.

Optionally, validation errors can be made to trigger an internal HTTP
redirect by specifying a ``handler`` in the ``error_cfg`` argument.

:param schema: A JSON schema.
:param handler: A URI path to redirect to when schema validation fails.
                Can also be a callable that returns a URI path.
:param status: The HTTP response code to use. Defaults to 400