Skip to content

Probatio is a modern, maintained data validation library for Python, and a clean-room reimplementation of voluptuous: the same API, written fresh. Change the import, keep your schemas, and get a library that is actively maintained, MIT licensed, and validated against voluptuous’s own behavior. Then, when you want more, it is already there.

The model stays the same as voluptuous: a schema is data, and data describes data. You compose schemas from plain Python types, dicts, lists, and small helpers, then call the schema with a value to validate it.

Created and written by Franck Nijhof, also known as Frenck.

Drop-in compatible

The public API mirrors voluptuous: Schema, Required, Optional, All, Any, Coerce, Invalid, and the rest. Change the import, keep your schemas. voluptuous’s own 0.16.0 test suite runs green against it.

More than a replacement

It also clears voluptuous’s backlog: cross-field rules, dataclass and TypedDict schemas, network and format validators, and errors that carry a path and suggest the key you meant. Several are voluptuous’s own open requests, finally shipped.

Proven, not promised

100% line and branch coverage, two type checkers, and continuous fuzzing on every untrusted-input surface. It is also safer than the original: leaks and RecursionError edges voluptuous has are fixed, and documented.

Typed and modern

Ships py.typed, checked under mypy and ty, pure Python with no native build. Loads JSON, YAML, and TOML, and exports JSON Schema and OpenAPI.

Define a schema, then call it with a value to validate it:

from probatio import Schema, Required, Optional
schema = Schema(
{
Required("name"): str,
Optional("age"): int,
}
)
schema({"name": "Frenck", "age": 40})
# {'name': 'Frenck', 'age': 40}

When a value does not match, the schema raises Invalid (or MultipleInvalid) with a path to the offending value:

from probatio import Schema, Invalid
schema = Schema({"port": int})
try:
schema({"port": "nope"})
except Invalid as err:
print(err)
# expected int for dictionary value @ data['port']

It is a config-loading library, so the bar is whether you would hand it untrusted input. The evidence, not the adjectives:

  • voluptuous 0.16.0 test suite: 140 pass, 27 deliberate and documented deviations. voluptuous’s own authors’ notion of the contract, run against Probatio.
  • Home Assistant config_validation: 142 of 142 pass, with voluptuous swapped out for Probatio.
  • 100% line and branch coverage, type-checked under both mypy and ty, in CI.
  • Fuzzed on every untrusted-input surface. The first fuzzing pass found hundreds of exception leaks on hostile input. All fixed; none since.
  • Safer than the original. A built-in validator only ever raises Invalid, never a raw exception, and that is enforced, not hoped for.

Probatio aims to be a drop-in replacement. In most cases the migration is a one-line import change. See migrating from voluptuous for the details and the current compatibility status.