Source code for views.schema_defined_resource

import abc
import jsonschema
from functools import wraps
from flask import request, jsonify, abort
from flask.ext.restful import Resource

__author__ = 'Michal Kononenko'


[docs]class SchemaDefinedResource(Resource): """ Abstract class that defines an API view with a schema built into it. This class is capable of serving its schema and """ _http_method_list = frozenset([ 'get', 'post', 'put', 'patch', 'delete', 'options', 'head' ]) def __init__(self): for method in self._http_method_list: if hasattr(self, method): setattr(self, method, self.show_schema(getattr(self, method))) @staticmethod def _parse_query_string(string): if string is None: return False if string == 'true' or string == 'True': return True elif string == 'false' or string == 'False': return False else: abort(404) @classmethod def show_schema(cls, f, req_to_parse=request): show_schema = cls._parse_query_string(req_to_parse.args.get('schema')) @wraps(f) def _wrapper(*args, **kwargs): if show_schema: return jsonify(cls.schema) else: return f(*args, **kwargs) return _wrapper @staticmethod @abc.abstractproperty def schema(): """ Return the JSON schema of the view as a dictionary """ raise NotImplementedError @property def is_schema_draft3(self): """ Checks if :attr:`self.schema` corresponds to the Draft 3 JSON Schema .. note :: At the time of writing, the latest draft of JSON Schema is Draft 4. Refrain from using Draft 3 schemas in this API wherever possible :return: True if the schema conforms to draft 3, else false :rtype: bool """ format_checker = jsonschema.FormatChecker() return format_checker.conforms(self.schema, 'draft3') @property def is_schema_draft4(self): format_checker = jsonschema.FormatChecker() return format_checker.conforms(self.schema, 'draft4')
[docs] def validate(self, dict_to_validate, source_dict=None): """ Checks that the supplied dictionary matches the JSON Schema in another dictionary. If no ``source_dict`` is provided, the method will attempt to validate the validation dictionary against `attr:self.schema`. :param dict dict_to_validate: The dictionary representing the JSON against the JSON Schema to be validated :param source_dict: The dictionary representing the JSON Schema against which the incoming JSON will be compared :return: A tuple containing a boolean corresponding to whether the schema validated or not, and a message. If the schema validated successfully, the message will be ``"success"``. If not, then the message will correspond to the reason why the schema did not successfully validate """ if source_dict is None: source_dict = self.schema try: jsonschema.validate(dict_to_validate, source_dict) return True, 'success' except jsonschema.ValidationError as val_error: return False, str(val_error)