Validators#

In Koda Validate, Validator is the fundamental validation building block. It’s based on the idea that any kind of data validation can be represented by a Callable signature like this:

ValidType = TypeVar("ValidType")

Callable[[Any], Union[Valid[ValidType], Invalid]]

In Koda Validate we can abbreviate this with the ValidationResult type alias to:

Callable[[Any], ValidationResult[ValidType]]

The way we actually represent this concept in Koda Validate is even simpler:

Validator[ValidType]

Note

There are a few differences between Validator[ValidType] and Callable[[Any], ValidationResult[ValidType]] that make them not exactly equivalent:

  • Validators are always subclasses of Validator. Using callable classes (instead of functions) makes it easy to branch on validators based on their class name.

  • Validators have a validate_async method, which allows them to be used in both sync and async contexts.

In sum, a Validator[ValidType] can be used in places where Callable[[Any], ValidationResult[ValidType]] is required, but Validator[ValidType] is fundamentally a richer type.

We can see in the following example how Validators act like simple functions which return either Valid[ValidType] or Invalid:

from koda_validate import IntValidator

int_validator = IntValidator()

Usage:

>>> int_validator(5)
Valid(val=5)

>>> int_validator("not an integer")
Invalid(err_type=TypeErr(expected_type=<class 'int'>), ...)

Having this simple function signature-based definition for validation is useful, because it means we can compose validators. Perhaps the simplest example of this is how ListValidator accepts a validator for the items of the list:

from koda_validate import ListValidator, StringValidator

list_str_validator = ListValidator(StringValidator())

Usage:

>>> list_str_validator(["ok", "nice"])
Valid(val=['ok', 'nice'])

>>> list_str_validator([1,2,3])
Invalid(...)

Since Validators are essentially functions (packaged as classes), they are flexible and easy to write. Take a look at Extension to see how.