how to use $ref from a definitions.json file (python code)
yuzhujiutian opened this issue · 1 comments
yuzhujiutian commented
in document: https://json-schema.org/understanding-json-schema/structuring.html
one line write:
$ref can also be a relative or absolute URI, so if you prefer to include your definitions in separate files, you can also do that. For example:
{ "$ref": "definitions.json#/address" }
My exercise code is as follows: (environment: jupyter lab, python 3.7)
- definitions.json
{
"address": {
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"city": {
"type": "string"
},
"state": {
"type": "string"
}
},
"required": [
"street_address",
"city",
"state"
]
}
}
- python code
from jsonschema import validate
from jsonschema.validators import Draft7Validator
from jsonschema.exceptions import ValidationError, SchemaError
# https://json-schema.org/understanding-json-schema/UnderstandingJSONSchema.pdf -> 5.1 Reuse
# Description: definitions can be defined before or after properties.
sch = {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"billing_address": {
"$ref": "#/definitions/address"
},
"shipping_address": {
"$ref": "#/definitions/address"
}
},
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"city": {
"type": "string"
},
"state": {
"type": "string"
}
},
"required": [
"street_address",
"city",
"state"
]
}
}
}
sch2 = {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"billing_address": {
"$ref": "definitions.json#/address"
},
"shipping_address": {
"$ref": "definitions.json#/address"
}
}
}
ins = {
"shipping_address": {
"street_address": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC"
},
"billing_address": {
"street_address": "1st Street SE",
"city": "Washington",
"state": "DC"
}
}
# case 1, OK
validator = Draft7Validator(schema = sch)
tmp = validator.validate(instance = ins)
print(tmp)
# case 2, NOK
validator = Draft7Validator(schema = sch2)
tmp = validator.validate(instance = ins)
print(tmp)
- run case 2, but error
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\validators.py in resolve_from_url(self, url)
773 try:
--> 774 document = self.store[url]
775 except KeyError:
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\_utils.py in __getitem__(self, uri)
21 def __getitem__(self, uri):
---> 22 return self.store[self.normalize(uri)]
23
KeyError: 'definitions.json'
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call last)
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\validators.py in resolve_from_url(self, url)
776 try:
--> 777 document = self.resolve_remote(url)
778 except Exception as exc:
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\validators.py in resolve_remote(self, uri)
862 # Otherwise, pass off to urllib and assume utf-8
--> 863 with urlopen(uri) as url:
864 result = json.loads(url.read().decode("utf-8"))
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\urllib\request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
221 opener = _opener
--> 222 return opener.open(url, data, timeout)
223
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\urllib\request.py in open(self, fullurl, data, timeout)
509 if isinstance(fullurl, str):
--> 510 req = Request(fullurl, data)
511 else:
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\urllib\request.py in __init__(self, url, data, headers, origin_req_host, unverifiable, method)
327 method=None):
--> 328 self.full_url = url
329 self.headers = {}
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\urllib\request.py in full_url(self, url)
353 self._full_url, self.fragment = splittag(self._full_url)
--> 354 self._parse()
355
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\urllib\request.py in _parse(self)
382 if self.type is None:
--> 383 raise ValueError("unknown url type: %r" % self.full_url)
384 self.host, self.selector = splithost(rest)
ValueError: unknown url type: 'definitions.json'
During handling of the above exception, another exception occurred:
RefResolutionError Traceback (most recent call last)
<ipython-input-1-42ea6f09d3f9> in <module>
73
74 validator = Draft7Validator(schema = sch2)
---> 75 tmp = validator.validate(instance = ins)
76 print(tmp)
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\validators.py in validate(self, *args, **kwargs)
350
351 def validate(self, *args, **kwargs):
--> 352 for error in self.iter_errors(*args, **kwargs):
353 raise error
354
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\validators.py in iter_errors(self, instance, _schema)
326
327 errors = validator(self, v, instance, _schema) or ()
--> 328 for error in errors:
329 # set details if not already set by the called fn
330 error._set(
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\_validators.py in properties(validator, properties, instance, schema)
284 subschema,
285 path=property,
--> 286 schema_path=property,
287 ):
288 yield error
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\validators.py in descend(self, instance, schema, path, schema_path)
342
343 def descend(self, instance, schema, path=None, schema_path=None):
--> 344 for error in self.iter_errors(instance, schema):
345 if path is not None:
346 error.path.appendleft(path)
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\validators.py in iter_errors(self, instance, _schema)
326
327 errors = validator(self, v, instance, _schema) or ()
--> 328 for error in errors:
329 # set details if not already set by the called fn
330 error._set(
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\_validators.py in ref(validator, ref, instance, schema)
257 yield error
258 else:
--> 259 scope, resolved = validator.resolver.resolve(ref)
260 validator.resolver.push_scope(scope)
261
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\validators.py in resolve(self, ref)
764 """
765 url = self._urljoin_cache(self.resolution_scope, ref)
--> 766 return url, self._remote_cache(url)
767
768 def resolve_from_url(self, url):
D:\winusr\anaconda\anaconda3_201910\envs\wanmore\lib\site-packages\jsonschema\validators.py in resolve_from_url(self, url)
777 document = self.resolve_remote(url)
778 except Exception as exc:
--> 779 raise exceptions.RefResolutionError(exc)
780
781 return self.resolve_fragment(document, fragment)
RefResolutionError: unknown url type: 'definitions.json'
Julian commented
Hi -- sorry you're having trouble.
Come talk to us on the JSON Schema Slack and someone will likely try and help, or otherwise perhaps give StackOverflow a shot as well if you're more comfortable there.
This repository though is one for the JSON Schema website, and specifically for issues or feature requests for it, not general JSON Schema questions.
Someone in one of the other more suitable forums for questions will likely be happy to help though!
