valify
A composable, expressive data validation library for Python.
Installation
pip install valify
Quick Start
from valify import Schema, StringValidator, IntValidator, EmailValidator
schema = Schema({
"name": StringValidator(min_length=2, max_length=50),
"age": IntValidator(min_value=0, max_value=120),
"email": EmailValidator(),
})
# Valid data — returns cleaned, validated dictionary
result = schema.validate({
"name": "Alice",
"age": 30,
"email": "alice@example.com",
})
print(result)
# {'name': 'Alice', 'age': 30, 'email': 'alice@example.com'}
# Invalid data — raises ValidationError with ALL errors at once
schema.validate({
"name": "A",
"age": -5,
"email": "not-an-email",
})
# ValidationError: Validation failed:
# name: Must be at least 2 characters long.
# age: Must be at least 0.
# email: 'not-an-email' is not a valid email address.
Validators
| Validator | What it checks |
|---|---|
StringValidator |
Strings, with optional min/max length |
IntValidator |
Integers, with optional min/max value |
FloatValidator |
Floats, with optional min/max value |
BoolValidator |
Booleans, with optional string coercion |
EmailValidator |
Email address format |
OptionalValidator |
Wraps any validator and makes it optional |
ListValidator |
Validates every item in a list |
EnumValidator |
Value must be one of a fixed set of choices |
RegexValidator |
Value must match against a given regex |
Validators in Detail
StringValidator
from valify import StringValidator
v = StringValidator(
min_length=2, # minimum character length
max_length=50, # maximum character length
strip=True, # strip whitespace before validating (default: True)
)
IntValidator
from valify import IntValidator
v = IntValidator(
min_value=0, # minimum allowed value
max_value=120, # maximum allowed value
coerce=False, # if True, converts "42" -> 42 (default: False)
)
EmailValidator
from valify import EmailValidator
v = EmailValidator()
v.validate("alice@example.com") # returns "alice@example.com"
Using Validators Standalone
Validators work without a Schema too:
from valify import IntValidator
from valify.exceptions import ValidationError
v = IntValidator(min_value=0)
try:
v.validate(-1)
except ValidationError as e:
print(e.message) # Must be at least 0.
print(e.value) # -1
Nested Schemas
Schemas can be nested inside other schemas for validating complex data:
from valify import Schema, StringValidator, IntValidator
address_schema = Schema({
"street": StringValidator(min_length=2),
"city": StringValidator(min_length=2),
"pin": StringValidator(min_length=6, max_length=6),
})
user_schema = Schema({
"name": StringValidator(min_length=2),
"age": IntValidator(min_value=0),
"address": address_schema,
})
user_schema.validate({
"name": "Darshan",
"age": 20,
"address": {
"street": "MG Road",
"city": "Pune",
"pin": "411001",
}
})
Schema Utilities
is_valid()
Checks whether the provided data is valid without raising exceptions.
Returns True when validation succeeds and False otherwise.
Example
if schema.is_valid(data):
process(data)
Valid data:
schema.is_valid(
{
"name": "Darshan",
"age": 21,
}
)
# True
Invalid data:
schema.is_valid(
{
"name": "",
"age": 15,
}
)
# False
errors()
Returns validation errors as a dictionary instead of raising an exception.
This is useful when building APIs, forms, CLIs, or user-facing validation flows.
Example
errors = schema.errors(data)
if errors:
return {"errors": errors}
Input:
{
"name": "",
"age": 15,
}
Output:
{
"name": "Name cannot be empty",
"age": "Value must be at least 18",
}
When validation succeeds:
schema.errors(valid_data)
# {}
Invalid Root Data
Schemas expect a dictionary as input.
schema.errors(["invalid"])
Output:
{
"__root__": "Expected a dictionary, got 'list'"
}
Error Handling
from valify.exceptions import (
ValifyError, # base — catches everything
ValidationError, # a value failed validation
RequiredFieldError, # a required field was missing
SchemaError, # the schema definition is invalid
)
Version History
- 0.8.0 — Added
RegexValidatorand security add-ons - 0.7.0 — Added
to_json_schema()on all validators and Schema - 0.6.0 — Added
Schema.from_example() - 0.5.0 — Added Documentation using sphinx
- 0.4.0 — Added nested schema support
- 0.3.0 — Added
OptionalValidator,ListValidator,EnumValidator - 0.2.0 — Full type hints and mypy compatibility
- 0.1.0 — Initial release
License
MIT
Release files for valify 0.8.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 | |
|---|---|---|---|
| valify-0.8.0.tar.gz | 16.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| valify-0.8.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.8 kB
Release files / valify-0.8.0.tar.gz
| Download URL | valify-0.8.0.tar.gz |
|---|---|
| Size | 16.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f96d03334c274bf8bc5580a21b209adf9c88dd465888ab27fff4cdc0b1626e4c
|
|
BLAKE2b-256 checksum How to use checksums |
6b07021559946809548ac489662b66a28f9bf45c8fb06d992e0ef7dd2f22161b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Release files / valify-0.8.0-py3-none-any.whl
| Download URL | valify-0.8.0-py3-none-any.whl |
|---|---|
| Size | 12.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9e96da04e597e6e42aea353fd56a0075400646d955d3c6a4576cdbb7d1cd79a1
|
|
BLAKE2b-256 checksum How to use checksums |
65a1d410fc3db328f5718d0a7977d13aec453cf5f516050c61d54d953413c947
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|