Search code examples
pythonip-addressjsonschema

JSON Schema validating ip-address is not working


Failed to validate ip address in one dict, file API.json is as follows:

{
"$schema": "http://json-schema.org/draft-03/schema#",
"title": "test",
"type": "object",
"properties": {
    "type": {"enum": ["spice", "vnc"]},
    "listen": {
        "type": "string",
        "oneOf": [
            {"format": "ipv4"},
            {"format": "ipv6"}
        ]
    }
},
"additionalProperties": false
}

Codes are as follows:

from jsonschema import Draft3Validator, ValidationError, FormatChecker
import json

if __name__ == '__main__':
    graphics1 = {'type': 'spice', 'listen': '0.0.0.0'}
    graphics2 = {'type': 'vnc', 'listen': '0.0.0.0'}
    graphics3 = {'type': 'abc', 'listen': '0.0.0.0'}
    graphics4 = {'type': 'vnc', 'listen': '777.485.999'}
    graphics5 = {'type': 'vnc', 'listen': 'fe00::0'}
    graphics6 = {'type': 'vnc', 'listen': 'def'}
    graphics7 = {'type': 'vnc', 'listen': 'fe00::0abcdefdefs'}
    s = json.load(open('API.json'))
    validator = Draft3Validator(s, format_checker=FormatChecker())
    for x in range(1, 8):
        try:
            graphics = locals().get('graphics'+str(x))
            validator.validate(graphics)
        except ValidationError:
            print('; '.join(e.message for e in validator.iter_errors(graphics)))

And the prints are these:

'abc' is not one of [u'spice', u'vnc']

Obviously, '777.485.999' ,'def', and 'fe00::0abcdefdefs' are not ip addresses, but the test script doesn't give warnings about them. I found one doc(https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-03) which says about 'ip-address', but not 'ipv4', but it doesn't work either.

[EDIT]: I have Added FormatChecker() for Draft3Validator, but it still isn't working. But as i tried, Draft4Validator is ok. In the doc, i don't find Draft3Valdator not supporting format/ip-address anywhere, it should work.


Solution

  • Got it, it's not because Draft3Validator doesn't support "format/ip-address", but "oneOf", "allOf", "anyOf" and "not". So the API.json should be:

    {
    "$schema": "http://json-schema.org/draft-03/schema#",
    "title": "test",
    "type": "object",
    "properties": {
        "type": {"enum": ["spice", "vnc"]},
        "listen": {
            "type": "string",
            "format": "ip-address"
        }
    },   
    "additionalProperties": false
    }
    

    See http://json-schema.org/draft-03/schema# and http://json-schema.org/draft-04/schema#