Quick start
A schema describes the shape of valid data. You build one from plain Python types and a few helpers, then call it with a value. A valid value comes back (possibly normalized); an invalid one raises an error that points at what went wrong.
Probatio not installed yet? Start with installation.
Your first schema
Section titled “Your first schema”from probatio import Schema, Required, Optional
schema = Schema( { Required("name"): str, Optional("port", default=8080): int, })
schema({"name": "app"}) # {'name': 'app', 'port': 8080}Two things happened there. name was required, so leaving it out would fail.
port was optional with a default, so it was filled in. The result is a new
dict; the input is not mutated.
Normalizing as you validate
Section titled “Normalizing as you validate”A schema does not only check, it can convert. Coerce turns the value into a
type, and the converted value is what you get back:
from probatio import Schema, Coerce, All, Range
port = Schema(All(Coerce(int), Range(min=1, max=65535)))
port("443") # 443All runs its validators in order and feeds each result into the next, so the
string becomes an int and then the int is range-checked.
Handling failures
Section titled “Handling failures”When validation fails, the schema raises MultipleInvalid (a subclass of
Invalid) with a path to the value that did not match, rendered as a dotted
trail into the nested data:
from probatio import Schema, Invalid
schema = Schema({"server": {"port": int}})
try: schema({"server": {"port": "nope"}})except Invalid as err: print(err) # expected int at 'server.port'Catching Invalid catches every validation error, because everything Probatio
raises for bad data is a subclass of it. The error handling
guide goes deeper into paths, multiple errors at once,
and human-readable messages.
Where to next
Section titled “Where to next”- Migrating from voluptuous: swap your imports and keep your schemas.
- The validation model: how schemas are built and what can go inside one.
- Dict schemas and markers: required and optional keys, defaults, and extra-key policy.
- Validating a config file: a worked end-to-end example.
- Dataclasses and TypedDict: skip writing the schema when the type already says it.
- JSON Schema and OpenAPI: export what you validate.
- Performance: fast for pure Python, with an opt-in compiled mode.
- API reference: the full public surface.