The correct way to use format checker is mentioned in the document.[Julian has already mentioned that]
from jsonschema import Draft3Validator, ValidationError, draft3_format_checker
my_schema = {
"$schema": "http://json-schema.org/draft-03/schema#",
"title": "test",
"type": "object",
"properties": {
"listen": {
"type": "string",
"format": 'ip-address'
},
"type": {"enum": ["spice", "vnc"]}
},
"additionalProperties": False
}
if __name__ == '__main__':
graphics1 = {'type': 'spice', 'listen': 'def'}
graphics2 = {'type': 'vnc', 'listen': '127.0.0.1'}
validator = Draft3Validator(my_schema, format_checker=draft3_format_checker)
for x in range(1, 3):
try:
graphics = locals().get('graphics'+str(x))
validator.validate(graphics)
except ValidationError:
print('; '.join(e.message for e in validator.iter_errors(graphics)))
Output:
'def' is not a 'ip-address'
Next when you are using format
you can just use format
keyword I mean without type
keyword. source look at example in this doc and format section of this doc,
my_schema = {
"$schema": "http://json-schema.org/draft-03/schema#",
"title": "test",
"type": "object",
"properties": {
"listen": {
"format": 'ip-address'
},
"type": {"enum": ["spice", "vnc"]}
},
"additionalProperties": False
}
From your question it looks like you are trying to check both IPv4 and IPv6 but if you go with schema format: 'ip-address
only IPv4 are validated.
from jsonschema import Draft3Validator, ValidationError, draft3_format_checker
my_schema = {
"$schema": "http://json-schema.org/draft-03/schema#",
"title": "test",
"type": "object",
"properties": {
"listen": {
"format": 'ip-address'
},
"type": {"enum": ["spice", "vnc"]}
},
"additionalProperties": False
}
if __name__ == '__main__':
graphics1 = {'type': 'spice', 'listen': 'def'}
graphics2 = {'type': 'vnc', 'listen': '127.0.0.1'}
graphics3 = {'type': 'vnc', 'listen': '::1'} # IPV6 localhost
validator = Draft3Validator(my_schema, format_checker=draft3_format_checker)
for x in range(1, 4):
try:
graphics = locals().get('graphics'+str(x))
validator.validate(graphics)
except ValidationError:
print('; '.join(e.message for e in validator.iter_errors(graphics)))
Output:
'def' is not a 'ip-address'
'::1' is not a 'ip-address'
Now if you want to check both IPv4 and IPv6 with Draft7(Since the question is old and Draft7 its new have many other options as well). Here is the revised code with handles both IPv4/v6, error.
from jsonschema import draft7_format_checker, Draft7Validator
my_schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "test",
"type": "object",
"properties": {
"listen": {
'oneOf': [
{"format": 'ipv4'},
{"format": 'ipv6'},
],
},
"type": {"enum": ["spice", "vnc"]}
},
"additionalProperties": False
}
if __name__ == '__main__':
test_list = [{'type': 'spice', 'listen': 'def'}, {'type': 'vnc', 'listen': '127.0.0.1'},{'type': 'vnc', 'listen': '::1'}]
validator = Draft7Validator(my_schema, format_checker=draft7_format_checker)
for my_json in test_list:
errors = validator.iter_errors(my_json)
for i, error in enumerate(errors):
print(error.message)
# # If you want to see more detail cause of each error use this
# # the ValidationError.context attribute can be used to see the sub-errors which caused the failure
# for i, error in enumerate(errors):
# for suberror in sorted(error.context, key=lambda e: e.schema_path):
# print(list(suberror.relative_schema_path), suberror.message, sep=", ")
Output:
'def' is not valid under any of the given schemas
and sample output of detail output(which is commented in above snippet)
[0, 'format'], 'def' is not a 'ipv4'
[1, 'format'], 'def' is not a 'ipv6'
error.context
: If the error was caused by errors in subschemas, the list of errors from the subschemas will be available on this property. The schema_path and path of these errors will be relative to the parent error.
Reference: https://python-jsonschema.readthedocs.io/en/stable/errors/