zodify
Validation for Python dictionaries.
zodify validates configuration and script inputs using ordinary Python types. It is written in pure Python with zero required runtime dependencies.
Documentation | Choosing a validator | PyPI | Changelog
Install
pip install zodify
Supports Python 3.10–3.13. The project is in alpha. These examples describe 0.8.0, published and verified September 9, 2026. See the compatibility contract for supported behavior and the path to 1.0.
Quick Start
from zodify import validate
schema = {"port": int, "debug": bool}
validate(schema, {"port": 8080, "debug": False})
# {'port': 8080, 'debug': False}
validate(schema, {"port": "8080", "debug": False})
# ValueError: port: expected int, got str
A dictionary schema returns a new dictionary. Types are strict by default:
"8080" is a string, so it fails an int check. Failures raise ValueError
with a path to the field. Extra keys are rejected.
Choosing a validator
| Use cases for zodify | Reasons to consider another approach |
|---|---|
| You already have dictionaries and want reusable checks. | A few direct Python checks already solve the task. |
| You validate configuration, CLI input, or data in scripts. | Your framework already provides the validation you need. |
| Zero required runtime dependencies matter. | You need a broader annotation vocabulary, model features, or specialized serialization. |
Pydantic supports both models and TypeAdapter for ordinary types, including
dictionaries. Use a dedicated JSON Schema implementation when a JSON Schema
document is your validation language. The
comparison guide explains the tradeoffs.
Schemas
Use nested dictionaries, single-element lists, unions, and optional keys as needed:
from zodify import Optional, validate
schema = {
"db": {"host": str, "port": Optional(int, 5432)},
"tags": [str],
"debug": Optional(bool, False),
}
validate(schema, {"db": {"host": "localhost"}, "tags": ["prod"]})
# {'db': {'host': 'localhost', 'port': 5432}, 'tags': ['prod'], 'debug': False}
Conversions are explicit. For string inputs such as configuration values:
validate({"port": int}, {"port": "8080"}, coerce=True)
# {'port': 8080}
Schema grammar and conversion rules cover the details.
Validation behavior
- Strict types: ordinary validation does not coerce values.
boolandintare distinct. Setcoerce=Trueto opt into the documented conversions. - Unknown keys: rejected by default.
unknown_keys="strip"drops them. - Missing versus null:
Optional(type)permits omission;type | Nonepermits a null value. These are separate choices. - Default ownership: defaults are trusted, without validation or copying. Mutable defaults can be shared between results. Successful validation does not make data deeply immutable.
- Errors: text mode raises
ValueError. Witherror_mode="structured",ValidationErroradds legacy.issuesand canonical.details. - Depth:
max_depth=32counts shaped dictionary traversals, including the root. It does not limit list nesting, input size, or general resource use.
See defaults and ownership and error handling.
Optional class syntax
For attribute access, declare a supported Schema:
from zodify import Schema, validate
class Config(Schema):
port: int
debug: bool = False
config = validate(Config, {"port": 8080})
print(config.port) # 8080
Validate class declarations with validate(Config, data). Direct Config()
instantiation is unsupported. Annotations are limited to the documented subset.
See class schemas and limitations.
Guides and reference
| Task | Guide |
|---|---|
| Run your first validation | Getting started |
| Validate application configuration | Configuration guide |
| Validate command-line input | CLI guide |
| Parse and validate a JSON object | JSON input guide |
| Look up options, env parsing, errors, or JSON export limits | Full API reference |
| Run complete examples | Example scripts |
env() reads one variable; load_env() parses an env file without changing the
process environment. In schema mode, load_env() defaults to coercion and unknown-key
stripping, unlike ordinary validation. Env file loading, canonical details, and
conservative JSON input/export require 0.8.0; the quickstart also works with 0.6.0.
Project and contributions
Read the contributor guide for local checks and the release procedure for publication. Report problems in GitHub Issues.
Benchmark methodology documents the measured workloads and comparison limits. The roadmap distinguishes released features from plans. Compilation remains outside the public API. The implementation issue tracks direction.
License
Copyright 2026 Jun Young Sohn.
Metadata
Release files for zodify 0.8.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| zodify-0.8.1.tar.gz | 32.6 kB | Without provenance | Details for zodify-0.8.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| zodify-0.8.1-py3-none-any.whl | Python 3 | none | any | Details for zodify-0.8.1-py3-none-any.whl |
Total release size: 52.1 kB
Release files / zodify-0.8.1.tar.gz
| Download URL | zodify-0.8.1.tar.gz |
|---|---|
| Size | 32.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ff05f969e4a674a650ae4259b8188b129da888109b5b55e9bbb2351edccc0778
|
|
BLAKE2b-256 checksum How to use checksums |
e20c2b11d8ce3cdd94cfa1c37b231634774b6f342571c0fcc2f9c8530b82165c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|
Release files / zodify-0.8.1-py3-none-any.whl
| Download URL | zodify-0.8.1-py3-none-any.whl |
|---|---|
| Size | 19.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4e118c65b2dd144b745530795853307098c4f57002c6e57dc57fa6734c3c58a6
|
|
BLAKE2b-256 checksum How to use checksums |
6dc294d37e45ba434cdab0ff8fd206325daa311cb3d4295f2835224690b0cd0f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|
Security for zodify 0.8.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.