Lightweight, zero-dependency Python library for validating dictionaries with optional coercion and custom rules
Project description
Pyvalidly
Pyvalidly is a lightweight, zero-dependency Python library for validating dictionaries with simple rules, custom functions, and optional coercion.
Inspired by Pydantic's power but built for simplicity, speed, and flexibility — especially useful when you want to avoid creating full-blown classes.
Features
- Simple schema-based dictionary validation
- Type validation – int, str, float, list, dict, custom classes.
- Coercion – Automatically convert types when possible.
- Default values – Fill missing fields with defaults.
- Conditional validation – Skip validation based on another field.
- Custom validation functions – Pass any callable returning True/False.
- Helper functions – is_email, is_url, min_value, max_value, min_length, max_length.
- Custom error messages – Per-field validation errors.
- Old-style and new-style schemas – Flexible for migration.
Installation
pip install pyvalidly
Basic Usage
Old-style Schema
from pyvalidly import validate, is_email
schema = {
"name": str, #(str,),
"age": (int, lambda x: x > 18),
"email": (str, is_email)
}
data = {
"name": "John",
"age": 25,
"email": "john@example.com"
}
validated = validate(data, schema)
print(validated)
# {'name': 'John', 'age': 25, 'email': 'john@example.com'}
New-style Schema
from pyvalidly import validate, is_email, min_value
schema = {
"name": {"type": str, "required": True},
"age": {"type": int, "coerce": True, "rules": [min_value(18)]},
"email": {"type": str, "rules": [is_email]}
}
data = {
"name": "John",
"age": "42",
"email": "john@example.com"
}
validated = validate(data,schema)
print(validated)
# {'name': 'John', 'age': 42, 'email': 'john@example.com'}
Advanced Features
1. Type Coercion
from pyvalidly import validate, is_email, min_value
schema = {
"age": {"type": int, "coerce": True}
}
data = {"age": "30"}
print(validate(data,schema))
# {'age': 30}
2. Default Values
from pyvalidly import validate, is_email, min_value
schema = {
"name": {"type": str, "default": "Anonymous"}
}
data = {}
print(validate(data,schema))
# {'name': 'Anonymous'}
3. Conditional Validation
from pyvalidly import validate, is_email, min_value
schema = {
"is_member": {"type": bool, "required": True},
"membership_id": {
"type": str,
"required": True,
"condition": lambda data: data.get("is_member") is True
}
}
data = {"is_member": False}
print(validate(data, schema))
# {'is_member': False}
4. Custom Error Messages
from pyvalidly import validate, is_email, min_value
schema = {
"age": {
"type": int,
"rules": [lambda x: x >= 18],
"error": "Must be at least 18 years old"
}
}
data = {"age": 10}
from pyvalidly.exceptions import ValidationError
try:
print(validate(data, schema))
except ValidationError as e:
print(e)
# Must be at least 18 years old
5. Built-in Helpers
from pyvalidly import is_email, is_url, min_value, max_value, min_length, max_length
print(is_email("test@example.com")) # True
print(is_url("http://example.com")) # True
print(min_value(10)(15)) # True
print(max_length(5)("hello")) # True
Schema Styles
-
Old-style tuple rules : Each field maps to a tuple of rules: (type, func, func, ...)
-
New-style dict rules : { "type": str, "required": True, "default": "X", "rules": [func], "coerce": True, "condition": func }
Project Structure
pyvalidly/
├── core.py
├── exceptions.py
├── validators.py
├── __init__.py
└── tests/
└── test_core.py
License
MIT License
Contribute
Pull requests, suggestions, and stars are welcome! If this helped you, consider supporting the project.
Contact
Made with love by Deepak singh — https://github.com/dark00infinity
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyvalidly-1.0.1.tar.gz.
File metadata
- Download URL: pyvalidly-1.0.1.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c8e4e5c5e6e771cbfb5be8d8d5ddf8b8dc7e1dd644ea8b906c7f326f7e00d565
|
|
| MD5 |
60cdd1d434fc1539636819f1f0c96df9
|
|
| BLAKE2b-256 |
307c4fcc2d5a8ff82c41c128e4a4b8987d840dc9c828608c17f1a00fe7bae869
|
File details
Details for the file pyvalidly-1.0.1-py3-none-any.whl.
File metadata
- Download URL: pyvalidly-1.0.1-py3-none-any.whl
- Upload date:
- Size: 9.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7baa9b6285bd8e9510e368ef2d7f9eae406b7e0718beb77a9b531a7fd494012a
|
|
| MD5 |
4ddbfaf6e90913433c66c949ec271150
|
|
| BLAKE2b-256 |
88147f9399453c1f4f7d1842fbbc6b10a836ed06ffa1b01b82f336608c1f1800
|