我们如何使用jsonschema.RefResolver验证模式中的多个引用?
我有一个验证脚本,如果我在文件中有一个引用,它会很好用。我现在在模式中有两个或三个refs,它们位于不同的目录中。
base_dir = '/schema/models/'
with open (os.path.join(base_dir, 'Defined.json')) as file_object:
schema = json.load(file_object)
resolver = jsonschema.RefResolver('file://' + base_dir + '/' + 'Fields/Ranges.json', schema)
jsonschema.Draft4Validator(schema, resolver=resolver).validate(data)
我的json架构:
{
"properties": {
"description": {
"type": "object",
"after": {"type": ["string", "null"]},
"before": {"type": "string"}
},
"width": {"type": "number"} ,
"range_specifier": {"type": "string"},
"start": {"type": "number", "enum" : [0, 1] } ,
"ranges": {
"$ref": "Fields/Ranges.json"
},
"values": {
"$ref": "Fields/Values.json"
}
}
}
所以我的问题是我应该有两个解析器一个用于范围,一个用于值并在Draft4Validator中单独调用解析器吗?或者有更好的方法吗?
答案 0 :(得分:1)
我自己花了几个小时处理同一个问题,所以我希望这个解决方法对其他人有用
def validate(schema_search_path, json_data, schema_id):
"""
load the json file and validate against loaded schema
"""
try:
schemastore = {}
schema = None
fnames = os.listdir(schema_search_path)
for fname in fnames:
fpath = os.path.join(schema_search_path, fname)
if fpath[-5:] == ".json":
with open(fpath, "r") as schema_fd:
schema = json.load(schema_fd)
if "id" in schema:
schemastore[schema["id"]] = schema
schema = schemastore.get("http://mydomain/json-schema/%s" % schema_id)
Draft4Validator.check_schema()
resolver = RefResolver("file://%s.json" % os.path.join(schema_search_path, schema_id), schema, schemastore)
Draft4Validator(schema, resolver=resolver).validate(json_data)
return True
except ValidationError as error:
# handle validation error
pass
except SchemaError as error:
# handle schema error
pass
return False
应在路径解析中使用的每个JSON模式都有一个ID元素,必须将其传递给验证为 schema_id 参数
"id": "http://mydomain/json-schema/myid"
所有架构都加载到dict中,然后作为存储传递给解析器。在您的示例中,您还应该从其他目录加载架构。
答案 1 :(得分:0)
我将整个架构存储在Python包根目录中名为api-spec.yaml
的YAML文件中。 YAML文件符合Swagger 3.0。重新构建该示例以验证根模式中描述的任何对象应该是微不足道的。
注意:此示例要求您从命令行执行以下命令:
pip install pyyaml, jsonschema
在名为cn
的软件包中,YAML文件已加载到__init__.py
中:
import yaml, os
__all__ = ['api_swagger']
with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'api-spec.yaml')) as file:
api_swagger = yaml.load(file, Loader=yaml.SafeLoader)
这是Python单元测试中的一些示例代码:
import unittest
from cn import api_swagger
class ValidateSwaggerSchema_Tests(unittest.TestCase):
def test_validation_using_jsonschema_RefResolver___should_pass(self):
# setup
from cn import api_swagger
schemastore = {
'': api_swagger,
}
resolver = jsonschema.RefResolver(
base_uri='',
referrer=api_swagger,
store=schemastore)
# setup: the schemas used when validating the data
ParsedMessageSchema = api_swagger['components']['schemas']['ParsedMessage']
FillSchema = api_swagger['components']['schemas']['Fill']
# validate: ParsedMessageSchema
validator = jsonschema.Draft7Validator(ParsedMessageSchema, resolver=resolver)
validator.validate({
'type': 'fill',
'data': [{
'order_id': 'a_unique_order_id',
'exchange_id': 'bittrex',
'market_id': 'USD-BTC',
'side': 'sell',
'price': 11167.01199693,
'amount': 0.00089773,
'type': 'limit',
'status': 'filled',
'leaves_amount': 0.0,
'cumulative_amount': 0.00089773,
'timestamp': '2019-07-13T20:17:01.480000',
}]
})
# validate: FillSchema
validator = jsonschema.Draft7Validator(FillSchema, resolver=resolver)
validator.validate(
{
'order_id': 'a_unique_order_id',
'exchange_id': 'bittrex',
'market_id': 'USD-BTC',
'side': 'sell',
'price': 11167.01199693,
'amount': 0.00089773,
'type': 'limit',
'status': 'filled',
'leaves_amount': 0.0,
'cumulative_amount': 0.00089773,
'timestamp': '2019-07-13T20:17:01.480000',
}
)
答案 2 :(得分:0)
您可以使用python库“ pyjn” (点安装pyjn) 并分三行进行。
from pyjn import pyjn
pyjn=pyjn()
json_pathtest='C:/Users/Entity.json'
print(pyjn.refsolver(json_pathtest))