Как настроить локальные ссылки на файлы в документе python-jsonschema? - PullRequest
0 голосов
/ 29 декабря 2018

У меня есть набор jsonschema совместимых документов.Некоторые документы содержат ссылки на другие документы (через атрибут $ref).Я не хочу размещать эти документы так, чтобы они были доступны по HTTP URI.Таким образом, все ссылки являются относительными.Все документы живут в локальной структуре папок.

Как я могу python-jsonschema понять, как правильно использовать мою локальную файловую систему для загрузки ссылочных документов?


Например, если у меня есть документ симя файла defs.json, содержащее некоторые определения.И я пытаюсь загрузить другой документ, который ссылается на него, например:

{
  "allOf": [
    {"$ref":"defs.json#/definitions/basic_event"},
    {
      "type": "object",
      "properties": {
        "action": {
          "type": "string",
          "enum": ["page_load"]
        }
      },
      "required": ["action"]
    }
  ]
}

Я получаю сообщение об ошибке RefResolutionError: <urlopen error [Errno 2] No such file or directory: '/defs.json'>

Может быть важно, чтобы я работал в Linux.


(Я пишу это как вопросы и ответы, потому что мне было трудно понять это и заметил, что у других людей тоже возникли проблемы .)

1 Ответ

0 голосов
/ 29 декабря 2018

Вы должны создать пользовательский jsonschema.RefResolver для каждой схемы, которая использует относительную ссылку, и убедиться, что ваш распознаватель знает, где в файловой системе живет данная схема.

Например, ...

import os
import json
from jsonschema import Draft4Validator, RefResolver # We prefer Draft7, but jsonschema 3.0 is still in alpha as of this writing 


abs_path_to_schema = '/path/to/schema-doc-foobar.json'
with open(abs_path_to_schema, 'r') as fp:
  schema = json.load(fp)

resolver = RefResolver(
  # The key part is here where we build a custom RefResolver 
  # and tell it where *this* schema lives in the filesystem
  # Note that `file:` is for unix systems
  schema_path='file:{}'.format(abs_path_to_schema),
  schema=schema
)
Draft4Validator.check_schema(schema) # Unnecessary but a good idea
validator = Draft4Validator(schema, resolver=resolver, format_checker=None)

# Then you can...
data_to_validate = `{...}`
validator.validate(data_to_validate)
...