YuPy - Python Schema Validation Library
Dead simple object schema validation for Python
Inspired by yup js library
YuPy is a schema builder for runtime value parsing and validation. Define a schema, transform a value to match, assert the shape of an existing value, or both. YuPy schemas are extremely expressive and allow modeling complex, interdependent validations or value transformations.
📋 Table of Contents
- YuPy - Python Schema Validation Library
🔧 Features
- ✅ Schema-based validation: strings, numbers, arrays, dictionaries
- 🔍 Type checking
- ❓ Nullability control (
None) - 🔄 Value transformation
- 🧪 Custom validators
- 🧾 Detailed error reporting
- 🌐 Locale support
- 🔌 Built-in adapters:
default,required,immutable - 📏 Comparison and size constraints
- 🔁 Mixed types and Union schema support
📦 Installation
pip install yupy
🚀 Usage
Basic validation
from yupy import string, number
string().min(3).max(10).validate("hello") # ✅
number().positive().integer().validate(42) # ✅
Nullability
string().nullable().validate(None) # ✅
Arrays
from yupy import array
array().of(string().min(2)).min(1).validate(["ok", "yes"])
Dictionaries (Mappings)
from yupy import mapping
user_schema = mapping().shape({
"name": string().min(3),
"age": number().ge(18)
})
Union
from yupy import union
union().one_of([string(), number()]).validate("hello")
union().one_of([string(), number()]).validate(10)
🧩 Adapters
required
from yupy import required
required(string().min(3)).validate("abc")
default
from yupy import default
default("N/A", string()).validate(None) # → "N/A"
immutable
from yupy import immutable
immutable(string()).validate("data") # -> creates deep copy
📘 API Reference
Base Schema
Inheritance: Schema (implements ISchema)
Base class for all schema types providing core validation functionality.
| Method | Description |
|---|---|
nullable() -> Self |
Makes the schema accept None values |
not_nullable(message: ErrorMessage = None) -> Self |
Explicitly disallows None values with custom message |
test(func: ValidatorFunc) -> Self |
Adds a custom validation function |
const(value: Any, message: ErrorMessage = None) -> Self |
Validates that the value equals a constant |
transform(func: TransformFunc) -> Self |
Adds a transformation function |
validate(value: Any, abort_early: bool = True, path: str = "~") -> Any |
Validates the value against the schema |
Sized Schema
Inheritance: Schema → SizedSchema (implements ISizedSchema)
Provides size-based validation methods for sequences and collections.
| Method | Description |
|---|---|
length(limit: int, message: ErrorMessage = None) -> Self |
Validates exact length |
min(limit: int, message: ErrorMessage = None) -> Self |
Validates minimum length |
max(limit: int, message: ErrorMessage = None) -> Self |
Validates maximum length |
Comparable Schema
Inheritance: Schema → ComparableSchema (implements IComparableSchema)
Provides comparison-based validation methods.
| Method | Description |
|---|---|
le(limit: Any, message: ErrorMessage = None) -> Self |
Validates value ≤ limit |
ge(limit: Any, message: ErrorMessage = None) -> Self |
Validates value ≥ limit |
lt(limit: Any, message: ErrorMessage = None) -> Self |
Validates value < limit |
gt(limit: Any, message: ErrorMessage = None) -> Self |
Validates value > limit |
eq(value: Any, message: ErrorMessage = None) -> Self |
Validates value equals specified value |
ne(value: Any, message: ErrorMessage = None) -> Self |
Validates value not equals specified value |
String Schema
Inheritance: Schema → SizedSchema, ComparableSchema, EqualityComparableSchema → StringSchema
Validates string values with text-specific methods.
| Method | Description |
|---|---|
email(message: ErrorMessage = None) -> Self |
Validates email format |
url(message: ErrorMessage = None) -> Self |
Validates URL format |
uuid(message: ErrorMessage = None) -> Self |
Validates UUID format |
matches(regex: re.Pattern, message: ErrorMessage = None, exclude_empty: bool = False) -> Self |
Validates against regex pattern |
lowercase(message: ErrorMessage = None) -> Self |
Validates string is lowercase |
uppercase(message: ErrorMessage = None) -> Self |
Validates string is uppercase |
ensure() -> Self |
Transforms empty/null values to empty string |
Number Schema
Inheritance: Schema → ComparableSchema, EqualityComparableSchema → NumberSchema
Validates numeric values (int, float) with number-specific methods.
| Method | Description |
|---|---|
positive(message: ErrorMessage = None) -> Self |
Validates number > 0 |
negative(message: ErrorMessage = None) -> Self |
Validates number < 0 |
integer(message: ErrorMessage = None) -> Self |
Validates number is integer (no decimals) |
multiple_of(multiplier: Union[int, float], message: ErrorMessage = None) -> Self |
Validates number is multiple of specified value |
Array Schema
Inheritance: Schema → SizedSchema, ComparableSchema, EqualityComparableSchema → ArraySchema
Validates list and tuple values.
| Method | Description |
|---|---|
of(schema: Union[ISchema, ISchemaAdapter], message: ErrorMessage = None) -> Self |
Validates all array elements against schema |
Mapping Schema
Inheritance: Schema → EqualityComparableSchema → MappingSchema
Validates dictionary/mapping values with object shape validation.
| Method | Description |
|---|---|
shape(fields: Dict[str, Union[ISchema, ISchemaAdapter]]) -> Self |
Defines the expected shape/structure |
strict(is_strict: bool = True, message: ErrorMessage = None) -> Self |
Disallows unknown keys when True |
Mixed Schema
Inheritance: Schema → EqualityComparableSchema → MixedSchema
Validates values of any type with flexible type checking.
| Method | Description |
|---|---|
of(type_or_types: _SchemaExpectedType, message: ErrorMessage = None) -> Self |
Validates value is of specified type(s) |
one_of(items: Iterable, message: ErrorMessage = None) -> Self |
Validates value is one of the specified items |
Union Schema
Inheritance: Schema → EqualityComparableSchema → UnionSchema
Validates values that can match one of multiple schemas.
| Method | Description |
|---|---|
one_of(options: list[Union[ISchema, ISchemaAdapter]], message: ErrorMessage = None) -> Self |
Validates value matches at least one of the provided schemas |
🛠 Extending
Custom Validator
from yupy import string, ValidationError
def is_palindrome(value):
if value != value[::-1]:
raise ValidationError("Not a palindrome")
string().test(is_palindrome).validate("madam")
Custom Adapter
from yupy import SchemaAdapter, string
class CustomAdapter(SchemaAdapter):
def validate(self, value, abort_early=True, path="~"):
# Custom logic before validation
result = super().validate(value, abort_early, path)
# Custom logic after validation
return result
# Usage
custom = CustomAdapter(string().min(3))
custom.validate("hello")
✅ Running Tests
pytest
🤝 Contributing
Contributions are welcome! Please open issues or submit pull requests.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
MIT License
Copyright (c) YuPy Contributors
Metadata
Release files for yupy 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| yupy-0.2.0.tar.gz | 98.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| yupy-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 134.8 kB
Release files / yupy-0.2.0.tar.gz
| Download URL | yupy-0.2.0.tar.gz |
|---|---|
| Size | 98.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2cb50a3b95c21c8457cd8f388ddd8b7fed85d6fa3033d874e947b14e5fc69eb4
|
|
BLAKE2b-256 checksum How to use checksums |
90103746114a0904cee22ba7f0482b1074e8d6bde34177da15425bde35949b86
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / yupy-0.2.0-py3-none-any.whl
| Download URL | yupy-0.2.0-py3-none-any.whl |
|---|---|
| Size | 36.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ca9981415381ff3dbfeb02c216a7d274b00ac39ddbd4cac10c30d698d040bc17
|
|
BLAKE2b-256 checksum How to use checksums |
fc4f1c44e5d5c1009ffaff122ea3689a0ff6952bf98a430052b360003c343e93
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|