asdf.extension
The ~asdf.extension.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.
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 ~asdf.util.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
.
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.