koda_validate#

class AlwaysValid#

Whatever value is submitted for validation will be returned as valid

class BoolValidator(*predicates, predicates_async=None, preprocessors=None, coerce=None)#

Validate a value is a bool, and any extra refinement.

If predicates_async is supplied, the __call__ method should not be called – only .validate_async should be used.

Parameters:
  • predicates (Predicate[TypeVar(SuccessT)]) – any number of Predicate[bool] instances

  • predicates_async (Optional[List[PredicateAsync[TypeVar(SuccessT)]]], default: None) – any number of PredicateAsync[bool] instances

  • preprocessors (Optional[List[Processor[TypeVar(SuccessT)]]], default: None) – any number of Processor[bool], which will be run before Predicates and PredicateAsyncs are checked.

  • coerce (Optional[Coercer[TypeVar(SuccessT)]], default: None) – a function that can control coercion

class BytesValidator(*predicates, predicates_async=None, preprocessors=None, coerce=None)#

Validate a value is a bytes, and any extra refinement.

If predicates_async is supplied, the __call__ method should not be called – only .validate_async should be used.

Example:

>>> from koda_validate import *
>>> validator = BytesValidator(not_blank, MaxLength(100), preprocessors=[strip])
>>> validator(b"")
Invalid(err_type=PredicateErrs(predicates=[NotBlank()]), ...)
>>> validator("")
Invalid(err_type=TypeErr(expected_type=<class 'bytes'>), ...)
>>> validator(b' ok ')
Valid(val=b'ok')
Parameters:
  • predicates (Predicate[TypeVar(SuccessT)]) – any number of Predicate[bytes] instances

  • predicates_async (Optional[List[PredicateAsync[TypeVar(SuccessT)]]], default: None) – any number of PredicateAsync[bytes] instances

  • preprocessors (Optional[List[Processor[TypeVar(SuccessT)]]], default: None) – any number of Processor[bytes], which will be run before Predicates and PredicateAsyncs are checked.

  • coerce (Optional[Coercer[TypeVar(SuccessT)]], default: None) – a function that can control coercion

class CacheValidatorBase(validator)#

This class should be subclassed to work with whatever caching configuration is desired

__call__(val)#
Parameters:

val (Any) – the value being validated

Return type:

Union[Valid[TypeVar(A)], Invalid]

async cache_get_async(val)#

Try to get a value from a cache asynchronously and return Maybe[ValidationResult[A]]

Parameters:

val (Any) – the value being validated

Return type:

Union[Just[Union[Valid[TypeVar(A)], Invalid]], Nothing]

cache_get_sync(val)#

Try to get a value from a cache and return Maybe[ValidationResult[A]]

Parameters:

val (Any) – the value being validated

Return type:

Union[Just[Union[Valid[TypeVar(A)], Invalid]], Nothing]

async cache_set_async(val, cache_val)#
Return type:

None

cache_set_sync(val, cache_val)#
Return type:

None

async validate_async(val)#
Parameters:

val (Any) – the value being validated

Return type:

Union[Valid[TypeVar(A)], Invalid]

validator#
class Choices(choices)#

A allow to check some Hashable type against a finite set of values.

__call__(val)#
Parameters:

val (TypeVar(ChoiceT, bound= Hashable)) – the value being validated

Return type:

bool

choices#
class Coercer(coerce, compatible_types)#
__call__(val)#

Call self as a function.

Return type:

Union[Just[TypeVar(A)], Nothing]

coerce#

The function which handles the coercion.

compatible_types#

All the types which can potentially be coerced.

class CoercionErr(compatible_types, dest_type)#

Similar to a TypeErr, but when one or more types can be coerced to a destination type

compatible_types#
dest_type#
class ContainerErr(child)#

This is for simple containers like Maybe or Result

child#
class DataclassValidator(data_cls, *, overrides=None, validate_object=None, validate_object_async=None, fail_on_unknown_keys=False, typehint_resolver=<function get_typehint_validator>, coerce=None)#

Takes a dataclass as an argument and derives a Validator. Will validate against an instance of self.data_cls or a dictionary. Regardless of the input type, the result will be an instance of type self.data_cls.

Optional keys are determined by the presence of a default argument.

Example:

from dataclasses import dataclass
from typing import List
from koda_validate import *

@dataclass
class Person:
    name: str
    hobbies: List[str]

validator = DataclassValidator(Person)

Usage:

>>> validator({"name": "Bob", "hobbies": ["eating", "coding", "sleeping"]})
Valid(val=Person(name='Bob', hobbies=['eating', 'coding', 'sleeping']))
Parameters:
  • data_cls (Type[TypeVar(_DCT, bound= DataclassLike)]) – A dataclass class

  • overrides (Optional[Dict[str, Validator[Any]]], default: None) – a dict whose keys define explicit validators

  • validate_object (Optional[Callable[[TypeVar(_DCT, bound= DataclassLike)], Union[CoercionErr, ContainerErr, ExtraKeysErr, IndexErrs, KeyErrs, MapErr, MissingKeyErr, PredicateErrs[Any], SetErrs, TypeErr, ValidationErrBase, UnionErrs, None]]], default: None) – is run if all keys have been validated individually. If it returns None, then there were no errors; otherwise it should return ErrType

  • validate_object_async (Optional[Callable[[TypeVar(_DCT, bound= DataclassLike)], Awaitable[Union[CoercionErr, ContainerErr, ExtraKeysErr, IndexErrs, KeyErrs, MapErr, MissingKeyErr, PredicateErrs[Any], SetErrs, TypeErr, ValidationErrBase, UnionErrs, None]]]], default: None) – same as validate_object, except that is runs asynchronously

  • typehint_resolver (Callable[[Any], Validator[Any]], default: <function get_typehint_validator at 0x7fa8194d2c00>) – define this to override default inferred validators for types

  • fail_on_unknown_keys (bool, default: False) – if True, this will fail if any keys not defined by self.data_cls are found. This will fail before any values are validated.

  • coerce (Optional[Coercer[Dict[Any, Any]]], default: None) – a function that can control coercion

Raises:

TypeError – should raise if non-dataclass type is passed for data_cls

class DateValidator(*predicates, predicates_async=None, preprocessors=None, coerce=Coercer(coerce=<function coerce_date>, compatible_types={<class 'str'>, <class 'datetime.date'>}))#
class DatetimeValidator(*predicates, predicates_async=None, preprocessors=None, coerce=Coercer(coerce=<function coerce_datetime>, compatible_types={<class 'datetime.datetime'>, <class 'str'>}))#
class DecimalValidator(*predicates, predicates_async=None, preprocessors=None, coerce=Coercer(coerce=<function coerce_decimal>, compatible_types={<class 'int'>, <class 'str'>, <class 'decimal.Decimal'>}))#
class DictValidatorAny(schema, *, validate_object=None, validate_object_async=None, fail_on_unknown_keys=False)#

This class exists for a few reasons:

  • it can handle an arbitrary amount of keys, of any combination of hashable types

  • it’s initialization is very straightforward

The big caveat is that a valid result is always typed as Dict[Any, Any], even though the validation will work just as well as with any other Validator

class EmailPredicate(pattern=re.compile('[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\\\.[a-zA-Z0-9-.]+'))#
__call__(val)#
Parameters:

val (str) – the value being validated

Return type:

bool

pattern = re.compile('[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+')#
class EndsWith(suffix)#
__call__(val)#
Parameters:

val (TypeVar(StrOrBytes, str, bytes)) – the value being validated

Return type:

bool

suffix#
class EqualTo(match)#
__call__(val)#
Parameters:

val (TypeVar(ExactMatchT, bool, bytes, int, Decimal, str, float, date, datetime, UUID)) – the value being validated

Return type:

bool

match#
class EqualsValidator(match, preprocessors=None)#

Check if a value is of the same type as match and check that that value is equivalent.

match#
preprocessors = None#
class ExactItemCount(item_count)#
__call__(val)#
Parameters:

val (Sized) – the value being validated

Return type:

bool

item_count#
class ExactLength(length)#
__call__(val)#
Parameters:

val (TypeVar(StrOrBytes, str, bytes)) – the value being validated

Return type:

bool

length#
class ExtraKeysErr(expected_keys)#

extra keys were present in a dictionary

expected_keys#
class FloatValidator(*predicates, predicates_async=None, preprocessors=None, coerce=None)#

Validate a value is a float, and any extra refinement.

If predicates_async is supplied, the __call__ method should not be called – only .validate_async should be used.

Parameters:
  • predicates (Predicate[TypeVar(SuccessT)]) – any number of Predicate[float] instances

  • predicates_async (Optional[List[PredicateAsync[TypeVar(SuccessT)]]], default: None) – any number of PredicateAsync[float] instances

  • preprocessors (Optional[List[Processor[TypeVar(SuccessT)]]], default: None) – any number of Processor[float], which will be run before Predicates and PredicateAsyncs are checked.

  • coerce (Optional[Coercer[TypeVar(SuccessT)]], default: None) – a function that can control coercion

class IndexErrs(indexes)#

dictionary of validation errors by index

indexes#
class IntValidator(*predicates, predicates_async=None, preprocessors=None, coerce=None)#

Validate a value is a int, and any extra refinement.

If predicates_async is supplied, the __call__ method should not be called – only .validate_async should be used.

Parameters:
  • predicates (Predicate[TypeVar(SuccessT)]) – any number of Predicate[int] instances

  • predicates_async (Optional[List[PredicateAsync[TypeVar(SuccessT)]]], default: None) – any number of PredicateAsync[int] instances

  • preprocessors (Optional[List[Processor[TypeVar(SuccessT)]]], default: None) – any number of Processor[int], which will be run before Predicates and PredicateAsyncs are checked.

  • coerce (Optional[Coercer[TypeVar(SuccessT)]], default: None) – a function that can control coercion

class Invalid(err_type, value, validator)#

Represents validation failure. Contains relevant failure data so use case-specific error objects (or other data) can be produced.

err_type#

Any of a number of classes that contain data about the type of error, e.g. TypeErr, CoercionErr, KeyMissingErr, etc.

is_valid = False#

This is always False on Invalid instances. It’s useful for if statements. Mypy understands it as a tag for a tagged union.

map(func)#
Return type:

Union[Valid[TypeVar(B)], Invalid]

validator#

The validator that determined value to be invalid

value#

The invalid value that was being validated

class IsDictValidator#
class KeyErrs(keys)#

validation failures for key/value pairs on a record-like dictionary

keys#
class KeyNotRequired(validator)#
__call__(val)#
Parameters:

val (Any) – the value being validated

Return type:

Union[Valid[Union[Just[TypeVar(A)], Nothing]], Invalid]

async validate_async(val)#
Parameters:

val (Any) – the value being validated

Return type:

Union[Valid[Union[Just[TypeVar(A)], Nothing]], Invalid]

class KeyValErrs(key, val)#

Key and/or value errors from a single key/value pair. This is useful for mapping collections.

key#
val#
class Lazy(validator, recurrent=True)#

Allows for specification of mutually recursive type definitions.

__call__(data)#
Parameters:

val – the value being validated

Return type:

Union[Valid[TypeVar(Ret)], Invalid]

async validate_async(data)#
Parameters:

val – the value being validated

Return type:

Union[Valid[TypeVar(Ret)], Invalid]

class ListValidator(item_validator, *, predicates=None, predicates_async=None, coerce=None)#
class LowerCase#
__call__(val)#

Call self as a function.

Return type:

TypeVar(StrOrBytes, str, bytes)

class MapErr(keys)#

errors from key/value pairs of a map-like dictionary

keys#
class MapValidator(*, key, value, predicates=None, predicates_async=None, coerce=None)#
__call__(val)#
Parameters:

val (Any) – the value being validated

Return type:

Union[Valid[Dict[TypeVar(T1), TypeVar(T2)]], Invalid]

async validate_async(val)#
Parameters:

val (Any) – the value being validated

Return type:

Union[Valid[Dict[TypeVar(T1), TypeVar(T2)]], Invalid]

class Max(maximum, exclusive_maximum=False)#
__call__(val)#
Parameters:

val (TypeVar(MinMaxT, int, float, Decimal, date, datetime)) – the value being validated

Return type:

bool

exclusive_maximum = False#
maximum#
class MaxItems(item_count)#
__call__(val)#
Parameters:

val (TypeVar(ListOrTupleOrSetAny, List[Any], Tuple[Any, ...], Set[Any])) – the value being validated

Return type:

bool

item_count#
class MaxKeys(size)#
__call__(val)#
Parameters:

val (Dict[Any, Any]) – the value being validated

Return type:

bool

size#
class MaxLength(length)#
__call__(val)#
Parameters:

val (TypeVar(StrOrBytes, str, bytes)) – the value being validated

Return type:

bool

length#
class Min(minimum, exclusive_minimum=False)#
__call__(val)#
Parameters:

val (TypeVar(MinMaxT, int, float, Decimal, date, datetime)) – the value being validated

Return type:

bool

exclusive_minimum = False#
minimum#
class MinItems(item_count)#
__call__(val)#
Parameters:

val (TypeVar(ListOrTupleOrSetAny, List[Any], Tuple[Any, ...], Set[Any])) – the value being validated

Return type:

bool

item_count#
class MinKeys(size)#
__call__(val)#
Parameters:

val (Dict[Any, Any]) – the value being validated

Return type:

bool

size#
class MinLength(length)#
__call__(val)#
Parameters:

val (TypeVar(StrOrBytes, str, bytes)) – the value being validated

Return type:

bool

length#
class MissingKeyErr#

A key is missing from a dictionary

class MultipleOf(factor)#
__call__(val)#
Parameters:

val (TypeVar(Num, int, float, Decimal)) – the value being validated

Return type:

bool

factor#
class NTupleValidator(*, fields, validate_object=None, coerce=Coercer(coerce=<function tuple_or_list_to_tuple>, compatible_types={<class 'list'>, <class 'tuple'>}))#
static typed(*, fields, validate_object=None, coerce=Coercer(coerce=<function tuple_or_list_to_tuple>, compatible_types={<class 'list'>, <class 'tuple'>}))#

Can be used for up to 8 typed tuple slots. For more than 8 slots, use NTupleValidator.untyped.

Parameters:
Return type:

Union[NTupleValidator[Tuple[TypeVar(T1)]], NTupleValidator[Tuple[TypeVar(T1), TypeVar(T2)]], NTupleValidator[Tuple[TypeVar(T1), TypeVar(T2), TypeVar(T3)]], NTupleValidator[Tuple[TypeVar(T1), TypeVar(T2), TypeVar(T3), TypeVar(T4)]], NTupleValidator[Tuple[TypeVar(T1), TypeVar(T2), TypeVar(T3), TypeVar(T4), TypeVar(T5)]], NTupleValidator[Tuple[TypeVar(T1), TypeVar(T2), TypeVar(T3), TypeVar(T4), TypeVar(T5), TypeVar(T6)]], NTupleValidator[Tuple[TypeVar(T1), TypeVar(T2), TypeVar(T3), TypeVar(T4), TypeVar(T5), TypeVar(T6), TypeVar(T7)]], NTupleValidator[Tuple[TypeVar(T1), TypeVar(T2), TypeVar(T3), TypeVar(T4), TypeVar(T5), TypeVar(T6), TypeVar(T7), TypeVar(T8)]]]

Returns:

NTupleValidator with the fields as defined by the fields parameter

static untyped(*, fields, validate_object=None, coerce=Coercer(coerce=<function tuple_or_list_to_tuple>, compatible_types={<class 'list'>, <class 'tuple'>}))#

Identical to NTupleValidator.typed except that it can be used for an arbitrary number of slots. Does not retain type information.

Parameters:
Return type:

NTupleValidator[Tuple[Any, ...]]

Returns:

NTupleValidator with the fields as defined by the fields parameter

class NamedTupleValidator(named_tuple_cls, *, overrides=None, validate_object=None, validate_object_async=None, fail_on_unknown_keys=False, typehint_resolver=<function get_typehint_validator>, coerce=None)#

Takes a NamedTuple subclass as an argument and derives a Validator. Will validate against an instance of self.named_tuple_cls or a dictionary. Regardless of the input type, the result will be an instance of type self.named_tuple_cls.

Optional keys are determined by the presence of a default argument.

Example:

from dataclasses import dataclass
from typing import List, NamedTuple
from koda_validate import *

class Person(NamedTuple):
    name: str
    hobbies: List[str]

validator = NamedTupleValidator(Person)

Usage:

>>> validator({"name": "Bob", "hobbies": ["eating", "coding", "sleeping"]})
Valid(val=Person(name='Bob', hobbies=['eating', 'coding', 'sleeping']))
Parameters:
  • named_tuple_cls (Type[TypeVar(_NTT, bound= NamedTuple)]) – A dataclass class

  • overrides (Optional[Dict[str, Validator[Any]]], default: None) – a dict whose keys define explicit validators

  • validate_object (Optional[Callable[[TypeVar(_NTT, bound= NamedTuple)], Union[CoercionErr, ContainerErr, ExtraKeysErr, IndexErrs, KeyErrs, MapErr, MissingKeyErr, PredicateErrs[Any], SetErrs, TypeErr, ValidationErrBase, UnionErrs, None]]], default: None) – is run if all keys have been validated individually. If it returns None, then there were no errors; otherwise it should return ErrType

  • validate_object_async (Optional[Callable[[TypeVar(_NTT, bound= NamedTuple)], Awaitable[Union[CoercionErr, ContainerErr, ExtraKeysErr, IndexErrs, KeyErrs, MapErr, MissingKeyErr, PredicateErrs[Any], SetErrs, TypeErr, ValidationErrBase, UnionErrs, None]]]], default: None) – same as validate_object, except that is runs asynchronously

  • typehint_resolver (Callable[[Any], Validator[Any]], default: <function get_typehint_validator at 0x7fa8194d2c00>) – define this to override default inferred validators for types

  • fail_on_unknown_keys (bool, default: False) – if True, this will fail if any keys not defined by self.data_cls are found. This will fail before any values are validated.

  • coerce (Optional[Coercer[Dict[Any, Any]]], default: None) – a function that can control coercion

Raises:

TypeError – should raise if non-NamedTuple type is passed for named_tuple_cls

class NoneValidator(coerce=None)#
coerce = None#
class NotBlank#
__call__(val)#
Parameters:

val (TypeVar(StrOrBytes, str, bytes)) – the value being validated

Return type:

bool

class OptionalValidator(validator, *, none_validator=NoneValidator(coerce=None))#

We have a value for a key, but it can be null (None)

class Predicate#

A predicate just returns True or False for some condition.

Predicates can be used during async validation, but PredicateAsync should be used for any validation that requires asyncio.

Example Predicate:

from koda_validate import Predicate

class GreaterThan(Predicate[int]):
    def __init__(self, limit: int) -> None:
        self.limit = limit

    def __call__(self, val: int) -> bool:
        return val > self.limit

Usage

>>> gt = GreaterThan(5)
>>> gt(6)
True
>>> gt(1)
False
abstract __call__(val)#
Parameters:

val (TypeVar(A)) – the value being validated

Return type:

bool

class PredicateAsync#

The async-only sibling of Predicate.

Example PredicateAsync

import asyncio
from koda_validate import PredicateAsync

class UsernameInDB(PredicateAsync[str]):
    async def validate_async(self, val: str) -> bool:
        # pretend to call db
        await asyncio.sleep(.001)
        # dummy logic for example
        return len(val) == 3

Usage

>>> asyncio.run(UsernameInDB().validate_async("abc"))
True
>>> asyncio.run(UsernameInDB().validate_async("abcdef"))
False
abstract async validate_async(val)#
Parameters:

val (TypeVar(A)) – the value being validated

Return type:

bool

Returns:

a bool indicating whether the condition is True for the value

class PredicateErrs(predicates)#

A grouping of failed Predicates

predicates#
class Processor#

Base class for Processors. These are litle more than

Callable[[A], A]

They transform a value of one type to another value of the same type. The are useful for things like strip-ping strings:

from dataclasses import dataclass
from koda_validate import Processor

@dataclass
class Strip(Processor[str]):
    def __call__(self, val: str) -> str:
        return val.strip()

Usage:

>>> strip = Strip()
>>> strip(" abc ")
'abc'
>>> strip("def")
'def'

Note

Because processors are type-aware they are most useful directly after type verification or coercion.

abstract __call__(val)#

Call self as a function.

Return type:

TypeVar(A)

class RecordValidator(into, keys, validate_object=None, validate_object_async=None, fail_on_unknown_keys=False)#
class RegexPredicate(pattern)#
__call__(val)#
Parameters:

val (str) – the value being validated

Return type:

bool

pattern#
class SetErrs(item_errs)#

Errors from items in a set.

item_errs#
class SetValidator(item_validator, *, predicates=None, predicates_async=None, coerce=None)#
class StartsWith(prefix)#
__call__(val)#
Parameters:

val (TypeVar(StrOrBytes, str, bytes)) – the value being validated

Return type:

bool

prefix#
class StringValidator(*predicates, predicates_async=None, preprocessors=None, coerce=None)#

Validate a value is a str, and any extra refinement.

If predicates_async is supplied, the __call__ method should not be called – only .validate_async should be used.

Example:

>>> from koda_validate import *
>>> validator = StringValidator(not_blank, MaxLength(100), preprocessors=[strip])
>>> validator("")
Invalid(err_type=PredicateErrs(predicates=[NotBlank()]), ...)
>>> validator(None)
Invalid(err_type=TypeErr(expected_type=<class 'str'>), ...)
>>> validator(" ok ")
Valid(val='ok')
Parameters:
  • predicates (Predicate[TypeVar(SuccessT)]) – any number of Predicate[str] instances

  • predicates_async (Optional[List[PredicateAsync[TypeVar(SuccessT)]]], default: None) – any number of PredicateAsync[str] instances

  • preprocessors (Optional[List[Processor[TypeVar(SuccessT)]]], default: None) – any number of Processor[str], which will be run before Predicates and PredicateAsyncs are checked.

class TypeErr(expected_type)#

A specific type was required but not found

expected_type#
class TypedDictValidator(td_cls, *, overrides=None, validate_object=None, validate_object_async=None, coerce=None, typehint_resolver=<function get_typehint_validator>, fail_on_unknown_keys=False)#

Takes a TypedDict subclass as an argument and derives a Validator.

Optional keys are determined by the __optional_keys__ and __required_keys__ attributes.

Note

This validator _might_ work on non-typed-dict classes (There are challenges in defining a TypedDict-like type). Please do not intentionally try to use it for non-TypedDict datatypes.

Example:

from typing import List, TypedDict
from koda_validate import *

class Person(TypedDict):
    name: str
    hobbies: List[str]

validator = TypedDictValidator(Person)

Usage:

>>> validator({"name": "Bob", "hobbies": ["eating", "coding", "sleeping"]})
Valid(val={'name': 'Bob', 'hobbies': ['eating', 'coding', 'sleeping']})
Parameters:
  • td_cls (Type[TypeVar(_TDT, bound= Mapping[str, object])]) – A TypedDict subclass

  • overrides (Optional[Dict[str, Validator[Any]]], default: None) – a dict whose keys define explicit validators

  • validate_object (Optional[Callable[[TypeVar(_TDT, bound= Mapping[str, object])], Union[CoercionErr, ContainerErr, ExtraKeysErr, IndexErrs, KeyErrs, MapErr, MissingKeyErr, PredicateErrs[Any], SetErrs, TypeErr, ValidationErrBase, UnionErrs, None]]], default: None) – is run if all keys have been validated individually. If it returns None, then there were no errors; otherwise it should return ErrType

  • validate_object_async (Optional[Callable[[TypeVar(_TDT, bound= Mapping[str, object])], Awaitable[Union[CoercionErr, ContainerErr, ExtraKeysErr, IndexErrs, KeyErrs, MapErr, MissingKeyErr, PredicateErrs[Any], SetErrs, TypeErr, ValidationErrBase, UnionErrs, None]]]], default: None) – same as validate_object, except that is runs asynchronously

  • typehint_resolver (Callable[[Any], Validator[Any]], default: <function get_typehint_validator at 0x7fa8194d2c00>) – define this to override default inferred validators for types

  • coerce (Optional[Coercer[Dict[Any, Any]]], default: None) – this can be set to create any kind of custom coercion

  • fail_on_unknown_keys (bool, default: False) – if True, this will fail if any keys not defined by the TypedDict are found. This will fail before any values are validated.

Raises:

TypeError – should raise if non-TypedDict type is passed for td_cls

class UUIDValidator(*predicates, predicates_async=None, preprocessors=None, coerce=Coercer(coerce=<function coerce_uuid>, compatible_types={<class 'str'>, <class 'uuid.UUID'>}))#
class UniformTupleValidator(item_validator, *, predicates=None, predicates_async=None, coerce=Coercer(coerce=<function tuple_or_list_to_tuple>, compatible_types={<class 'list'>, <class 'tuple'>}))#
class UnionErrs(variants)#

Errors from each variant of a union.

variants#
class UnionValidator(validator_1, *validators)#
static typed(validator_1, validator_2=None, validator_3=None, validator_4=None, validator_5=None, validator_6=None, validator_7=None, validator_8=None)#

Can be used for up to 8 typed variants. For more than 8 variants, use UnionValidator.untyped. Arguments should be positional only. (@overloads specify that arguments should be positional-only.)

Parameters:
  • validator_1 (Validator[TypeVar(T1)]) – the first variant

  • validator_2 (Optional[Validator[TypeVar(T2)]], default: None) – the second variant (if defined)

  • validator_3 (Optional[Validator[TypeVar(T3)]], default: None) – the third variant (if defined)

  • validator_4 (Optional[Validator[TypeVar(T4)]], default: None) – the fourth variant (if defined)

  • validator_5 (Optional[Validator[TypeVar(T5)]], default: None) – the fifth variant (if defined)

  • validator_6 (Optional[Validator[TypeVar(T6)]], default: None) – the sixth variant (if defined)

  • validator_7 (Optional[Validator[TypeVar(T7)]], default: None) – the seventh variant (if defined)

  • validator_8 (Optional[Validator[TypeVar(T8)]], default: None) – the eighth variant (if defined)

Return type:

Union[UnionValidator[TypeVar(T1)], UnionValidator[Union[TypeVar(T1), TypeVar(T2)]], UnionValidator[Union[TypeVar(T1), TypeVar(T2), TypeVar(T3)]], UnionValidator[Union[TypeVar(T1), TypeVar(T2), TypeVar(T3), TypeVar(T4)]], UnionValidator[Union[TypeVar(T1), TypeVar(T2), TypeVar(T3), TypeVar(T4), TypeVar(T5)]], UnionValidator[Union[TypeVar(T1), TypeVar(T2), TypeVar(T3), TypeVar(T4), TypeVar(T5), TypeVar(T6)]], UnionValidator[Union[TypeVar(T1), TypeVar(T2), TypeVar(T3), TypeVar(T4), TypeVar(T5), TypeVar(T6), TypeVar(T7)]], UnionValidator[Union[TypeVar(T1), TypeVar(T2), TypeVar(T3), TypeVar(T4), TypeVar(T5), TypeVar(T6), TypeVar(T7), TypeVar(T8)]]]

Returns:

UnionValidator with the variants defined above.

static untyped(validator_1, *validators)#

Can handle any number of variant Validator<koda_validate.Validator>`s (as opposed to UnionValidator.typed), but does not retain type information.

Parameters:
  • validator_1 (Validator[Any]) – the first variant of the union. This is specified on its own, so we have at least one variant specified

  • validators (Validator[Any]) – the rest of the variants of the union

Return type:

UnionValidator[Any]

Returns:

UnionValidator with the variants defined above.

class UniqueItems#

Works with both hashable and unhashable items.

__call__(val)#
Parameters:

val (TypeVar(ListOrTupleOrSetAny, List[Any], Tuple[Any, ...], Set[Any])) – the value being validated

Return type:

bool

class UpperCase#
__call__(val)#

Call self as a function.

Return type:

TypeVar(StrOrBytes, str, bytes)

class Valid(val)#

A wrapper for valid data, e.g. Valid("abc")

is_valid = True#

This is always True on Valid instances. It’s useful for if statements. Mypy understands it as a tag for a tagged union.

map(func)#
Return type:

Union[Valid[TypeVar(B)], Invalid]

val#

The value that has succeeded validation

class ValidationErrBase#

This class exists only to provide a class to subclass for custom error types

class Validator#

Base class for all Validators.

It’s little more than a Callable[[Any], ValidationResult[SuccessT]], with two notable differences:

  • A .validate_async method is allowed, meaning a Validator can be made

    to work in both sync and async contexts.

  • Validator`s are ``class`es. Constructing Callable classes allows

    us to more easily make metadata from the validator available (as opposed to data being hidden inside a closure)

Depending on your use case, you may want to implement the __call__ method, the async_validate method, or both.

Note

Fundamentally, Validators need to be able to return valid data that is a different type than what was passed in. The main reason for this is that we need to be able to call a Validator with data of unknown types. For that reason Validators accept Any as input. This has a few notable implications:

  • we can never assume that the data returned is the same data passed in

  • coercing and conforming (see Processors) data is fundamentally legal

  • some kind of type verification usually needs to happen within a Validator

  • refinement (see Predicates) needs to be run after type verification

__call__(val)#
Parameters:

val (Any) – the value being validated

Return type:

Union[Valid[TypeVar(SuccessT)], Invalid]

async validate_async(val)#
Parameters:

val (Any) – the value being validated

Return type:

Union[Valid[TypeVar(SuccessT)], Invalid]

coercer(*compatible_types)#

This is purely a convenience constructor for Coercer objects.

Parameters:

compatible_types (Type[Any]) – the types the coercer can take to produce an the return type

Return type:

Callable[[Callable[[Any], Union[Just[TypeVar(A)], Nothing]]], Coercer[TypeVar(A)]]

Returns:

A callable which accepts a function that should be congruent with the compatible_types param.

ValidationResult#

alias of Union[Valid[A], Invalid]

ErrType#

alias of Union[CoercionErr, ContainerErr, ExtraKeysErr, IndexErrs, KeyErrs, MapErr, MissingKeyErr, PredicateErrs[Any], SetErrs, TypeErr, ValidationErrBase, UnionErrs]