Source code for flask_restx.schemas

"""
This module give access to OpenAPI specifications schemas
and allows to validate specs against them.

.. versionadded:: 0.12.1
"""
import io
import json
import pkg_resources

from collections.abc import Mapping
from jsonschema import Draft4Validator

from flask_restx import errors


[docs]class SchemaValidationError(errors.ValidationError): """ Raised when specification is not valid .. versionadded:: 0.12.1 """ def __init__(self, msg, errors=None): super(SchemaValidationError, self).__init__(msg) self.errors = errors def __str__(self): msg = [self.msg] for error in sorted(self.errors, key=lambda e: e.path): path = ".".join(error.path) msg.append("- {}: {}".format(path, error.message)) for suberror in sorted(error.context, key=lambda e: e.schema_path): path = ".".join(suberror.schema_path) msg.append(" - {}: {}".format(path, suberror.message)) return "\n".join(msg) __unicode__ = __str__
[docs]class LazySchema(Mapping): """ A thin wrapper around schema file lazy loading the data on first access :param filename str: The package relative json schema filename :param validator: The jsonschema validator class version .. versionadded:: 0.12.1 """ def __init__(self, filename, validator=Draft4Validator): super(LazySchema, self).__init__() self.filename = filename self._schema = None self._validator = validator def _load(self): if not self._schema: filename = pkg_resources.resource_filename(__name__, self.filename) with io.open(filename) as infile: self._schema = json.load(infile) def __getitem__(self, key): self._load() return self._schema.__getitem__(key) def __iter__(self): self._load() return self._schema.__iter__() def __len__(self): self._load() return self._schema.__len__() @property def validator(self): """The jsonschema validator to validate against""" return self._validator(self)
#: OpenAPI 2.0 specification schema OAS_20 = LazySchema("oas-2.0.json") #: Map supported OpenAPI versions to their JSON schema VERSIONS = { "2.0": OAS_20, }
[docs]def validate(data): """ Validate an OpenAPI specification. Supported OpenAPI versions: 2.0 :param data dict: The specification to validate :returns boolean: True if the specification is valid :raises SchemaValidationError: when the specification is invalid :raises flask_restx.errors.SpecsError: when it's not possible to determinate the schema to validate against .. versionadded:: 0.12.1 """ if "swagger" not in data: raise errors.SpecsError("Unable to determinate OpenAPI schema version") version = data["swagger"] if version not in VERSIONS: raise errors.SpecsError('Unknown OpenAPI schema version "{}"'.format(version)) validator = VERSIONS[version].validator validation_errors = list(validator.iter_errors(data)) if validation_errors: raise SchemaValidationError( "OpenAPI {} validation failed".format(version), errors=validation_errors ) return True