""" JSON Draft4 Schema Validator Wrapper ==================================== A Wrapper for a JSON Draft4 schema validation library which allows us to transform the results into an internal Response() format. """ from functools import wraps from flask import request from jsonschema import Draft4Validator from ows_accounting import response from ows_accounting.constants import error def populate_validate_result(data, validator): """Generic JSON Draft4 Schema Validation. Args: data (dict): JSON to be validated. validator (Draft4Validator): JSON Draft4 Schema used. Returns: Response: Result of the validation as a Response object. """ validation = Draft4Validator(validator) for result_error in sorted(validation.iter_errors(data), key=str): key = None condition = '' message = error.ERROR_MESSAGE_NO_MATCH if len(result_error.relative_schema_path) > 2: condition = result_error.relative_schema_path.pop() key = result_error.relative_schema_path.pop() elif len(result_error.relative_schema_path) == 1: message = result_error.message if key in error.JSON_SCHEMA_ERRORS: message = '{message} {condition}'.format( message=error.JSON_SCHEMA_ERRORS.get(key) or '', condition=condition).strip() return response.create_error_response( error.ERROR_CODE_INVALID_REQUEST, message, status=400) return response.Response(message=data, status=200) def validate_request(args_schema=None, body_schema=None): """Decorates the handlers for parameter validation. Args: args_schema (str): JSON Draft4 Schema used for query string. body_schema (str): JSON Draft4 Schema used for request body. Returns: function: Decorated with validation results. """ def decorator(handler_function): @wraps(handler_function) def wrapper(*args, **kwargs): validation_response = response.Response() if args_schema: data = request.args.to_dict(flat=True) validation_response = populate_validate_result( data, args_schema) if body_schema: validation_response = populate_validate_result( request.get_json(), body_schema) if not validation_response: return response.flaskify(validation_response) return handler_function(*args, **kwargs) return wrapper return decorator