### Install mypy as a Poetry dev dependency Source: https://koda-validate.readthedocs.io/en/stable/setup/type-checking This command installs 'mypy' specifically for the 'test' dependency group using Poetry. This is a common practice as 'mypy' is a development tool and not required at runtime. ```shell poetry add mypy --group test ``` -------------------------------- ### Install Koda Validate with Pip Source: https://context7.com/context7/koda-validate_readthedocs_io_en_stable/llms.txt Installs the Koda Validate library using pip, a standard Python package installer. Ensure you have Python 3.8+ and pip installed. ```bash pip install koda-validate ``` -------------------------------- ### Install mypy with pip Source: https://koda-validate.readthedocs.io/en/stable/_sources/setup/type-checking This code snippet shows the command to install the mypy type checker using pip. mypy is recommended for use with Koda Validate to leverage type hints. ```bash pip install mypy ``` -------------------------------- ### Install mypy using pip Source: https://koda-validate.readthedocs.io/en/stable/setup/type-checking This command installs the 'mypy' type checker using pip, a common Python package installer. It ensures that 'mypy' is available in your Python environment for static analysis. ```shell pip install mypy ``` -------------------------------- ### Complex RecordValidator Example Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/dictionaries/records Illustrates a more advanced RecordValidator setup using various key types including integers, booleans, and tuples, along with a ListValidator for a list of strings. This example validates against a Person dataclass with a list of hobbies. ```python from dataclasses import dataclass from koda import Maybe, Just from koda_validate import ( RecordValidator, StringValidator, KeyNotRequired, IntValidator, Valid, ListValidator ) @dataclass class Person: name: str age: Maybe[int] hobbies: list[str] person_validator = RecordValidator( into=Person, keys=( (1, StringValidator()), (False, KeyNotRequired(IntValidator())), (("abc", 123), ListValidator(StringValidator())) ), ) assert person_validator({ 1: "John Doe", False: 30, ("abc", 123): ["reading", "cooking"] }) == Valid(Person( "John Doe", Just(30), ["reading", "cooking"] )) ``` -------------------------------- ### Install mypy using Poetry Source: https://koda-validate.readthedocs.io/en/stable/setup/type-checking This command adds 'mypy' as a project dependency using Poetry, a dependency management tool for Python. It integrates 'mypy' into your project's dependency tree. ```shell poetry add mypy ``` -------------------------------- ### Install Koda Validate with pip Source: https://koda-validate.readthedocs.io/en/stable/setup/installation Installs the Koda Validate Python package using the pip package installer. This is the standard method for most Python projects. ```shell pip install koda-validate ``` -------------------------------- ### Add Koda Validate to Poetry project Source: https://koda-validate.readthedocs.io/en/stable/setup/installation Adds the Koda Validate Python package as a dependency to a project managed by Poetry. Poetry handles dependency management and packaging. ```shell poetry add koda-validate ``` -------------------------------- ### Basic IntValidator Usage in Koda Validate Source: https://koda-validate.readthedocs.io/en/stable/philosophy/validators Demonstrates how to instantiate and use the IntValidator to validate integer inputs. It shows successful validation and an example of an invalid input. ```python 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=), # value='not an integer', # validator=IntValidator() # ) ``` -------------------------------- ### Install mypy as a dev dependency with Poetry Source: https://koda-validate.readthedocs.io/en/stable/_sources/setup/type-checking This code snippet illustrates adding mypy to a specific dependency group (e.g., 'test') using Poetry. This is common for development tools that do not affect runtime. ```bash poetry add mypy --group test ``` -------------------------------- ### Install mypy with Poetry Source: https://koda-validate.readthedocs.io/en/stable/_sources/setup/type-checking This code snippet demonstrates how to add mypy as a dependency using Poetry. mypy is a type checker that enhances code reliability and is recommended for Koda Validate. ```bash poetry add mypy ``` -------------------------------- ### BytesValidator Example in Python Source: https://koda-validate.readthedocs.io/en/stable/api/koda_validate Demonstrates the usage of BytesValidator for validating byte strings. It shows how to use predicates like `not_blank` and `MaxLength`, along with preprocessors like `strip`. The examples illustrate successful validation, validation errors for incorrect types, and validation errors due to unmet predicates. ```python from koda_validate import * validator = BytesValidator(not_blank, MaxLength(100), preprocessors=[strip]) validator(b" Invalid( err_type=PredicateErrs(predicates=[ NotBlank(), ]), value=b'', validator=BytesValidator(NotBlank(), MaxLength(length=100), preprocessors=[Strip()]) ) validator("") Invalid( err_type=TypeErr(expected_type=), value='', validator=BytesValidator(NotBlank(), MaxLength(length=100), preprocessors=[Strip()]) ) validator(b' ok ') Valid(val=b'ok') ``` -------------------------------- ### Install Koda Validate with Poetry Source: https://context7.com/context7/koda-validate_readthedocs_io_en_stable/llms.txt Adds the Koda Validate library as a dependency to a project managed by Poetry, a Python dependency management tool. This command ensures compatibility within your project's environment. ```bash poetry add koda-validate ``` -------------------------------- ### IntValidator Usage Example Source: https://koda-validate.readthedocs.io/en/stable/_sources/philosophy/validators Demonstrates the usage of IntValidator to validate if a given value is an integer. It shows the expected output for a valid integer input and an invalid string input. ```python from koda_validate import IntValidator int_validator = IntValidator() # Usage: print(int_validator(5)) print(int_validator("not an integer")) ``` -------------------------------- ### Koda Validate Predicate Usage Example Source: https://koda-validate.readthedocs.io/en/stable/philosophy/predicates Demonstrates how to use the Predicate class in Koda Validate with an IntValidator. It shows successful validation, type error, and predicate error scenarios. ```python from koda_validate import IntValidator, Min int_validator = IntValidator(Min(5)) # Example usage: # int_validator(6) # Returns Valid(val=6) # int_validator("a string") # Returns Invalid(err_type=TypeErr(...), ...) # int_validator(4) # Returns Invalid(err_type=PredicateErrs(...), ...) ``` -------------------------------- ### String Preprocessing with `strip` Source: https://context7.com/context7/koda-validate_readthedocs_io_en_stable/llms.txt Demonstrates preprocessing strings before validation using the `strip` function. This example also includes the `NotBlank` predicate to ensure the string is not empty after stripping whitespace. Dependencies: 'koda_validate'. ```python from koda_validate import StringValidator, NotBlank, strip validator = StringValidator(NotBlank(), preprocessors=[strip]) result = validator(" hello ") # Valid(val='hello') result = validator(" ") # Invalid(err_type=PredicateErrs(predicates=[NotBlank()]), ...) ``` -------------------------------- ### String Refinement with Koda Validate Predicates Source: https://koda-validate.readthedocs.io/en/stable/_sources/index Demonstrates how to apply multiple validation rules (predicates) to a string validator in Koda Validate. This example uses MinLength, MaxLength, and StartsWith predicates to enforce specific string characteristics. ```python from koda_validate import StringValidator, MinLength, MaxLength, StartsWith validator = StringValidator(MinLength(5), MaxLength(10), StartsWith("a")) # Example usage (as shown in doctests): # print(validator("abc123")) ``` -------------------------------- ### Custom Processor Implementation with koda-validate Source: https://context7.com/context7/koda-validate_readthedocs_io_en_stable/llms.txt Create custom processors by subclassing 'Processor' to transform values before validation. An example shows converting a string to uppercase. Requires 'dataclasses'. ```python from dataclasses import dataclass from koda_validate import Processor, StringValidator @dataclass class Uppercase(Processor[str]): def __call__(self, val: str) -> str: return val.upper() validator = StringValidator(preprocessors=[Uppercase()]) result = validator("hello") # Valid(val='HELLO') ``` -------------------------------- ### Custom Async Validator Implementation - Python Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/async Provides an example of creating a custom asynchronous validator by implementing the `validate_async` method within a `Validator` subclass. This example shows a `SimpleFloatValidator` made async-compatible. ```python import asyncio from typing import Any from koda_validate import Validator, Invalid, Valid, TypeErr, ValidationResult class SimpleFloatValidator(Validator[float]): def __call__(self, val: Any) -> ValidationResult[float]: if isinstance(val, float): return Valid(val) else: # This part of the original code was incomplete, so it's assumed to be handled elsewhere or omitted for brevity. pass ``` -------------------------------- ### Initialize Validator Once in Python Source: https://koda-validate.readthedocs.io/en/stable/how_to/performance Demonstrates the difference in performance between initializing a validator on every function call versus initializing it once at the module level. Initializing once is significantly faster as it avoids repeated setup costs. This pattern is crucial for performance-sensitive applications. ```python from typing import Any from koda_validate import ValidationResult, TypedDictValidator class Book(TypedDict): title: str author: str # Slower approach: validator initialized on each call def some_request_handler_slower(data: Any) -> ValidationResult[Book]: return TypedDictValidator(Book)(data) # Faster approach: validator initialized once book_validator = TypedDictValidator(Book) def some_request_handler_faster(data: Any) -> ValidationResult[Book]: return book_validator(data) ``` -------------------------------- ### Async Function Signature Validation with Koda Validate Source: https://koda-validate.readthedocs.io/en/stable/how_to/runtime_type_checking Shows how to use `validate_signature` with asynchronous functions in Python. It includes an example of a simple async function and then demonstrates how to incorporate asynchronous validation predicates for more complex scenarios. ```python from koda_validate.signature import * @validate_signature async def save_data(version: int, data: dict[str, str]) -> None: # do some async saving logic return None ``` ```python from typing import Annotated from koda_validate import * from koda_validate.signature import * class CheckLatestVersion(PredicateAsync[int]): async def validate_async(self, val: int) -> bool: # should be something like # latest_version = await get_latest_version(val) # for simplicity, we'll pretend the service returned 5 latest_version = 5 return val == latest_version @validate_signature async def save_data( version: Annotated[int, IntValidator(predicates_async=[CheckLatestVersion()])], data: dict[str, str] ) -> None: # do some async saving logic return None ``` -------------------------------- ### TypedDictValidator Example Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/dictionaries/derived Demonstrates using TypedDictValidator to validate a dictionary against a TypedDict structure. It expects integer and optional string types and ensures the output is a Valid object. ```Python from typing import Optional, TypedDict from koda_validate import TypedDictValidator, Valid class Image(TypedDict): height: int width: int description: Optional[str] validator = TypedDictValidator(Image) assert validator({"height": 10, "width": 20, "description": None}) == Valid( {"height": 10, "width": 20, "description": None} ) ``` -------------------------------- ### Sync and Async Validation Example - Python Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/async Illustrates how a single Validator instance can be used in both synchronous and asynchronous contexts. It shows a StringValidator with a MaxLength predicate working in both modes. ```python import asyncio from koda_validate import StringValidator, MaxLength, Valid validator = StringValidator(MaxLength(10)) # sync mode assert validator("sync") == Valid("sync") # async mode (we're not in an async context, so we can't use `await` here) assert asyncio.run(validator.validate_async("async")) == Valid("async") ``` -------------------------------- ### Implement a DictCacheValidator in Python Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/performance Provides a concrete implementation of a caching validator using Python's dict. This example subclasses CacheValidatorBase to cache validation results for IntValidator, demonstrating cache hits and misses. ```python from dataclasses import dataclass, field from typing import Any, TypeVar from koda import Maybe, Just, nothing from koda_validate import ( CacheValidatorBase, ValidationResult, ListValidator, StringValidator, IntValidator ) A = TypeVar('A') @dataclass class DictCacheValidator(CacheValidatorBase[A]): _dict_cache: dict[Any, ValidationResult[A]] = field(default_factory=dict) def cache_get_sync(self, val: Any) -> Maybe[ValidationResult[A]]: if val in self._dict_cache: return Just(self._dict_cache[val]) else: return nothing def cache_set_sync(self, val: Any, cache_val: ValidationResult[A]) -> None: self._dict_cache[val] = cache_val ``` -------------------------------- ### String Validation with Predicates in Python Source: https://context7.com/context7/koda-validate_readthedocs_io_en_stable/llms.txt Shows how to apply multiple string validation predicates like minimum length, maximum length, and a starting pattern using `StringValidator`. Invalid inputs will result in a `PredicateErrs` object detailing the failed constraints. ```python from koda_validate import StringValidator, MinLength, MaxLength, StartsWith validator = StringValidator( MinLength(5), MaxLength(10), StartsWith("a") ) result = validator("abc123") # Valid(val='abc123') result = validator("ab") # Invalid(err_type=PredicateErrs(...), value='ab', ...) result = validator("bcdefghijk") # Invalid(err_type=PredicateErrs(...), value='bcdefghijk', ...) ``` -------------------------------- ### Example Usage of to_flat_errs with Validation Scenarios Source: https://koda-validate.readthedocs.io/en/stable/philosophy/errors Demonstrates the practical application of the `to_flat_errs` function by validating different data structures (empty and complex) against a `ListValidator` with a `TypedDictValidator`. It asserts the expected `Invalid` results and their flattened error representations. ```python class Person(TypedDict): name: str age: int validator = ListValidator(TypedDictValidator(Person)) simple_result = validator({}) assert isinstance(simple_result, Invalid) assert to_flat_errs(simple_result) == [ FlatError(location=[], message=f"expected type ") ] complex_result = validator([None, {}, {"name": "Bob", "age": "not an int"}]) assert isinstance(complex_result, Invalid) assert to_flat_errs(complex_result) == [ FlatError(location=[0], message="expected type "), FlatError(location=[1, 'name'], message='missing key!'), FlatError(location=[1, 'age'], message='missing key!'), FlatError(location=[2, 'age'], message="expected type ") ] ``` -------------------------------- ### DataclassValidator Example Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/dictionaries/derived Shows how to use DataclassValidator for validating dictionaries against a dataclass. It converts dictionary input to a dataclass instance and validates types, returning a Valid object on success. ```Python from typing import Optional from dataclasses import dataclass from koda_validate import DataclassValidator, Valid @dataclass class Image: height: int width: int description: Optional[str] validator = DataclassValidator(Image) assert validator({"height": 10, "width": 20, "description": None}) == Valid( Image(height=10, width=20, description=None) ) ``` -------------------------------- ### Async Validation Example with SimpleFloatValidator Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/async Demonstrates how to use the `validate_async` method of a validator in an asynchronous context. It shows successful validation and type error handling. This validator does not perform I/O operations. ```python import asyncio # Assuming SimpleFloatValidator and ValidationResult classes are defined elsewhere # For demonstration, let's mock them: class ValidationResult: pass class Valid(ValidationResult): def __init__(self, value): self.value = value def __eq__(self, other): return isinstance(other, Valid) and self.value == other.value class Invalid(ValidationResult): def __init__(self, error, value, validator): self.error = error self.value = value self.validator = validator def __eq__(self, other): return isinstance(other, Invalid) and self.error == other.error and self.value == other.value and self.validator == other.validator class TypeErr: def __init__(self, expected_type): self.expected_type = expected_type def __eq__(self, other): return isinstance(other, TypeErr) and self.expected_type == other.expected_type class SimpleFloatValidator: def __call__(self, val: any) -> ValidationResult[float]: if isinstance(val, float): return Valid(val) else: return Invalid(TypeErr(float), val, self) async def validate_async(self, val: any) -> ValidationResult[float]: return self(val) float_validator = SimpleFloatValidator() test_val = 5.5 assert asyncio.run(float_validator.validate_async(test_val)) == Valid(test_val) assert asyncio.run(float_validator.validate_async(5)) == Invalid(TypeErr(float), 5, float_validator) ``` -------------------------------- ### Create a String Stripping Processor Source: https://koda-validate.readthedocs.io/en/stable/api/koda_validate Demonstrates how to create a custom processor by inheriting from `Processor`. This example defines a `Strip` processor that removes leading and trailing whitespace from a string. Processors are used to transform values of the same type. ```python 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 ") # Expected output: 'abc' ``` -------------------------------- ### Python Asynchronous Validation Example Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/extension This Python snippet illustrates how to perform asynchronous validation using a SimpleFloatValidator. It assumes the validator has a `validate_async` method and demonstrates calling it within an async context, showing the pattern for awaited asynchronous operations. ```python validator = SimpleFloatValidator(...) await validator.validate_async(5.5) ``` -------------------------------- ### DataclassValidator Example in Python Source: https://koda-validate.readthedocs.io/en/stable/api/koda_validate Illustrates how to use DataclassValidator to create a validator for a Python dataclass. It explains how the validator can handle dictionary inputs and convert them to dataclass instances, and how optional fields are inferred from default arguments. ```python from dataclasses import dataclass from koda_validate import DataclassValidator @dataclass class User: name: str age: int is_active: bool = True user_validator = DataclassValidator(User) # Example usage: valid_data = {"name": "Alice", "age": 30} result = user_validator(valid_data) # result will be Valid(val=User(name='Alice', age=30, is_active=True)) invalid_data = {"name": "Bob", "age": "twenty"} result = user_validator(invalid_data) # result will be Invalid(... indicating type error for age) ``` -------------------------------- ### ListValidator Composition Example Source: https://koda-validate.readthedocs.io/en/stable/_sources/philosophy/validators Illustrates how ListValidator can be composed with other validators, specifically StringValidator, to validate a list of strings. It shows successful validation of a list of strings and unsuccessful validation of a list of integers. ```python from koda_validate import ListValidator, StringValidator list_str_validator = ListValidator(StringValidator()) # Usage: print(list_str_validator(["ok", "nice"])) print(list_str_validator([1,2,3])) ``` -------------------------------- ### Async Validation with Custom Predicate Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/runtime_type_checking Illustrates advanced asynchronous validation within `validate_signature`. This example defines a custom asynchronous predicate `CheckLatestVersion` to validate function arguments against an external service (simulated here). ```python from typing import Annotated from koda_validate import * from koda_validate.signature import * class CheckLatestVersion(PredicateAsync[int]): async def validate_async(self, val: int) -> bool: # should be something like # latest_version = await get_latest_version(val) # for simplicity, we'll pretend the service returned 5 latest_version = 5 return val == latest_version @validate_signature async def save_data( version: Annotated[int, IntValidator(predicates_async=[CheckLatestVersion()])], data: dict[str, str] ) -> None: # do some async saving logic return None ``` -------------------------------- ### Custom Async Predicate Example - Python Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/async Defines and uses a custom asynchronous predicate `IsActiveUsername` for validating usernames against a list of active users, simulating database latency. It demonstrates handling both valid and invalid cases asynchronously and shows that sync usage raises an AssertionError. ```python import asyncio from koda_validate import PredicateAsync, StringValidator, MinLength, Invalid, Valid, PredicateErrs class IsActiveUsername(PredicateAsync[str]): async def validate_async(self, val: str) -> bool: # add some latency to pretend we're calling the db await asyncio.sleep(.01) return val in {"michael", "gob", "lindsay", "buster"} username_validator = StringValidator(MinLength(1), predicates_async=[(is_active_username := IsActiveUsername())]) assert asyncio.run(username_validator.validate_async("michael")) == Valid("michael") assert asyncio.run(username_validator.validate_async("tobias")) == Invalid(PredicateErrs([is_active_username]), "tobias", username_validator) # calling in sync mode raises an AssertionError try: username_validator("michael") except AssertionError: print("expected error raised") ``` -------------------------------- ### Using typing.Any for Type Inference (Python) Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/type-checking This example shows how to use `typing.Any` to indicate that a variable can be of any type. This is useful when the exact type is unknown or when dealing with functions that return values of indeterminate types. It bypasses strict type checking for the variable `x`. ```python from typing import Any x: Any = some_function() ``` -------------------------------- ### Python SimpleFloatValidator Usage Example Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/extension This Python doctest demonstrates how to use the SimpleFloatValidator. It shows the instantiation of the validator with a specific predicate (FloatMin) and a preprocessor (FloatAbs), and then calls the validator with a negative float value, expecting a positive float as output. ```python validator = SimpleFloatValidator(predicate=FloatMin(2.2), preprocessor=FloatAbs()) validator(-5.5) ``` -------------------------------- ### Implement a Cache Validator in Python Source: https://koda-validate.readthedocs.io/en/stable/how_to/performance Shows how to create a custom caching validator by subclassing `CacheValidatorBase`. This example uses a dictionary as a cache backend to store validation results, reducing redundant computations for repeated inputs. It includes synchronous `cache_get_sync` and `cache_set_sync` methods. ```python from dataclasses import dataclass, field from typing import Any, TypeVar from koda import Maybe, Just, nothing from koda_validate import ( CacheValidatorBase, ValidationResult, ListValidator, StringValidator, IntValidator ) A = TypeVar('A') @dataclass class DictCacheValidator(CacheValidatorBase[A]): _dict_cache: dict[Any, ValidationResult[A]] = field(default_factory=dict) def cache_get_sync(self, val: Any) -> Maybe[ValidationResult[A]]: if val in self._dict_cache: return Just(self._dict_cache[val]) else: return nothing def cache_set_sync(self, val: Any, cache_val: ValidationResult[A]) -> None: self._dict_cache[val] = cache_val # Example usage with IntValidator cached_int_validator = DictCacheValidator(IntValidator()) # Example usage for list items validator = ListValidator(DictCacheValidator(StringValidator())) ``` -------------------------------- ### Generate Markdown Description from Koda Validator (Python) Source: https://koda-validate.readthedocs.io/en/stable/how_to/metadata This Python code defines a function `to_markdown_description` that uses pattern matching to generate a markdown description for different types of Koda Validate validators. It handles `StringValidator` and `ListValidator` with nested item validators, and includes a default case for other validator types. The example demonstrates its usage by creating a list validator with a string validator. ```python 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 _: # Handle other validator types or raise an error return "unknown validator" # Example Usage: list_validator = ListValidator(StringValidator()) print(to_markdown_description(list_validator)) ``` -------------------------------- ### Validator and ValidationResult Example (Python) Source: https://koda-validate.readthedocs.io/en/stable/how_to/results Demonstrates how a Validator, specifically IntValidator, returns a ValidationResult. It shows how to check the validity of the result and access the validated integer value. The ValidationResult[int] is equivalent to Union[Valid[int], Invalid]. ```python from koda_validate import Validator, ValidationResult, Valid, Invalid, IntValidator validator: Validator[int] = IntValidator() result = validator(5) assert result.is_valid assert isinstance(result.val, int) # mypy also knows ``result.val`` is an ``int`` result_invalid = validator("abc") assert not result_invalid.is_valid assert isinstance(result_invalid.err_type, type(TypeError)) assert result_invalid.value == "abc" assert result_invalid.validator == validator ``` -------------------------------- ### List Validation with Koda Validate Source: https://koda-validate.readthedocs.io/en/stable/_sources/index Illustrates how to create a validator for lists containing specific types using Koda Validate. This example shows nesting an IntValidator within a ListValidator to ensure all elements in a list are integers. ```python from koda_validate import ListValidator, IntValidator list_int_validator = ListValidator(IntValidator()) # Example usage (as shown in doctests): # list_int_validator([1,2,3]) ``` -------------------------------- ### Koda Validate Error Conversion Example Source: https://koda-validate.readthedocs.io/en/stable/_sources/philosophy/errors Demonstrates the usage of the `to_flat_errs` function with Koda Validate's ListValidator and TypedDictValidator. It shows how validation errors for empty and complex data structures are captured and converted into a flat list of human-readable error messages. ```python class Person(TypedDict): name: str age: int validator = ListValidator(TypedDictValidator(Person)) simple_result = validator({}) assert isinstance(simple_result, Invalid) assert to_flat_errs(simple_result) == [ FlatError(location=[], message=f"expected type ") ] complex_result = validator([None, {}, {"name": "Bob", "age": "not an int"}]) assert isinstance(complex_result, Invalid) ``` -------------------------------- ### Complex RecordValidator with Mixed Key Types Source: https://koda-validate.readthedocs.io/en/stable/how_to/dictionaries/records This example illustrates a more advanced use of `RecordValidator`, showcasing its ability to handle diverse key types, including integers, booleans, and tuples. It validates a `Person` dataclass with a name, an optional age, and a list of hobbies, demonstrating flexible input mapping. ```python from dataclasses import dataclass from koda import Maybe, Just from koda_validate import ( RecordValidator, StringValidator, KeyNotRequired, IntValidator, Valid, ListValidator, ) @dataclass class Person: name: str age: Maybe[int] hobbies: list[str] person_validator = RecordValidator( into=Person, keys=( (1, StringValidator()), (False, KeyNotRequired(IntValidator())), (("abc", 123), ListValidator(StringValidator())) ), ) assert person_validator({ 1: "John Doe", False: 30, ("abc", 123): ["reading", "cooking"] }) == Valid(Person( "John Doe", Just(30), ["reading", "cooking"] )) ``` -------------------------------- ### Implement Custom Predicate for Integer Comparison Source: https://koda-validate.readthedocs.io/en/stable/api/koda_validate Shows how to create a custom synchronous predicate by inheriting from `Predicate`. This example defines a `GreaterThan` predicate that checks if an integer is greater than a specified limit. Predicates are useful for custom validation logic. ```python 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) # Expected output: True # gt(1) # Expected output: False ``` -------------------------------- ### Define and Use RecordValidator with Dataclass Source: https://koda-validate.readthedocs.io/en/stable/how_to/dictionaries/records This snippet demonstrates how to define a `RecordValidator` using a Python `dataclass` for type hinting and structure. It handles both required and optional string and integer fields. The example shows how to match the validation result, printing the validated data or errors. ```python from dataclasses import dataclass from koda import Maybe, Just from koda_validate import ( RecordValidator, StringValidator, not_blank, MaxLength, Min, Max, IntValidator, KeyNotRequired, Invalid, Valid, ) @dataclass class Person: name: str age: Maybe[int] person_validator = RecordValidator( into=Person, keys=( ("full name", StringValidator(not_blank, MaxLength(50))), ("age", KeyNotRequired(IntValidator(Min(0), Max(130)))), ), ) match person_validator({"full name": "John Doe", "age": 30}): case Valid(person): match person.age: case Just(age): age_message = f"{age} years old" case nothing: age_message = "ageless" print(f"{person.name} is {age_message}") case Invalid(errs): print(errs) ``` -------------------------------- ### Basic String Validation with Koda Validate Source: https://koda-validate.readthedocs.io/en/stable/_sources/index Demonstrates the creation and usage of a basic StringValidator in Koda Validate. It shows how to instantiate a validator and what the output looks like for both valid and invalid string inputs. ```python from koda_validate import StringValidator my_first_validator = StringValidator() # Example usage (as shown in doctests): # my_first_validator("a string") # my_first_validator(0) ``` -------------------------------- ### koda_validate - Validator Methods Source: https://koda-validate.readthedocs.io/en/stable/index Details common methods available on validator instances. ```APIDOC ## Validator Methods This section describes common methods available on validator objects for configuring and using them. ### `validate_async()` Asynchronous method to perform validation. Subclasses implementing asynchronous logic should override this. ### `__call__()` Synchronous method to perform validation. This is the primary way to validate data using a validator instance. ``` -------------------------------- ### Basic String Validation with Koda Validate Source: https://koda-validate.readthedocs.io/en/stable/index Demonstrates the basic usage of StringValidator for validating string inputs. It shows how to create a validator and handle both valid and invalid results without raising exceptions. ```python from koda_validate import StringValidator my_first_validator = StringValidator() # Example usage: print(my_first_validator("a string")) print(my_first_validator(0)) ``` -------------------------------- ### koda_validate - Performance Optimizations Source: https://koda-validate.readthedocs.io/en/stable/index Provides tips and techniques for optimizing the performance of koda_validate. ```APIDOC ## Performance This section offers guidance on optimizing the performance of validation processes using koda_validate. ### Use asyncio for IO Leverage asynchronous I/O operations when dealing with external resources during validation. ### Initialize Validators in Outer Scopes Avoid re-initializing complex validators within loops or frequently called functions. Initialize them once in an outer scope for reuse. * **Slower**: Re-initializing validators repeatedly. * **Faster**: Reusing pre-initialized validator instances. ### Use a Cache Utilize the caching mechanisms provided by `CacheValidatorBase` to store and retrieve validation results for identical inputs. ### Look at koda_validate._internals Explore the internal implementation details for advanced performance tuning opportunities. ### Compile Parts of Koda Validate Consider pre-compiling or pre-processing validator structures where possible to reduce runtime overhead. ``` -------------------------------- ### String Validation with Preprocessing (Python) Source: https://koda-validate.readthedocs.io/en/stable/_sources/philosophy/processors Demonstrates using StringValidator with multiple preprocessors to clean and transform string input before applying validation rules like MaxLength. The preprocessors `strip` and `upper_case` are applied sequentially. ```python from koda_validate import StringValidator, MaxLength, strip, upper_case, Valid max_length_3_validator = StringValidator( MaxLength(3), preprocessors=[strip, upper_case] ) assert max_length_3_validator(" hmm ") == Valid("HMM") ``` -------------------------------- ### Custom Integer Validator in Koda Validate Source: https://koda-validate.readthedocs.io/en/stable/index Demonstrates how to create a custom validator class by subclassing Validator. This example defines an IntegerValidator that checks if a value is an integer, showcasing custom validation logic. ```python from typing import Any from koda_validate import Validator, ValidationResult, Valid, Invalid, TypeErr class IntegerValidator(Validator[int]): def __call__(self, val: Any) -> ValidationResult[int]: if isinstance(val, int): return Valid(val) else: return Invalid(TypeErr(int), val, self) # Example usage: validator = IntegerValidator() print(validator(5)) print(validator("not an integer")) ``` -------------------------------- ### Run Async Validator - Python Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/async Demonstrates the basic usage of running an asynchronous validator using the `.validate_async` method. This is the standard way to perform asynchronous validation in Koda Validate. ```python await validator.validate_async("abc") ``` -------------------------------- ### Use a Simple Float Validator Source: https://koda-validate.readthedocs.io/en/stable/how_to/extension Demonstrates how to instantiate and use the `SimpleFloatValidator`. It shows successful validation for a float and failed validation for an integer, illustrating the expected output. ```python >>> float_validator = SimpleFloatValidator() >>> float_validator(5.5) Valid(val=5.5) >>> float_validator(5) Invalid( err_type=TypeErr(expected_type=), value=5, validator= ) ``` -------------------------------- ### Fail on Unknown Keys with DataclassValidator in Python Source: https://koda-validate.readthedocs.io/en/stable/how_to/dictionaries/derived Shows how to configure DataclassValidator to fail validation if unexpected keys are present in the input dictionary by setting `fail_on_unknown_keys=True`. The example contrasts this with a validator that allows unknown keys. ```python from dataclasses import dataclass from koda_validate import DataclassValidator, Valid, Invalid @dataclass class Example: a: str b: float test_dict = {"a": "ok", "b": 2.0, "c": None} validator_no_unknown_keys = DataclassValidator(Example, fail_on_unknown_keys=True) assert isinstance(validator_no_unknown_keys(test_dict), Invalid) validator_unknown_keys_ok = DataclassValidator(Example) assert isinstance(validator_unknown_keys_ok(test_dict), Valid) ``` -------------------------------- ### Validate Nested Structures with Python Source: https://koda-validate.readthedocs.io/en/stable/how_to/dictionaries/derived Illustrates validating complex, nested data structures using TypedDictValidator, including unions, optionals, literals, and lists of custom types. This example validates a recipe structure. ```python from dataclasses import dataclass from typing import Literal, Optional, TypedDict, Union from koda_validate import TypedDictValidator, Valid @dataclass class Ingredient: quantity: Union[int, float] unit: Optional[Literal["teaspoon", "tablespoon"]] # etc... name: str class Recipe(TypedDict): title: str ingredients: list[Ingredient] instructions: str recipe_validator = TypedDictValidator(Recipe) result = recipe_validator( { "title": "Peanut Butter and Jelly Sandwich", "ingredients": [ {"quantity": 2, "unit": None, "name": "slices of bread"}, {"quantity": 2, "unit": "tablespoon", "name": "peanut butter"}, {"quantity": 4.5, "unit": "teaspoon", "name": "jelly"}, ], "instructions": "spread the peanut butter and jelly onto the bread", } ) assert isinstance(result, Valid) assert result.val["title"] == "Peanut Butter and Jelly Sandwich" ``` -------------------------------- ### Dataclass Validation with validate_object Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/dictionaries/derived This example illustrates how to perform object-level validation after individual field validation using the `validate_object` parameter in DataclassValidator. It defines a custom error class and a validation function that checks a condition on the entire object. ```python from dataclasses import dataclass from typing import Optional from koda_validate import ( DataclassValidator, Invalid, Valid, ValidationErrBase, ErrType ) @dataclass class QA: question_id: int answer: str @dataclass class WrongAnswerErr(ValidationErrBase): pass def answer_is_valid(obj: QA) -> Optional[ErrType]: # really sophisticated logic here! if obj.question_id == 100 and obj.answer == "the right answer": # success return None else: return WrongAnswerErr() validator = DataclassValidator(QA, validate_object=answer_is_valid) assert validator( {"question_id": 100, "answer": "wrong answer :("} ) == Invalid(WrongAnswerErr(), QA(100, 'wrong answer :('), validator) assert validator( {"question_id": 100, "answer": "the right answer"} ) == Valid(QA(100, 'the right answer')) ``` -------------------------------- ### Dataclass Validation with Overrides Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/dictionaries/derived This example shows how to use the `overrides` parameter in DataclassValidator to specify validators for fields without using `Annotated` types directly in the dataclass definition. This is useful for decoupling validation logic from the class structure. ```python from dataclasses import dataclass from typing import Annotated, Optional from koda_validate import DataclassValidator, IntValidator, Min, Max @dataclass class Image: height: int width: int description: Optional[str] = None validator = DataclassValidator(Image, overrides={ "height": IntValidator(Min(10), Max(1000)), "width": IntValidator(Min(10), Max(1000)) }) ``` -------------------------------- ### Complex Nested Validator with Literal and Union Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/dictionaries/derived Illustrates creating complex, nested validators using koda_validate. This example combines TypedDictValidator and DataclassValidator with Union and Literal types for intricate data structures like recipes and ingredients. ```Python from dataclasses import dataclass from typing import Literal, Optional, TypedDict, Union from koda_validate import TypedDictValidator, Valid @dataclass class Ingredient: quantity: Union[int, float] unit: Optional[Literal["teaspoon", "tablespoon"]] # etc... name: str class Recipe(TypedDict): title: str ingredients: list[Ingredient] instructions: str recipe_validator = TypedDictValidator(Recipe) result = recipe_validator( { "title": "Peanut Butter and Jelly Sandwich", "ingredients": [ {"quantity": 2, "unit": None, "name": "slices of bread"}, {"quantity": 2, "unit": "tablespoon", "name": "peanut butter"}, {"quantity": 4.5, "unit": "teaspoon", "name": "jelly"}, ], "instructions": "spread the peanut butter and jelly onto the bread", } ) assert isinstance(result, Valid) assert result.val["title"] == "Peanut Butter and Jelly Sandwich" ``` -------------------------------- ### koda_validate - Typehint Troubleshooting Source: https://koda-validate.readthedocs.io/en/stable/index Addresses common issues encountered when using koda_validate with Python type hints. -------------------------------- ### Initialize Validator Once in Python Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/performance Shows initializing a TypedDictValidator once at the module level. This pre-initialized validator is then reused, significantly improving performance by avoiding repeated instantiation. ```python class Book(TypedDict): title: str author: str # the validator is initialized once book_validator = TypedDictValidator(Book) def some_request_handler(data: Any) -> ValidationResult[Book]: return book_validator(data) ``` -------------------------------- ### IntValidator Usage with ValidationResult Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/results Demonstrates basic usage of IntValidator, showing how it returns a ValidationResult. It asserts the validity and type of the returned value. ```python from koda_validate import * validator: Validator[int] = IntValidator() result = validator(5) assert result.is_valid assert isinstance(result.val, int) # mypy also knows ``result.val`` is an ``int`` ``` -------------------------------- ### Refining String Validation with Predicates in Koda Validate Source: https://koda-validate.readthedocs.io/en/stable/index Demonstrates how to refine string validation using predicates like MinLength, MaxLength, and StartsWith. This allows for more specific validation rules beyond basic type checking. ```python from koda_validate import StringValidator, MinLength, MaxLength, StartsWith validator = StringValidator(MinLength(5), MaxLength(10), StartsWith("a")) # Example usage: print(validator("abc123")) ``` -------------------------------- ### Complex Nested Validators with TypedDicts in Koda Validate Source: https://koda-validate.readthedocs.io/en/stable/index Shows the creation of complex, deeply nested validators using TypedDictValidator, Union, Literal, and Annotated types. This example validates a 'Playlist' structure containing multiple 'Song' objects. ```python from typing import Annotated, Union, TypedDict, Literal from koda_validate import TypedDictValidator, ListValidator, MinItems class Group(TypedDict): name: str members: list[str] class Song(TypedDict): artist: Union[list[str], Group, Literal["unknown"]] title: str duration_seconds: int song_validator = TypedDictValidator(Song) songs_validator = ListValidator(song_validator, predicates=[MinItems(2)]) class Playlist(TypedDict): title: str songs: Annotated[list[Song], songs_validator] playlist_validator = TypedDictValidator(Playlist) # Example usage: stonehenge = { "artist": { "name": "Spinal Tap", "members": ["David St. Hubbins", "Nigel Tufnel", "Derek Smalls"] }, "title": "Stonehenge", "duration_seconds": 276 } drinkinstein = { "artist": ["Sylvester Stallone", "Dolly Parton"], "title": "Drinkin' Stein", "duration_seconds": 215 } print(playlist_validator({ "title": "My Favorite Songs", "songs": [stonehenge, drinkinstein] })) ``` -------------------------------- ### Basic Function Validation with @validate_signature Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/runtime_type_checking Demonstrates the fundamental usage of the @validate_signature decorator to validate function arguments and return types based on type hints. It shows a simple 'add' function and how invalid arguments trigger an InvalidArgsError. ```python from koda_validate.signature import validate_signature @validate_signature def add(x: int, y: int) -> int: return x + y ``` -------------------------------- ### Create and Use Person Validator Source: https://koda-validate.readthedocs.io/en/stable/_sources/how_to/dictionaries/records Demonstrates creating a RecordValidator for a Person dataclass with required and optional string and integer fields. It shows how to validate a dictionary against this schema and handle the Valid and Invalid cases. ```python from dataclasses import dataclass from koda import Maybe, Just from koda_validate import ( RecordValidator, StringValidator, not_blank, MaxLength, Min, Max, IntValidator, KeyNotRequired, Invalid, Valid ) @dataclass class Person: name: str age: Maybe[int] person_validator = RecordValidator( into=Person, keys=( ("full name", StringValidator(not_blank, MaxLength(50))), ("age", KeyNotRequired(IntValidator(Min(0), Max(130)))), ), ) match person_validator({"full name": "John Doe", "age": 30}): case Valid(person): match person.age: case Just(age): age_message = f"{age} years old" case nothing: age_message = "ageless" print(f"{person.name} is {age_message}") case Invalid(errs): print(errs) ``` -------------------------------- ### Sync and Async String Validation with Koda Validate Source: https://koda-validate.readthedocs.io/en/stable/_sources/philosophy/async Demonstrates how the same StringValidator can be used for both synchronous and asynchronous validation. It shows the typical return for sync and the usage of asyncio.run for async validation. ```python import asyncio from koda_validate import StringValidator str_validator = StringValidator() # Synchronous usage print(str_validator("a string")) # Asynchronous usage async def run_async_validation(): print(await str_validator.validate_async("a string")) asyncio.run(run_async_validation()) ```