Metadata¶
Validators in Koda Validate naturally forms into graph structures, usually
trees (a notable exception would be the use of Lazy, which can create cycles). It is an
aim of this library to facilitate the re-purposing of such validation structures for other
purposes, such as schemas, HTML, documentation, customized error types, and so on.
Because it’s easy to branch on the type of a Validator, it’s straightforward to
write functions that transform arbitrary Validators into other structures.
Some examples of this exist within Koda Validate:
to_json_schemaconvertsValidators into JSON Schema objectsto_serializable_errsconvertsInvalidobjects in human-readable serializable structures (discussed in Errors)koda_validate.signature._get_arg_fail_messageconvertsInvalidobjects to human-readable traceback messages.
Pattern Matching¶
The recommended approach to branching on validation graphs is to use pattern matching
against the type of Validator. For example, if you wanted to generate a markdown description
from a Validator, you could start with something like this:
from typing import Union, Any
from koda_validate import (Validator, Predicate, PredicateAsync,
ListValidator, StringValidator)
def to_markdown_description(obj: Union[Validator[Any],
Predicate[Any],
PredicateAsync[Any]]) -> str:
match obj:
case StringValidator():
return "string validator"
case ListValidator(item_validator):
return f"list validator\n- {to_markdown_description(item_validator)}"
case _:
...
print(to_markdown_description(ListValidator(StringValidator())))
Outputs:
list validator
- string validator
Here we generated a very simple output with code that supports a tiny subset of
Validators, but it’s easy to expand the same approach to produce arbitrary
outputs for a wide range of validators.