examples.18_custom_sanitizer_transform

Demonstrates a multi-step sanitization and validation pipeline that trims and lowercases user input before applying type and enumeration validation.

This example shows:
  • How to compose multiple string preprocessing transformations.
  • How to validate cleaned strings against an allowed list of values.
  • How a value passes through sequential strategies before validation.
Run directly:

python examples/18_custom_sanitizer_transform.py

Expected output:

x: OK apple y: EXCEPTION Value must be one of ('apple', 'pear', 'plum'), got banana

  1"""Demonstrates a multi-step sanitization and validation pipeline that trims
  2and lowercases user input before applying type and enumeration validation.
  3
  4This example shows:
  5  * How to compose multiple string preprocessing transformations.
  6  * How to validate cleaned strings against an allowed list of values.
  7  * How a value passes through sequential strategies before validation.
  8
  9Run directly:
 10
 11    python examples/18_custom_sanitizer_transform.py
 12
 13Expected output:
 14
 15    x: OK apple
 16    y: EXCEPTION Value must be one of ('apple', 'pear', 'plum'), got banana
 17"""
 18
 19import sys
 20import pathlib
 21from typing import List
 22
 23# ---------------------------------------------------------------------------
 24# Make repo root importable when running this file directly
 25# ---------------------------------------------------------------------------
 26sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1]))
 27
 28from constrained_values import Response, Status, TypeValidationStrategy, EnumValidationStrategy
 29from constrained_values.value import TransformationStrategy, ConstrainedValue, PipeLineStrategy
 30
 31
 32class Trim(TransformationStrategy[str, str]):
 33    """A transformation that removes leading and trailing whitespace."""
 34
 35    def transform(self, value: str) -> Response[str]:
 36        """Trim the input string.
 37
 38        Args:
 39            value: The input string.
 40
 41        Returns:
 42            Response[str]: Contains:
 43                * `status = Status.OK`
 44                * `details = "trim"`
 45                * `value` — the trimmed string
 46        """
 47        return Response(status=Status.OK, details="trim", value=value.strip())
 48
 49
 50class Lower(TransformationStrategy[str, str]):
 51    """A transformation that converts input text to lowercase."""
 52
 53    def transform(self, value: str) -> Response[str]:
 54        """Convert the string to lowercase.
 55
 56        Args:
 57            value: The input string.
 58
 59        Returns:
 60            Response[str]: Contains:
 61                * `status = Status.OK`
 62                * `details = "lower"`
 63                * `value` — the lowercase string
 64        """
 65        return Response(status=Status.OK, details="lower", value=value.lower())
 66
 67
 68class CleanFruit(ConstrainedValue[str]):
 69    """A constrained string value that sanitizes and validates fruit names.
 70
 71    The transformation pipeline performs the following steps:
 72        1. `Trim()` — remove leading/trailing spaces.
 73        2. `Lower()` — convert to lowercase.
 74        3. `TypeValidationStrategy(str)` — ensure the value is a string.
 75        4. `EnumValidationStrategy(("apple", "pear", "plum"))` — check membership.
 76
 77    Inputs that pass all transformations and validations yield `Status.OK`.
 78    """
 79
 80    def get_strategies(self) -> List[PipeLineStrategy]:
 81        """Return the sanitization and validation pipeline."""
 82        return [
 83            Trim(),
 84            Lower(),
 85            TypeValidationStrategy(str),
 86            EnumValidationStrategy(("apple", "pear", "plum")),
 87        ]
 88
 89
 90def main() -> None:
 91    """Run the custom sanitizer demonstration.
 92
 93    Creates two :class:`CleanFruit` constrained values:
 94        1. Input `"  Apple  "` — trimmed, lowercased, and validated → OK.
 95        2. Input `" Banana "` — not in the allowed list → EXCEPTION.
 96
 97    Prints:
 98        * `"x: OK apple"`
 99        * `"y: EXCEPTION Value must be one of ('apple', 'pear', 'plum'), got banana"`
100    """
101    x = CleanFruit("  Apple  ")
102    y = CleanFruit(" Banana ")
103    print("x:", x.status.name, x.value)
104    print("y:", y.status.name, y.details)
105
106
107if __name__ == "__main__":
108    main()
class Trim(constrained_values.value.TransformationStrategy[str, str]):
33class Trim(TransformationStrategy[str, str]):
34    """A transformation that removes leading and trailing whitespace."""
35
36    def transform(self, value: str) -> Response[str]:
37        """Trim the input string.
38
39        Args:
40            value: The input string.
41
42        Returns:
43            Response[str]: Contains:
44                * `status = Status.OK`
45                * `details = "trim"`
46                * `value` — the trimmed string
47        """
48        return Response(status=Status.OK, details="trim", value=value.strip())

A transformation that removes leading and trailing whitespace.

def transform(self, value: str) -> constrained_values.Response[str]:
36    def transform(self, value: str) -> Response[str]:
37        """Trim the input string.
38
39        Args:
40            value: The input string.
41
42        Returns:
43            Response[str]: Contains:
44                * `status = Status.OK`
45                * `details = "trim"`
46                * `value` — the trimmed string
47        """
48        return Response(status=Status.OK, details="trim", value=value.strip())

Trim the input string.

Arguments:
  • value: The input string.
Returns:

Response[str]: Contains: * status = Status.OK * details = "trim" * value — the trimmed string

class Lower(constrained_values.value.TransformationStrategy[str, str]):
51class Lower(TransformationStrategy[str, str]):
52    """A transformation that converts input text to lowercase."""
53
54    def transform(self, value: str) -> Response[str]:
55        """Convert the string to lowercase.
56
57        Args:
58            value: The input string.
59
60        Returns:
61            Response[str]: Contains:
62                * `status = Status.OK`
63                * `details = "lower"`
64                * `value` — the lowercase string
65        """
66        return Response(status=Status.OK, details="lower", value=value.lower())

A transformation that converts input text to lowercase.

def transform(self, value: str) -> constrained_values.Response[str]:
54    def transform(self, value: str) -> Response[str]:
55        """Convert the string to lowercase.
56
57        Args:
58            value: The input string.
59
60        Returns:
61            Response[str]: Contains:
62                * `status = Status.OK`
63                * `details = "lower"`
64                * `value` — the lowercase string
65        """
66        return Response(status=Status.OK, details="lower", value=value.lower())

Convert the string to lowercase.

Arguments:
  • value: The input string.
Returns:

Response[str]: Contains: * status = Status.OK * details = "lower" * value — the lowercase string

class CleanFruit(constrained_values.value.ConstrainedValue[str]):
69class CleanFruit(ConstrainedValue[str]):
70    """A constrained string value that sanitizes and validates fruit names.
71
72    The transformation pipeline performs the following steps:
73        1. `Trim()` — remove leading/trailing spaces.
74        2. `Lower()` — convert to lowercase.
75        3. `TypeValidationStrategy(str)` — ensure the value is a string.
76        4. `EnumValidationStrategy(("apple", "pear", "plum"))` — check membership.
77
78    Inputs that pass all transformations and validations yield `Status.OK`.
79    """
80
81    def get_strategies(self) -> List[PipeLineStrategy]:
82        """Return the sanitization and validation pipeline."""
83        return [
84            Trim(),
85            Lower(),
86            TypeValidationStrategy(str),
87            EnumValidationStrategy(("apple", "pear", "plum")),
88        ]

A constrained string value that sanitizes and validates fruit names.

The transformation pipeline performs the following steps:
  1. Trim() — remove leading/trailing spaces.
  2. Lower() — convert to lowercase.
  3. TypeValidationStrategy(str) — ensure the value is a string.
  4. EnumValidationStrategy(("apple", "pear", "plum")) — check membership.

Inputs that pass all transformations and validations yield Status.OK.

def get_strategies(self) -> List[constrained_values.value.PipeLineStrategy]:
81    def get_strategies(self) -> List[PipeLineStrategy]:
82        """Return the sanitization and validation pipeline."""
83        return [
84            Trim(),
85            Lower(),
86            TypeValidationStrategy(str),
87            EnumValidationStrategy(("apple", "pear", "plum")),
88        ]

Return the sanitization and validation pipeline.

Inherited Members
constrained_values.value.ConstrainedValue
ConstrainedValue
status
details
value
unwrap
ok
def main() -> None:
 91def main() -> None:
 92    """Run the custom sanitizer demonstration.
 93
 94    Creates two :class:`CleanFruit` constrained values:
 95        1. Input `"  Apple  "` — trimmed, lowercased, and validated → OK.
 96        2. Input `" Banana "` — not in the allowed list → EXCEPTION.
 97
 98    Prints:
 99        * `"x: OK apple"`
100        * `"y: EXCEPTION Value must be one of ('apple', 'pear', 'plum'), got banana"`
101    """
102    x = CleanFruit("  Apple  ")
103    y = CleanFruit(" Banana ")
104    print("x:", x.status.name, x.value)
105    print("y:", y.status.name, y.details)

Run the custom sanitizer demonstration.

Creates two CleanFruit constrained values: 1. Input " Apple " — trimmed, lowercased, and validated → OK. 2. Input " Banana " — not in the allowed list → EXCEPTION.

Prints:
  • "x: OK apple"
  • "y: EXCEPTION Value must be one of ('apple', 'pear', 'plum'), got banana"