from functools import wraps from flask import request import jsonschema class ValidationError(Exception): def __init__(self, message): Exception.__init__(self) self.message = message def _check_parameter_exists(param): if not param in request.args: raise ValidationError("No {} is specified".format(param)) def _is_number(s): try: float(s) return True except ValueError: return False def validate_jsonschema(schema): def decorator(f): @wraps(f) def wrapper(*args, **kwargs): if not request.json: raise ValidationError("Payload is not valid json") try: j = request.json jsonschema.validate(j, schema) except jsonschema.ValidationError as e: raise ValidationError(e.message) except jsonschema.SchemaError as e: raise ValidationError(e.message) return f(*args, **kwargs) return wrapper return decorator def validate_exists(*keys): def decorator(f): @wraps(f) def wrapper(*args, **kwargs): for key in keys: _check_parameter_exists(key) return f(*args, **kwargs) return wrapper return decorator def validate_number(*keys): def decorator(f): @wraps(f) def wrapper(*args, **kwargs): for key in keys: _check_parameter_exists(key) value = request.args.get(key) if not _is_number(value): raise ValidationError("{} is not a number".format(key)) return f(*args, **kwargs) return wrapper return decorator def validate_any_of(key, values): def decorator(f): @wraps(f) def wrapper(*args, **kwargs): _check_parameter_exists(key) value = request.args.get(key) if not value in values: raise ValidationError( "{} contains an invalid value, must be one of: {}".format( key, values ) ) return f(*args, **kwargs) return wrapper return decorator