При проверке jsonschema не удается разрешить ссылки на локальные файлы "внуков"

Фон: у меня есть несколько JSON-схем, ссылающихся на большие объекты. Эти объекты перемещаются в подкаталог. В приведенном ниже примере отображаются следующие зависимости:

  1. main_schema => positive_integer
  2. main_schema => дата
  3. date => positive_integer
  4. дата => месяц

Библиотека 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

0 ответов

Другие вопросы по тегам