Metadata#
Validator
s 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 Validator
s into other structures.
Some examples of this exist within Koda Validate:
to_json_schema
convertsValidator
s into JSON Schema objectsto_serializable_errs
convertsInvalid
objects in human-readable serializable structures (discussed in Errors)koda_validate.signature._get_arg_fail_message
convertsInvalid
objects 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
Validator
s, but it’s easy to expand the same approach to produce arbitrary
outputs for a wide range of validators.