Validators

The Validator interface provides support for a custom ASDF schema property. The Validator identifies the schema property and tag(s) that it works on and provides a method for doing the work of validation.

The Validator interface

Every Validator implementation must provide two required properties and one required method:

Validator.schema_property - The schema property that triggers this validator. The property need not be globally unique, but it should be unique among the validators that apply to the tag(s), and must not collide with any of the built-in JSON schema properties (type, additionalProperties, etc).

Validator.tags - a list of tag URIs or URI patterns handled by the validator. Patterns may include the wildcard character *, which matches any sequence of characters up to a /, or **, which matches any sequence of characters. The uri_match method can be used to test URI patterns.

Validator.validate - a method that accepts the schema property value, a tagged ASDF node, and the surrounding schema dict, and performs validation on the node. For every error present, the method should yield an instance of asdf.exceptions.ValidationError.

A simple example

Say we have a custom tagged object, asdf://example.com/example-project/tags/rectangle-1.0.0, which describes a rectangle with width and height properties. Let’s implement a validator that checks that the area of the rectangle is less than some maximum value.

The schema property will be called max_area, so our validator will look like this:

from asdf.extension import Validator
from asdf.exceptions import ValidationError


class MaxAreaValidator(Validator):
    schema_property = "max_area"
    tags = ["asdf://example.com/example-project/tags/rectangle-1.0.0"]

    def validate(self, max_area, node, schema):
        area = node["width"] * node["height"]
        if area > max_area:
            yield ValidationError(
                f"Rectangle with area {area} exceeds max area of {max_area}"
            )

Note that the validator operates on raw ASDF tagged nodes, and not the custom Python object that they’ll be converted to.

In order to use this Validator, we’ll need to create a simple extension around it and install that extension:

import asdf
from asdf.extension import Extension


class ShapesExtension(Extension):
    extension_uri = "asdf://example.com/shapes/extensions/shapes-1.0.0"
    validators = [MaxAreaValidator()]
    tags = ["asdf://example.com/shapes/tags/rectangle-1.0.0"]


asdf.get_config().add_extension(ShapesExtension())

Now we can include a max_area property in a schema and have it restrict the area of a rectangle.