При проверке jsonschema не удается разрешить ссылки на локальные файлы "внуков"
Фон: у меня есть несколько JSON-схем, ссылающихся на большие объекты. Эти объекты перемещаются в подкаталог. В приведенном ниже примере отображаются следующие зависимости:
- main_schema => positive_integer
- main_schema => дата
- date => positive_integer
- дата => месяц
Библиотека jsonschema не может разрешить только последнюю зависимость, обрабатывая все остальные штрафа.
Дерево проекта
/
+-- code.py
+-- schemas /
| +-- dependencies /
| | +-- date.json
| | +-- month.json
| | +-- positive_integer.json
| +-- main_schema.json
code.py:
из jsonschema импорт проверить импорт json
contact = \
{
"name": "William Johns",
"age": 25,
"birthDate": { "month": "apr", "day": 15 }
}
def main():
schema = json.load(open("schemas/main_schema.json"))
validate(contact, schema)
if (__name__ == '__main__'):
main()
Схемы JSON
main_schema json
{
"title": "MainSchema",
"properties":
{
"name": { "type": "string" },
"age": { "$ref": "file:schemas/dependencies/positive_integer.json" },
"birthDate": { "$ref": "file:schemas/dependencies/date.json" }
},
"additionalProperties": false
}
date.json
{
"title": "date",
"type": "object",
"properties":
{
"month": { "$ref": "file:month.json" },
"day": { "$ref": "file:positive_integer.json" }
},
"additionalProperties": false
}
month.json:
{
"title": "month",
"type": "string",
"enum": [ "jan", "feb", "mar", "apr" ]
}
positive_integer.json:
{
"title": "positiveInteger",
"type": "integer",
"minimum": 1
}
проблема
Когда я запускаю это, программа завершается с ошибкой стека трассировки:
"C:\Program Files (x86)\Python\3.6.0\python.exe" D:/Code/python/test/json_schema_testing/validator.py
Traceback (most recent call last):
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 380, in resolve_from_url
document = self.store[url]
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\_utils.py", line 23, in __getitem__
return self.store[self.normalize(uri)]
KeyError: 'file:///schemas/dependencies/month.json'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 1474, in open_local_file
stats = os.stat(localfile)
FileNotFoundError: [WinError 3] Системе не удается найти указанный путь: '\\schemas\\dependencies\\month.json'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 383, in resolve_from_url
document = self.resolve_remote(url)
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 474, in resolve_remote
result = json.loads(urlopen(uri).read().decode("utf-8"))
File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 223, in urlopen
return opener.open(url, data, timeout)
File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 526, in open
response = self._open(req, data)
File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 544, in _open
'_open', req)
File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 504, in _call_chain
result = func(*args)
File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 1452, in file_open
return self.open_local_file(req)
File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 1492, in open_local_file
raise URLError(exp)
urllib.error.URLError: <urlopen error [WinError 3] Системе не удается найти указанный путь: '\\schemas\\dependencies\\month.json'>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:/Code/python/test/json_schema_testing/validator.py", line 16, in <module>
main()
File "D:/Code/python/test/json_schema_testing/validator.py", line 13, in main
validate(contact, schema)
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 541, in validate
cls(schema, *args, **kwargs).validate(instance)
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 129, in validate
for error in self.iter_errors(*args, **kwargs):
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 105, in iter_errors
for error in errors:
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\_validators.py", line 304, in properties_draft4
schema_path=property,
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 121, in descend
for error in self.iter_errors(instance, schema):
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 105, in iter_errors
for error in errors:
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\_validators.py", line 216, in ref
for error in validator.descend(instance, resolved):
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 121, in descend
for error in self.iter_errors(instance, schema):
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 105, in iter_errors
for error in errors:
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\_validators.py", line 304, in properties_draft4
schema_path=property,
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 121, in descend
for error in self.iter_errors(instance, schema):
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 105, in iter_errors
for error in errors:
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\_validators.py", line 212, in ref
scope, resolved = validator.resolver.resolve(ref)
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 375, in resolve
return url, self._remote_cache(url)
File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 385, in resolve_from_url
raise RefResolutionError(exc)
jsonschema.exceptions.RefResolutionError: <urlopen error [WinError 3] Системе не удается найти указанный путь: '\\schemas\\dependencies\\month.json'>
(eng: System could not find such file: ...)
Process finished with exit code 1
Как я выяснил, зависимости "внуков" могут быть разрешены, только если они были предварительно загружены ранее. Таким образом, если удалить зависимость "date => month" или принудительно "предварительно загрузить" ее с уровня rool, все будет работать нормально.
Временное решение
Измените main_schema.json, чтобы он был примерно таким:
{
"title": "MainSchema",
"not":
{
"comment": "This is preload of 'grandchild' dependencies. It is required due to the jsonschema lib issues.",
"anyOf":
[
{ "$ref": "file:schemas/dependencies/month.json" },
{ "$ref": "file:schemas/dependencies/date.json" },
{ "$ref": "file:schemas/dependencies/positive_integer.json" }
]
},
"properties":
{
"name": { "type": "string" },
"age": { "$ref": "file:schemas/dependencies/positive_integer.json" },
"birthDate": { "$ref": "file:schemas/dependencies/date.json" }
},
"additionalProperties": false
}
Если это сделать, проверка будет успешной. Однако мне действительно не нравится этот обходной путь. Если есть идеи как это исправить, подскажите пожалуйста.
Системная информация:
- Windows 7
- Python 3.6.0
- jsonschema 2.6.0