The JSON Schema specification does not require the default keyword to modify the instance. To automatically populate default values into your Python objects during validation, you must extend a validator class to include a custom implementation for the properties keyword.
When implementing this, ensure that the default values themselves are valid under the schema, as they are applied before the properties are validated. Additionally, for nested objects to receive defaults, the parent object must also have a default value defined in the schema.
from jsonschema import Draft202012Validator, validators
def extend_with_default(validator_class):
validate_properties = validator_class.VALIDATORS["properties"]
def set_defaults(validator, properties, instance, schema):
for property, subschema in properties.items():
if "default" in subschema:
instance.setdefault(property, subschema["default"])
for error in validate_properties(
validator, properties, instance, schema,
):
yield error
return validators.extend(
validator_class, {"properties" : set_defaults},
)
DefaultValidatingValidator = extend_with_default(Draft202012Validator)
# Example usage:
obj = {}
schema = {'properties': {'foo': {'default': 'bar'}}}
# Note: jsonschema.validate(obj, schema, cls=DefaultValidatingValidator)
# will not work because the metaschema contains `default` keywords.
DefaultValidatingValidator(schema).validate(obj)
assert obj == {'foo': 'bar'}