简体   繁体   中英

Python jsonschema not validating on required property from ref file

I am trying to validate a JSON schema using python jsonschema using a "$ref" that points to an external file. My issue is that the "required" properties in the external file are not failing validation when they are not present in the request. Based on the info below, I would have expected my request to fail because 'ofld2' is missing. If I omit any of the required fields from the parent schema, it fails properly. Any help/guidance would be greatly appreciated.

Parent Json File: test_refs.json:

{
    "test_refs":{
            "schema": {
                "allOf": [
                    {
                    "type": "object",
                    "properties": {
                        "fld1": {
                            "type": "string"
                        },
                        "fld2": {
                            "type": "string"
                        },
                        "fld3": {
                            "type": "string"
                        },
                        "ref1": { 
                            "$ref":"myref.json"
                        }
                    },
                    "required": ["fld1", "fld2", "fld3", "ref1"]
                    }
                ]
            }
        }
}

Reference Json file:

{
    "myrefs": {
        "schema": {
            "$schema": "http://json-schema.org/draft-04/schema#",
            "id":"myref",
            "type": "object",
            "properties": {
                "ofld1": {"type": "string"},
                "ofld2": {"type": "string"},
                "ofld3": {"type": "string"}
            },
            "required": ["ofld1", "ofld2"]
        }
    }
}

My validation logic:

 req_schema = resource_config.get("schema", {})
 schema = jsonschema.Draft4Validator(req_schema)
 try:
    json_content = jsonref.loads(content)
 except Exception as error:
    is_valid = False
    log.error(error)
    myerrors.append("EXCEPTION Error: invalid message payload.")

Request Data:

{'fld1': '10.0', 'fld2': '10.0', 'fld3': 'test', 'ref1': {'ofld1': 'test 1', 'ofld3': 'test  3'}}

Schema:

{
    'schema': {
    'allOf': [
        {'type': 'object', 
        'properties': 
            {'fld1': {'type': 'string'}, 
            'fld2': {'type': 'string'},
            'fld3': {'type': 'string'}, 
            'ref1': {
                'myrefs': {
                    'schema': {
                        '$schema': 'http://json-schema.org/draft-04/schema#', 
                        'id': 'myref', 
                        'type': 'object', 
                        'properties': {
                            'ofld1': {'type': 'string'}, 
                            'ofld2': {'type': 'string'}, 
                            'ofld3': {'type': 'string'}
                         }, 
                        'required': ['ofld1', 'ofld2']}
                        }
                    }
                }, 
            'required': ['fld1', 'fld2', 'fld3', 'ref1']}
            ]
        }, 
        'resolver': <jsonschema.validators.    RefResolver object at 0xb0e4526c>, 'format_checker': None}

UPDATE: Here is a test script that produces this output using the files:

import json
import jsonref
import jsonschema
import logging
from os.path import dirname
from jsonschema import validate



def read_json_file(file_path):
    """Reads the file at the file_path and returns the contents.
        Returns:
            json_content: Contents of the json file

        """
    try:
        json_content_file = open(file_path, 'r')
    except IOError as error:
        print(error)

    else:
        try:
            base_path = dirname(file_path)
            base_uri = 'file://{}/'.format(base_path)
            json_schema = jsonref.load(json_content_file, base_uri=base_uri, jsonschema=True)
        except (ValueError, KeyError) as error:
            print(file_path)
            print(error)

        json_content_file.close()

    return json_schema

def validate_json_file(json_data):
    req_schema = read_json_file('/path/to/json/files/test_refs.json')
    print("SCHEMA --> "+str(req_schema))
    try:
        validate(instance=json_data, schema=req_schema)
    except jsonschema.exceptions.ValidationError as err:
        print(err)
        err = "Given JSON data is InValid"
        return False, err

    message = "Given JSON data is Valid"
    return True, message


jsonData = jsonref.loads('{"fld1": "10.0", "fld2": "10.0", "fld3": "test", "ref1": {"ofld1": "test 1", "ofld3": "test  3"}}')
is_valid, msg = validate_json_file(jsonData)
print(msg)

Your schema is malformed. Everything under /schema/allOf/0/properties/ref1 is not a valid schema, so it is all ignored. You should lift the embedded schema up multiple levels and place it right under ref1.

The first two schemas you included aren't referenced anywhere; are they just intended to be copies of the schema you created where everything is embedded?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM