Skip to content

valgebra

Fast runtime validation through a closed Boolean algebra of schemas.

A schema denotes a set of Python values. Validation is membership: you ask whether the object you already hold belongs to the set — no copy, no coercion. Schemas compile once into a Rust validator tree, and the hot path crosses into Rust exactly once per call.

from typing import Annotated, TypedDict

import annotated_types as at

from valgebra import Validator


class User(TypedDict):
    name: str
    age: Annotated[int, at.Ge(0)]


users = Validator(User)
assert users.is_valid({"name": "Ada", "age": 36})
assert not users.is_valid({"name": "Ada", "age": -1})

Pre-alpha

valgebra is under active development and published to PyPI. The APIs described here work today but may change before a stable 0.1.0 release. See the changelog for what is built.

What valgebra is for

valgebra is a contracts-and-checking tool, not a parsing framework. Reach for it when you want to check an object you already hold against a composable, inspectable contract — cheaply enough to run on every request or every agent turn.

For ingesting untrusted input into typed models with coercion and defaults, use pydantic; for the fastest deserialization into structs, use msgspec. valgebra occupies the niche neither covers: a closed, lawful algebra of schemas (union, intersection, complement, refinement, fixpoints) with check-only semantics, on a Rust core.

What makes it different

  • Schemas denote sets; validation is membership. Subtyping is set inclusion and equivalence is mutual inclusion — decided soundly over a wide fragment and deliberately conservative beyond it. The whole model is one idea.
  • A real Boolean algebra. union, intersection, and complement compose any schema into a lattice whose laws are property-tested, with a law-justified simplifier that never changes a schema's value set.
  • Typing-first. Standard annotations are the primary notation, read through the typing spec's own introspection.
  • Check, don't parse. validate and is_valid never copy or coerce; ensure is the explicit, separate conversion mode.
  • Few boundary crossings. Tree walks, key lookups, and bound checks run in Rust; a comparison against a Python object — a literal, a refinement predicate, or an instance or attribute check — is the documented step into Python, never a silent fallback.
  • JSON on the Rust path. validate_json parses and validates JSON in Rust, consistent with the object path.
  • Immutable and thread-safe by design. Free-threaded CPython 3.14 is supported with a dedicated cp314t wheel where the release image exposes that interpreter.

Where to go next