class TestRefResolver(TestCase): def setUp(self): self.resolver = RefResolver() self.schema = mock.MagicMock() def test_it_resolves_local_refs(self): ref = "#/properties/foo" resolved = self.resolver.resolve(self.schema, ref) self.assertEqual(resolved, self.schema["properties"]["foo"]) def test_it_retrieves_non_local_refs(self): schema = '{"type" : "integer"}' get_page = mock.Mock(return_value=StringIO(schema)) resolver = RefResolver(get_page=get_page) url = "http://example.com/schema" resolved = resolver.resolve(mock.Mock(), url) self.assertEqual(resolved, json.loads(schema)) get_page.assert_called_once_with(url) def test_it_uses_urlopen_by_default_for_nonlocal_refs(self): self.assertEqual(self.resolver.get_page, urlopen) def test_it_accepts_a_ref_store(self): store = mock.Mock() self.assertEqual(RefResolver(store).store, store) def test_it_retrieves_stored_refs(self): ref = self.resolver.store["cached_ref"] = mock.Mock() resolved = self.resolver.resolve(self.schema, "cached_ref") self.assertEqual(resolved, ref)
def test_if_you_give_it_junk_you_get_a_resolution_error(self): ref = "foo://bar" foo_handler = mock.Mock(side_effect=ValueError("Oh no! What's this?")) resolver = RefResolver("", {}, handlers={"foo" : foo_handler}) with self.assertRaises(RefResolutionError) as err: with resolver.resolving(ref): pass self.assertEqual(str(err.exception), "Oh no! What's this?")
def test_custom_uri_scheme_handlers(self): schema = {"foo": "bar"} ref = "foo://bar" foo_handler = mock.Mock(return_value=schema) resolver = RefResolver("", {}, handlers={"foo": foo_handler}) with resolver.resolving(ref) as resolved: self.assertEqual(resolved, schema) foo_handler.assert_called_once_with(ref)
def test_it_retrieves_non_local_refs(self): schema = '{"type" : "integer"}' get_page = mock.Mock(return_value=StringIO(schema)) resolver = RefResolver(get_page=get_page) url = "http://example.com/schema" resolved = resolver.resolve(mock.Mock(), url) self.assertEqual(resolved, json.loads(schema)) get_page.assert_called_once_with(url)
def test_cache_remote_off(self): ref = "foo://bar" foo_handler = mock.Mock() resolver = RefResolver("", {}, cache_remote=False, handlers={"foo": foo_handler}) with resolver.resolving(ref): pass with resolver.resolving(ref): pass self.assertEqual(foo_handler.call_count, 2)
def test_cache_remote_on(self): ref = "foo://bar" foo_handler = mock.Mock() resolver = RefResolver("", {}, cache_remote=True, handlers={"foo": foo_handler}) with resolver.resolving(ref): pass with resolver.resolving(ref): pass foo_handler.assert_called_once_with(ref)
class TestRefResolver(unittest.TestCase): def setUp(self): self.base_uri = "" self.referrer = {} self.store = {} self.resolver = RefResolver(self.base_uri, self.referrer, self.store) def test_it_does_not_retrieve_schema_urls_from_the_network(self): ref = Draft3Validator.META_SCHEMA["id"] with mock.patch.object(self.resolver, "resolve_remote") as remote: resolved = self.resolver.resolve(ref) self.assertEqual(resolved, Draft3Validator.META_SCHEMA) self.assertFalse(remote.called) def test_it_resolves_local_refs(self): ref = "#/properties/foo" self.referrer["properties"] = {"foo" : object()} resolved = self.resolver.resolve(ref) self.assertEqual(resolved, self.referrer["properties"]["foo"]) def test_it_retrieves_stored_refs(self): self.resolver.store["cached_ref"] = {"foo" : 12} resolved = self.resolver.resolve("cached_ref#/foo") self.assertEqual(resolved, 12) def test_it_retrieves_unstored_refs_via_urlopen(self): ref = "http://bar#baz" schema = {"baz" : 12} with mock.patch("jsonschema.urlopen") as urlopen: urlopen.return_value.read.return_value = json.dumps(schema) resolved = self.resolver.resolve(ref) self.assertEqual(resolved, 12) urlopen.assert_called_once_with("http://bar") def test_it_can_construct_a_base_uri_from_a_schema(self): schema = {"id" : "foo"} resolver = RefResolver.from_schema(schema) self.assertEqual(resolver.base_uri, "foo") self.assertEqual(resolver.referrer, schema) def test_it_can_construct_a_base_uri_from_a_schema_without_id(self): schema = {} resolver = RefResolver.from_schema(schema) self.assertEqual(resolver.base_uri, "") self.assertEqual(resolver.referrer, schema)
def is_valid(self): handlers = {'https': self.session_request_json, 'http': self.session_request_json} resolver = RefResolver.from_schema(self.schema.raw_schema, handlers=handlers) try: validate(self.data, self.schema.raw_schema, resolver=resolver) except (SchemaError, ValidationError): return False return True
def validate(self): """ Validate that this instance matches its schema. """ schema = Schema(self.__class__.SCHEMA) resolver = RefResolver.from_schema( schema, store=REGISTRY, ) validate(self, schema, resolver=resolver)
def resolve_reference(self, value, root): """Resolves a reference. :param value: The actual reference, e.g. ``_yaml.yaml#/def`` :param root: The containing root of :param:`value`. This needs to be passed in order to resolve self-referential $refs, e.g. ``#/def``. :returns: JSON Schema pointed to by :param:`value` """ base, ref = value.split('#', 1) if base: resolver, new_root = self.resolvers[base] referrer, resolution = resolver.resolve(value) self.resolve_schema(resolution, new_root) else: resolver = RefResolver('#', root) referrer, resolution = resolver.resolve(value) return resolution
def resolve_remote (self, uri): """ Overrides superclass resolve_remote, processing "jsdb:" URI, otherwise calls superclass to fetch the schema. """ if uri[0:5] == "jsdb:": document = self.resolve_jsdb (uri) # duplicate caching logic from superclass if self.cache_remote: self.store[uri] = document return document else: return RefResolver.resolve_remote (self, uri)
def load_schema(filename): if isinstance(filename, dict): schema = filename resolver = NoRemoteResolver.from_schema(schema) else: utf8 = codecs.getreader("utf-8") asset = AssetResolver(caller_package()).resolve(filename) schema = json.load(utf8(asset.stream()), object_pairs_hook=collections.OrderedDict) resolver = RefResolver('file://' + asset.abspath(), schema) schema = mixinProperties(schema, resolver) # SchemaValidator is not thread safe for now SchemaValidator(schema, resolver=resolver, serialize=True) return schema
def __init__(self, configuration_file_path: str): """ :type configuration_file_path: str """ schema_directory = os.path.realpath('./schema') + '/' configuration_schema_file_path = os.path.join( schema_directory, 'naiad.configuration.schema.json') configuration_schema_reference_resolver = RefResolver( 'file://' + schema_directory, configuration_schema_file_path) configuration = json.load(open(configuration_file_path, 'r')) validate(configuration, json.load(open(configuration_schema_file_path, 'r')), resolver=configuration_schema_reference_resolver) self._configuration = configuration
def __init__(self, schema_file): """instantiates a SchemaValidator object Args: schema_file (string): name of JSON schema file (without directory) """ # reference resolved to "schemas" directory in this library, # schema loaded self.schema_file = schema_file self.schema_dir = os.path.dirname(inspect.getmodule(self).__file__) \ + "/" + SCHEMA_RELATIVE_DIR self.resolver = RefResolver('file://' + self.schema_dir + "/", None) self.schema_json = json.loads( open(self.schema_dir + "/" + self.schema_file, "r").read())
def validate_json(self, json_file_name): """Validate the JSON using the test classes schema file.""" json_schema = self.get_json(self.get_json_schema_file_name()) json_data = self.get_json(json_file_name) validate( json_data, json_schema, resolver=RefResolver( '', {}, store={ schema_id: self.get_json(schema_path) for schema_id, schema_path in self.schema_id_path_pairs }), format_checker=FormatChecker(), )
def assertContainsRequiredFields(schema_filename, response): schema_dir = os.path.abspath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..', '..', 'schema')) schema_filename = os.path.join(schema_dir, schema_filename) schema = json.load(open(schema_filename)) Draft4Validator.check_schema(schema) if os.name == 'nt': os_base_uri = 'file:///' else: os_base_uri = 'file://' resolver = RefResolver(referrer=schema, base_uri=os_base_uri + schema_dir + '/') # Raises ValidationError when incorrect response validate(response, schema, resolver=resolver)
def validate_json(json_document, schema_path): """Validate a json document against a json schema. :param json_document: json document in the form of a list or dict. :param schema_path: package relative path of the json schema file. """ schema_path = resource_filename('swagger_spec_validator', schema_path) schema = read_file(schema_path) resolver = RefResolver( base_uri=get_uri_from_file_path(schema_path), referrer=schema, handlers=default_handlers, ) jsonschema.validate(json_document, schema, resolver=resolver)
def validate_dict(config_dict, schemapath=config_schema_file, validator=DefaultDraft4Validator): with open(schemapath) as f: schema = yaml.load(f, Loader=YAMLLoader) schemaurl = "file://" + schemapath handlers = {"file": _yaml_handler} resolver = RefResolver(schemaurl, schema, handlers=handlers) validated_dict = deepcopy(config_dict) validator(schema=schema, types={ "quantity": (Quantity, ) }, resolver=resolver).validate(validated_dict) return validated_dict
def validate_payload(payload, schema_name): """ Validate payload with selected schema """ schemas_dir = str(f'{pathlib.Path(__file__).parent.absolute()}/schemas') schema = json.loads( pathlib.Path(f'{schemas_dir}/{schema_name}').read_text()) validate( payload, schema, resolver=RefResolver( 'file://' + str(pathlib.Path(f'{schemas_dir}/{schema_name}').absolute()), schema # it's used to resolve file: inside schemas correctly ))
def findSchemaErrors(obj, schema, baseUri=None): # XXX2 have option that includes definitions from manifest's schema if baseUri is not None: resolver = RefResolver(base_uri=baseUri, referrer=schema) else: resolver = None DefaultValidatingLatestDraftValidator.check_schema(schema) validator = DefaultValidatingLatestDraftValidator(schema, resolver=resolver) errors = list(validator.iter_errors(obj)) error = jsonschema.exceptions.best_match(errors) if not error: return None message = "%s in %s" % (error.message, "/".join(error.absolute_path)) return message, errors
def test_data(self): filename = os.path.join(os.path.dirname(__file__), 'fixtures', 'bouwdossier.json') with open(filename) as instance_json: instance = json.load(instance_json) Draft7Validator.check_schema(self.test_schema) _resolver = RefResolver(base_uri="defenitions", handlers={"https": _amsterdam_schema_handler}, referrer=None, cache_remote=False) validator = Draft7Validator(self.test_schema, resolver=_resolver) self.assertTrue(validator.is_valid(instance))
def _validate_json_against_schema(self, json_to_validate): try: base_uri = pathlib.Path( os.path.abspath('schemas/questionnaire_v1.json')).as_uri() resolver = RefResolver(base_uri=base_uri, referrer=self.schema) validate(json_to_validate, self.schema, resolver=resolver) return [] except ValidationError as e: return { 'message': e.message, 'predicted_cause': best_match([e]).message, 'path': str(e.path), } except SchemaError as e: return '{}'.format(e)
def resolver_factory(self) -> RefResolver: """ Creates a refResolver with a persistent cache :return: RefResolver """ def request_json(url): return # json.loads(self.cache.resolve(url).decode("utf-8")) resolver = RefResolver('', '', handlers={ 'http': request_json, 'https': request_json }) return resolver
def create_resolver_schema(entity: str) -> Tuple[RefResolver, Dict]: """ Create resolver and schema from json spec, catalog or collection """ json_schema_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), f"../../test/json_schema/{entity}-spec/json-schema", ) schema_path = os.path.join(json_schema_path, f"{entity}.json") resolver = RefResolver("file://" + json_schema_path + "/", None) # Loads schema with open(schema_path) as fp_schema: schema = json.load(fp_schema) return resolver, schema
def validate_instance(path, filename, schema_filename, error_printing): try: schema_file = open(join(DATS_schemasPath, schema_filename)) schema = json.load(schema_file) schemastore = get_schemas_store(DATS_schemasPath) print(schemastore) store = { schema['id']: schema} resolver = RefResolver(base_uri='file://' + DATS_schemasPath + '/' + schema_filename, referrer=schema, store=store ) validator = Draft4Validator(schema, resolver=resolver, format_checker=FormatChecker()) logger.info("Validating %s against %s ", filename, schema_filename) try: instance_file = open(join(path, filename)) instance = json.load(instance_file) if (error_printing): errors = sorted(validator.iter_errors(instance), key=lambda e: e.path) for error in errors: print(error.message) if (len(errors) == 0): return True else: return False elif (error_printing == 0): errors = sorted(validator.iter_errors(instance), key=lambda e: e.path) for error in errors: for suberror in sorted(error.context, key=lambda e: e.schema_path): print(list(suberror.schema_path), suberror.message) if (len(errors) == 0): logger.info("...done") return True else: return False else: try: validator.validate(instance, schema) logger.info("...done") return True except Exception as e: logger.error(e) return False finally: instance_file.close() finally: schema_file.close()
def add_config_files(self, flist): """Add configuration files Positional arguments: flist - a list of files to add to this configuration """ for config_file in flist: if not config_file.endswith(self.__mbed_lib_config_name): continue full_path = os.path.normpath(os.path.abspath(config_file)) # Check that we didn't already process this file if full_path in self.processed_configs: continue self.processed_configs[full_path] = True # Read the library configuration and add a "__full_config_path" # attribute to it try: cfg = json_file_to_dict(config_file) except ValueError as exc: sys.stderr.write(str(exc) + "\n") continue # Validate the format of the JSON file based on the schema_lib.json schema_root = os.path.dirname(os.path.abspath(__file__)) schema_path = os.path.join(schema_root, "schema_lib.json") schema_file = json_file_to_dict(schema_path) url = moves.urllib.request.pathname2url(schema_path) uri = moves.urllib_parse.urljoin("file://", url) resolver = RefResolver(uri, schema_file) validator = Draft4Validator(schema_file, resolver=resolver) errors = sorted(validator.iter_errors(cfg)) if errors: raise ConfigException(",".join(x.message for x in errors)) cfg["__config_path"] = full_path # If there's already a configuration for a module with the same # name, exit with error if cfg["name"] in self.lib_config_data: raise ConfigException( "Library name '%s' is not unique (defined in '%s' and '%s')" % (cfg["name"], full_path, self.lib_config_data[cfg["name"]]["__config_path"])) self.lib_config_data[cfg["name"]] = cfg
def convert(self, work_dir): """ Convert an ISA-Tab dataset (version 1) to JSON provided the ISA model v1.0 JSON Schemas :param work_dir: directory containing the ISA-tab dataset """ log.info("Converting ISA-Tab to ISA-JSON for %s", work_dir) isa_tab = parse(work_dir) if isa_tab is None: log.fatal("No ISA-Tab dataset found") else: isa_json = dict([]) if isa_tab.metadata != {}: isa_json = dict([ ("identifier", isa_tab.metadata['Investigation Identifier']), ("title", isa_tab.metadata['Investigation Title']), ("description", isa_tab.metadata['Investigation Description']), ("submissionDate", isa_tab.metadata['Investigation Submission Date']), ("publicReleaseDate", isa_tab.metadata['Investigation Public Release Date']), ("ontologySourceReferences", self.createOntologySourceReferences( isa_tab.ontology_refs)), ("publications", self.createPublications(isa_tab.publications, "Investigation")), ("people", self.createContacts(isa_tab.contacts, "Investigation")), ("studies", self.createStudies(isa_tab.studies)), ("comments", self.createComments(isa_tab.metadata)) ]) # validate json with open(join(SCHEMAS_PATH, INVESTIGATION_SCHEMA)) as json_fp: schema = json.load(json_fp) resolver = RefResolver( 'file://' + join(SCHEMAS_PATH, INVESTIGATION_SCHEMA), schema) validator = Draft4Validator(schema, resolver=resolver) validator.validate(isa_json, schema) log.info("Conversion finished") return isa_json
def validate_json(self, json_file_name): json_schema = self.get_json(self.get_json_schema_file_name()) json_data = self.get_json(json_file_name) validate( json_data, json_schema, resolver=RefResolver( '', {}, store={ schema_id: self.get_json(schema_path) for schema_id, schema_path in self.schema_id_path_pairs } ), format_checker=FormatChecker() )
def make_validator(schema, base_uri=None, timeout=TIMEOUT_IN_SECONDS): if not base_uri: base_uri = Draft7Validator.ID_OF(schema) def get_with_timeout(uri): return requests.get(uri, timeout=timeout).json() resolver = RefResolver( base_uri=base_uri, referrer=schema, handlers={ "http": get_with_timeout, "https": get_with_timeout }, ) return Draft7Validator(schema, resolver=resolver)
def validate_with_defaults(obj, schema, resolve=None): """ Validate a configuration file and fill in defaults (modifies ``obj``) """ if resolve: resolver = RefResolver('file://' + str(resolve) + '/', schema) else: resolver = None # Allow tuple/list as 'array' type # See: https://github.com/Julian/jsonschema/issues/148 types_ = {'array': (list, tuple)} validator = DefaultValidatingDraft7Validator(schema, resolver=resolver, types=types_) validator.validate(obj)
def __init__(self, schema_dir=DEFAULT_SCHEMA_DIR, load_schemas=False): try: if schema_dir is None: schema_dir = DEFAULT_SCHEMA_DIR self.schema_dir = os.path.abspath(os.path.dirname(__file__) + '/' + schema_dir) except Exception as e: print('SCHEMA ERROR') print(e) raise e self.resolver = RefResolver('file://{}/'.format(self.schema_dir), None) if load_schemas: self.schemas = self.load(self.schema_dir) else: self.schemas = {}
def validate_dict_with_schema(dictionary, schema_path): """ Validates a dictionary against a schema with given `schema_path` """ validator = Draft4Validator( validation_schema, resolver=RefResolver.from_schema(validation_schema), format_checker=FormatChecker()) schema = validation_schema for path_part in schema_path.split('/'): schema = schema[path_part] errors = [ error.message for error in validator.iter_errors(dictionary, schema) ] if errors: raise ValidationError(errors)
def _get_schema_validator(): """Get schema validator. Returns: obj: Jsonschema draft7 validator. """ schema = Config.server_schema() Draft7Validator.check_schema(schema) resolver = RefResolver(base_uri=Config.server_schema_base_uri(), referrer=schema) validator = Draft7Validator(schema, resolver=resolver, format_checker=None) return validator
def load_schemas_from_dir(directory, schemas=None, resolvers=None): """Returns all yamls and resolvers of those yamls from dir""" if schemas is None: schemas = {} if resolvers is None: resolvers = {} with visit_directory(directory): for path in glob.glob("*.yaml"): schema = load_yaml(path) schemas[path] = schema resolver = RefResolver("{}#".format(path), schema) resolvers[path] = ResolverPair(resolver, schema) return schemas, resolvers
def resolve(self, schema: dict, refs: Dict[str, dict] = None) -> dict: """Resolves and replaces json-schema $refs with the appropriate dict. Recursively walks the given schema dict, converting every instance of $ref in a 'properties' structure with a resolved dict. This modifies the input schema and also returns it. Arguments: schema: the schema dict refs: a dict of <string, dict> which forms a store of referenced schemata Returns: schema """ refs = refs or {} refs = {**self._shared_refs, **refs} return self._resolve_schema_references(schema, RefResolver("", schema, store=refs))
def from_json(cls, json_string: str): """from_json Generates me_armServo from json data :param json_string: String containing the json data. Must adhere to arm.ServoSchema :type json_string: str """ data = json.loads(json_string) resolver = RefResolver('', arm_servo_schema, schema_store) validator = Draft4Validator(arm_servo_schema, [], resolver) validator.check_schema(arm_servo_schema) if not validator.is_valid(data): raise ValidationError( 'Could not validate meArm servo json. Check your json file', instance=1) instance = cls.from_dict(data) return instance
class Validator: def __init__(self, schema_type: str, url: str): self.schema = get_json(os.path.join(settings.JSON_SCHEMAS_PATH, schema_type)) self.resolver = RefResolver( base_uri=url, referrer=self.schema ) self.base_uri = url def validate(self, data: dict): Draft4Validator.check_schema(self.schema) validator = Draft4Validator(self.schema, resolver=self.resolver, format_checker=None) validator.validate(data) def resolve(self, schema_url: str): return self.resolver.resolve_from_url(schema_url)
def validateConditionsRaw(self): dirpath = Path(f'{os.path.dirname(os.path.realpath(__file__))}', '../../json_schemas/injection_cond.json') schema_path = dirpath.absolute().as_uri() with dirpath.open('r') as jsonfile: schema = json.load(jsonfile) resolver = RefResolver( schema_path, schema, ) validator = Draft7Validator(schema, resolver=resolver, format_checker=None) instance = self.getConditions() validator.validate(instance)
def make_validator(schema, base_uri=None): if not base_uri: base_uri = Draft7Validator.ID_OF(schema) def get_from_local(uri): # pylint: disable=unused-argument meta_schema = Path(os.path.dirname(os.path.realpath(__file__))).joinpath( "data/schema/meta-schema.json" ) return json.load(meta_schema.open()) resolver = RefResolver( base_uri=base_uri, referrer=schema, handlers={"http": get_from_local, "https": get_from_local}, ) return Draft7Validator(schema, resolver=resolver)
def resolve_refs(spec, store=None, external_refs={}, handlers=None, base_uri=''): """ Resolve JSON references like {"$ref": <some URI>} in a spec. Optionally takes a store, which is a mapping from reference URLs to a dereferenced objects. Prepopulating the store can avoid network calls. """ spec = deepcopy(spec) store = store or {} handlers = handlers or default_handlers resolver = RefResolver(base_uri, spec, store, handlers=handlers) base_path = os.path.split(base_uri)[0] def _do_resolve(node): if isinstance(node, collections.Mapping) and '$ref' in node: ref = node['$ref'] if ref[:2] == "//": del ref[:2] path = ref.split("/") name = ref.split("#")[0] try: # resolve known references node.update(deep_get(spec, path)) del node['$ref'] return node except KeyError: # resolve external references with resolver.resolving(node['$ref']) as resolved: full_uri = os.path.join(base_path, name) if full_uri in resolver.store: external_refs[name] = str(resolver.store[full_uri]) _do_resolve(resolved) return resolved elif isinstance(node, collections.Mapping): for k, v in node.items(): node[k] = _do_resolve(v) elif isinstance(node, (list, tuple)): for i, _ in enumerate(node): node[i] = _do_resolve(node[i]) return node res = _do_resolve(spec) return res
def validate(self, instance, schema_id, skip_http=True): """ Validate an instance against a registered schema. """ schema = self[schema_id] handlers = {} if skip_http: handlers.update( http=do_not_resolve, https=do_not_resolve, ) resolver = RefResolver.from_schema( schema, store=self, handlers=handlers, ) return validate(instance, schema, resolver=resolver)
def __init__(self, host, path, version): """Api constructor. `host`: used for the schema URI. `path`: used a prefix for the route. `version`: used for the api doc `apiVersion` attribute """ if path[0] != "/": raise ValueError("path cannot be relative") self.host = host.rstrip("/") self.path = path.rstrip("/") self.version = version self.resources = {} self._schemas = {} self._resolver = RefResolver(self.schema_path, {}, store={})
def validate(self, data=None): if not data: data = self.config_dict schema_dir = "/usr/share/contrailctl/schema/" schema_path="{}/{}.json".format(schema_dir, self.component) resolver = RefResolver("file://{}/".format(schema_dir), None) try: schema=open(schema_path,'r').read() except IOError as error: print("Schema file is missing - {}".format(schema_path)) return True try: validate(data, json.loads(schema), format_checker=FormatChecker(), resolver=resolver) return True except exceptions.ValidationError as error: print(error.message) return False
class TestRefResolver(unittest.TestCase): def setUp(self): self.base_uri = "" self.referrer = {} self.store = {} self.resolver = RefResolver(self.base_uri, self.referrer, self.store) def test_it_does_not_retrieve_schema_urls_from_the_network(self): ref = Draft3Validator.META_SCHEMA["id"] with mock.patch.object(self.resolver, "resolve_remote") as remote: with self.resolver.resolving(ref) as resolved: self.assertEqual(resolved, Draft3Validator.META_SCHEMA) self.assertFalse(remote.called) def test_it_resolves_local_refs(self): ref = "#/properties/foo" self.referrer["properties"] = {"foo" : object()} with self.resolver.resolving(ref) as resolved: self.assertEqual(resolved, self.referrer["properties"]["foo"]) def test_it_retrieves_stored_refs(self): self.resolver.store["cached_ref"] = {"foo" : 12} with self.resolver.resolving("cached_ref#/foo") as resolved: self.assertEqual(resolved, 12) def test_it_retrieves_unstored_refs_via_requests(self): ref = "http://bar#baz" schema = {"baz" : 12} with mock.patch("jsonschema.requests") as requests: requests.get.return_value.json.return_value = schema with self.resolver.resolving(ref) as resolved: self.assertEqual(resolved, 12) requests.get.assert_called_once_with("http://bar") def test_it_retrieves_unstored_refs_via_urlopen(self): ref = "http://bar#baz" schema = {"baz" : 12} with mock.patch("jsonschema.requests", None): with mock.patch("jsonschema.urlopen") as urlopen: urlopen.return_value.read.return_value = ( json.dumps(schema).encode("utf8")) with self.resolver.resolving(ref) as resolved: self.assertEqual(resolved, 12) urlopen.assert_called_once_with("http://bar") def test_it_can_construct_a_base_uri_from_a_schema(self): schema = {"id" : "foo"} resolver = RefResolver.from_schema(schema) self.assertEqual(resolver.base_uri, "foo") self.assertEqual(resolver.referrer, schema) def test_it_can_construct_a_base_uri_from_a_schema_without_id(self): schema = {} resolver = RefResolver.from_schema(schema) self.assertEqual(resolver.base_uri, "") self.assertEqual(resolver.referrer, schema) def test_custom_uri_scheme_handlers(self): schema = {"foo": "bar"} ref = "foo://bar" foo_handler = mock.Mock(return_value=schema) resolver = RefResolver("", {}, handlers={"foo": foo_handler}) with resolver.resolving(ref) as resolved: self.assertEqual(resolved, schema) foo_handler.assert_called_once_with(ref) def test_cache_remote_on(self): ref = "foo://bar" foo_handler = mock.Mock() resolver = RefResolver("", {}, cache_remote=True, handlers={"foo": foo_handler}) with resolver.resolving(ref): pass with resolver.resolving(ref): pass foo_handler.assert_called_once_with(ref) def test_cache_remote_off(self): ref = "foo://bar" foo_handler = mock.Mock() resolver = RefResolver("", {}, cache_remote=False, handlers={"foo": foo_handler}) with resolver.resolving(ref): pass with resolver.resolving(ref): pass self.assertEqual(foo_handler.call_count, 2)
def setUp(self): self.referrer = {} self.store = {self.stored_uri : self.stored_schema} self.resolver = RefResolver(self.base_uri, self.referrer, self.store)
def setUp(self): self.resolver = RefResolver() self.schema = mock.MagicMock()
def resolver(self): return RefResolver.from_schema(Swagger(self).as_dict())
"type": "object", "properties": { "name": {"type": "string"}, "mean": {"$ref": '#/evaluationResult'}, "student": {"$ref": '#/evaluationResult'}, }, "required": ["name", "mean", "student"] }, "evaluationResult": { "id": "#evaluation-result", "type": "number", "minimum": -1, "maximum": 1, }, } resolver = RefResolver( _base_uri, {}, store={ '%s/schemas/education.json' % _base_uri: _education_schemas, '%s/schemas/education/portfolio.json' % _base_uri: _portfolio_schemas, } ) with resolver.resolving('schemas/education.json#student') as schema: student = Draft4Validator(schema, resolver=resolver) with resolver.resolving('schemas/education/portfolio.json#portfolio') as schema: portfolio = Draft4Validator(schema, resolver=resolver)
def setUp(self): self.base_uri = "" self.referrer = {} self.store = {} self.resolver = RefResolver(self.base_uri, self.referrer, self.store)
def refresolver(self): if not self._refresolver: self._refresolver = RefResolver.from_schema(self.__schema__) return self._refresolver
import os import re import json from jsonschema import Draft4Validator, FormatChecker, RefResolver from jsonmapping import SchemaVisitor from aleph.model.constants import COUNTRY_NAMES, LANGUAGE_NAMES from aleph.model.constants import SOURCE_CATEGORIES resolver = RefResolver('core.json#', {}) schema_dir = os.path.join(os.path.dirname(__file__), '..', 'schema') for (root, dirs, files) in os.walk(schema_dir): for schema_file in files: with open(os.path.join(root, schema_file), 'r') as fh: schema = json.load(fh) resolver.store[schema['id']] = schema format_checker = FormatChecker() # JS: '^([12]\\d{3}(-[01]?[1-9](-[0123]?[1-9])?)?)?$' date_re = re.compile('^([12]\d{3}(-[01]?[1-9](-[0123]?[1-9])?)?)?$') @format_checker.checks('country-code') def is_country_code(code): return code.lower() in COUNTRY_NAMES.keys() @format_checker.checks('partial-date')
class Api(object): """Decorator (decorator builder) for webapp2 request handler. Generate routes, schemas and the swagger api doc of an api. """ # api doc `swaggerVersion` attribute swagger_version = "1.2" def __init__(self, host, path, version): """Api constructor. `host`: used for the schema URI. `path`: used a prefix for the route. `version`: used for the api doc `apiVersion` attribute """ if path[0] != "/": raise ValueError("path cannot be relative") self.host = host.rstrip("/") self.path = path.rstrip("/") self.version = version self.resources = {} self._schemas = {} self._resolver = RefResolver(self.schema_path, {}, store={}) @property def base_path(self): return "".join([self.host, self.path]) @property def schema_path(self): return "%s/json-schemas" % self.base_path def api_doc(self): """Generate the api doc (as a dict). It generate a route documentation listing all the resources. """ return { "apiVersion": self.version, "swaggerVersion": self.swagger_version, "apis": sorted([r.summary() for r in self.resources.values()], key=operator.itemgetter("path")), } def _json_handler(self, data, status=200): resp = webapp2.Response(json.dumps(data, sort_keys=True, indent=4)) resp.headers["Content-Type"] = "application/json" resp.status = status return resp def schema_handler(self, request): """http handler for the schema request. """ return self._json_handler(self.schemas()) def api_doc_handler(self, request): """http handler for the route api-doc request. """ return self._json_handler(self.api_doc()) def apis_handler(self, request, path): """http handler for a resource api-doc request. """ resource = self.resources.get("/%s" % path, None) if resource is None: return self._json_handler({"error": "resource not found"}, 404) return self._json_handler(resource.api_doc()) def routes(self): """Return a route collection for an api (including the api-doc and schema): - the request handler routes are define by the `swagger.ApiRequestHandler.path` class attributes. - the api-doc path `<api.path>/api-docs` - the schema path `<api.path>/json-schemas/` """ rel_routes = [] rel_routes.append(webapp2.Route("/api-docs", self.api_doc_handler, methods=["GET"])) rel_routes.append(webapp2.Route("/api-docs/<path:.+>", self.apis_handler, methods=["GET"])) rel_routes.append(webapp2.Route("/json-schemas", self.schema_handler, methods=["GET"])) for resource in self.resources.itervalues(): for api in resource.apis.itervalues(): rel_routes.append(webapp2.Route(api.path, api.handler)) return routes.PathPrefixRoute(self.path, rel_routes) def resource(self, path, desc=None): """Define a new resource. """ if path not in self.resources: self.resources[path] = _Resource(self, path, desc) return self.resources[path] def schema(self, name, properties=None, additional_properties=False, **kw): """Create a new schema definition. The base schema can currently only be defined as objects (swagger only define models as object). """ properties = {} if properties is None else properties kw.setdefault("required", []) for prop_name, prop in properties.iteritems(): if prop.required: kw["required"].append(prop_name) prop.required = None definition = Object(id=name, properties=properties, additional_properties=additional_properties, **kw) self._schemas[name] = definition self._update_resolver() def schemas(self): """Json-schema for all complex type defined in an API. """ schemas = {"id": "%s#" % self.schema_path, "$schema": "http://json-schema.org/draft-04/schema#"} for s_id, s in self._schemas.iteritems(): if s is None: continue schemas[s_id] = s return to_dict(schemas, ctx=_Context(self)) def ref(self, name, required=False): """Return an object with "$ref" attribute. Suitable to be used in json schema document. Use Api.model if the reference is to be used in swagger api document. """ self._schemas.setdefault(name, None) return _Ref(name, required=required) def _update_resolver(self): self._resolver.store[self.schema_path] = self.schemas() def validate(self, schema, data): """Create json-schema validator for a complex type. """ with self._resolver.resolving("#/%s" % schema) as schema: validator = Draft4Validator(schema, resolver=self._resolver) validator.validate(data)
def validate_subschema(data, schema_selector): schema = load_schema() resolver = RefResolver.from_schema(schema) format_checker = FormatChecker() request_schema = resolver.resolve_from_url(schema_selector) validate(data, request_schema, resolver=resolver, format_checker=format_checker)
def test_it_can_construct_a_base_uri_from_a_schema(self): schema = {"id" : "foo"} resolver = RefResolver.from_schema(schema) self.assertEqual(resolver.base_uri, "foo") self.assertEqual(resolver.referrer, schema)
def test_it_can_construct_a_base_uri_from_a_schema_without_id(self): schema = {} resolver = RefResolver.from_schema(schema) self.assertEqual(resolver.base_uri, "") self.assertEqual(resolver.referrer, schema)