Skip to main content

Lightweight validation library for (micro)Python

Project description

uzod

A lightweight validation library inspired by zod for (micro)python that provides runtime type checking and validation with a clean, chainable API.

PyPI - Version GitHub Actions Workflow Status PyPI - Downloads

Features

🦾 Ergonomic API - Fluent, chainable interface

🛡️ Type-safe - Comes with complete type stubs for IDE support

🪶 Lightweight - Zero dependencies, single file (~220 lines)

🤸🏻 Flexible - Built-in validators + custom refinements

🧩 Composable - Build complex schemas from simple primitives

Installation

Install from PyPI:

pip install uzod

Or just copy uzod.py into your project - it's standalone!

Quick Start

from uzod import z, ValidationError

# Define a schema
user_schema = z.object({
    "name": z.string(min=2, max=50),
    "email": z.string().refine(lambda s: "@" in s, "invalid email"),
    "age": z.integer(min=0, max=120).optional,
})

# Validate data
try:
    user = user_schema.parse({
        "name": "Alice",
        "email": "alice@example.com",
        "age": 30
    })
    print(user)  # {'name': 'Alice', 'email': 'alice@example.com', 'age': 30}
except ValidationError as error:
    print(f"Validation failed: {error}")

API Reference

String

z.string()                   # Any string
z.string(min=3)              # At least 3 characters
z.string(max=100)            # At most 100 characters
z.string(min=3, max=100)     # Between 3-100 characters

Integer

z.integer()                 # Any integer
z.integer(min=0)            # Non-negative
z.integer(min=1, max=10)    # Between 1-10

Float

z.float()                   # Any float
z.float(min=0.0)            # Non-negative
z.float(min=0.0, max=1.0)   # Between 0.0-1.0

Boolean

z.boolean()                 # true or false

Literal

z.literal("admin", "user")  # Must be "admin" or "user"
z.literal(1, 2, 3)          # Must be 1, 2, or 3

Array

z.array(z.string())                  # Array of strings
z.array(z.integer(), min=1, max=10)  # 1-10 integers
z.array(z.object({...}))             # Array of objects

Object

z.object({
    "name": z.string(),
    "age": z.integer()
})

# Strict mode - reject unknown keys (can also be used with chainable method)
z.object({"name": z.string()}, strict=True)

Union

z.union(z.string(), z.integer())     # String OR integer
z.union(z.literal("yes", "no"), z.boolean())

Modifiers

Optional

# Field can be omitted (returns None)
z.object({
    "name": z.string(),
    "nickname": z.string().optional
})

# parse({"name": "Alice"}) -> {"name": "Alice", "nickname": None}

Nullable

# Field can be None
z.object({
    "name": z.string().nullable
})

# parse({"name": None}) -> {"name": None}

Default

# Provide default value when field is missing or None
z.object({
    "role": z.string().default("user")
})

# parse({}) -> {"role": "user"}

Refine (Custom Validation)

# Add custom validation logic
z.string().refine(lambda s: s.isalnum(), "must be alphanumeric")
z.integer().refine(lambda n: n % 2 == 0, "must be even")

Error Messages

uzod provides helpful error messages:

>>> z.string(min=5).parse("hi")
ValidationError: too short, at least 5 chars

>>> z.integer().parse("123")
ValidationError: expected int, got str

>>> z.object({"name": z.string()}).parse({"name": 123})
ValidationError: name: expected str, got int

>>> z.object({"a": z.string()}, strict=True).parse({"a": "x", "b": "y"})
ValidationError: unexpected keys: b

Testing

Run the test suite with:

python -m unittest discover tests

Contributing

Contributions are welcome! This is a small, focused library - let's keep it that way.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uzod-1.1.1.tar.gz (12.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uzod-1.1.1-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

File details

Details for the file uzod-1.1.1.tar.gz.

File metadata

  • Download URL: uzod-1.1.1.tar.gz
  • Upload date:
  • Size: 12.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for uzod-1.1.1.tar.gz
Algorithm Hash digest
SHA256 152d6a055e2caffef19624d9033d54428b8663d533a16fdb060386f6c4c4b921
MD5 cee844e0d6b66eb2132ee4fee3a472f1
BLAKE2b-256 810e4d85f182d435d7ef23eb47a2cac13966f7820410460cbb0e934503e592c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for uzod-1.1.1.tar.gz:

Publisher: publish-to-pypi.yml on markusand/uzod

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file uzod-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: uzod-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 10.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for uzod-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 cc9cf6f1dae24e9818829fbd01da2dffa67f98cf5388ca63c4376bf43f62ecf7
MD5 e3912a346e0dfac271938edf9e3ffc20
BLAKE2b-256 5fad8447a55059d922e865a95629a1b4d34e7ad53c5e3770b69e9550a122fee2

See more details on using hashes here.

Provenance

The following attestation bundles were made for uzod-1.1.1-py3-none-any.whl:

Publisher: publish-to-pypi.yml on markusand/uzod

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page