Skip to main content

A high-performance JSON Schema validator for Python

Project description

jsonschema-rs

Build Version Python versions License Supported Dialects

A high-performance JSON Schema validator for Python.

import jsonschema_rs

schema = {"maxLength": 5}
instance = "foo"

# One-off validation
try:
    jsonschema_rs.validate(schema, "incorrect")
except jsonschema_rs.ValidationError as exc:
    assert str(exc) == '''"incorrect" is longer than 5 characters

Failed validating "maxLength" in schema

On instance:
    "incorrect"'''

# Build & reuse (faster)
validator = jsonschema_rs.validator_for(schema)

# Iterate over errors
for error in validator.iter_errors(instance):
    print(f"Error: {error}")
    print(f"Location: {error.instance_path}")

# Boolean result
assert validator.is_valid(instance)

⚠️ Upgrading from older versions? Check our Migration Guide for key changes.

Highlights

  • 📚 Full support for popular JSON Schema drafts
  • 🌐 Remote reference fetching (network/file)
  • 🔧 Custom format validators
  • ✨ Meta-schema validation for schema documents

Supported drafts

The following drafts are supported:

  • Draft 2020-12
  • Draft 2019-09
  • Draft 7
  • Draft 6
  • Draft 4

You can check the current status on the Bowtie Report.

Installation

To install jsonschema-rs via pip run the following command:

pip install jsonschema-rs

Usage

If you have a schema as a JSON string, then you could pass it to validator_for to avoid parsing on the Python side:

import jsonschema_rs

validator = jsonschema_rs.validator_for('{"minimum": 42}')
...

You can use draft-specific validators for different JSON Schema versions:

import jsonschema_rs

# Automatic draft detection
validator = jsonschema_rs.validator_for({"minimum": 42})

# Draft-specific validators
validator = jsonschema_rs.Draft7Validator({"minimum": 42})
validator = jsonschema_rs.Draft201909Validator({"minimum": 42})
validator = jsonschema_rs.Draft202012Validator({"minimum": 42})

JSON Schema allows for format validation through the format keyword. While jsonschema-rs provides built-in validators for standard formats, you can also define custom format validators for domain-specific string formats.

To implement a custom format validator:

  1. Define a function that takes a str and returns a bool.
  2. Pass it with the formats argument.
  3. Ensure validate_formats is set appropriately (especially for Draft 2019-09 and 2020-12).
import jsonschema_rs

def is_currency(value):
    # The input value is always a string
    return len(value) == 3 and value.isascii()


validator = jsonschema_rs.validator_for(
    {"type": "string", "format": "currency"}, 
    formats={"currency": is_currency},
    validate_formats=True  # Important for Draft 2019-09 and 2020-12
)
validator.is_valid("USD")  # True
validator.is_valid("invalid")  # False

Additional configuration options are available for fine-tuning the validation process:

  • validate_formats: Override the draft-specific default behavior for format validation.
  • ignore_unknown_formats: Control whether unrecognized formats should be reported as errors.
  • base_uri - a base URI for all relative $ref in the schema.

Example usage of these options:

import jsonschema_rs

validator = jsonschema_rs.Draft202012Validator(
    {"type": "string", "format": "date"},
    validate_formats=True,
    ignore_unknown_formats=False
)

# This will validate the "date" format
validator.is_valid("2023-05-17")  # True
validator.is_valid("not a date")  # False

# With ignore_unknown_formats=False, using an unknown format will raise an error
invalid_schema = {"type": "string", "format": "unknown"}
try:
    jsonschema_rs.Draft202012Validator(
        invalid_schema, validate_formats=True, ignore_unknown_formats=False
    )
except jsonschema_rs.ValidationError as exc:
    assert str(exc) == '''Unknown format: 'unknown'. Adjust configuration to ignore unrecognized formats

Failed validating "format" in schema

On instance:
    "unknown"'''

Arbitrary-Precision Numbers

The Python bindings always include the arbitrary-precision support from the Rust validator, so numeric values are exposed to Python using the most accurate type available:

  • Integers, regardless of size, are returned as regular int objects.
  • Floating-point literals that fit into IEEE-754 become Python floats.
  • Floating-point literals that don't fit in float (for example 1e10000 or extremely precise decimals) fall back to decimal.Decimal using their original JSON string representation.

This means ValidationError.kind attributes may contain Decimal instances for very large numbers. Import Decimal from the standard library if you need to compare against or serialize those values exactly:

from decimal import Decimal
from jsonschema_rs import ValidationError, validator_for

validator = validator_for('{"const": 1e10000}')
try:
    validator.validate(0)
except ValidationError as exc:
    assert exc.kind.expected_value == Decimal("1e10000")

# Extremely large exponents (beyond ~10^1_000_000) are clamped internally to keep parsing
# predictable, matching the Rust implementation's guardrails.

Meta-Schema Validation

JSON Schema documents can be validated against their meta-schemas to ensure they are valid schemas. jsonschema-rs provides this functionality through the meta module:

import jsonschema_rs

# Valid schema
schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer", "minimum": 0}
    },
    "required": ["name"]
}

# Validate schema (draft is auto-detected)
assert jsonschema_rs.meta.is_valid(schema)
jsonschema_rs.meta.validate(schema)  # No error raised

# Invalid schema
invalid_schema = {
    "minimum": "not_a_number"  # "minimum" must be a number
}

try:
    jsonschema_rs.meta.validate(invalid_schema)
except jsonschema_rs.ValidationError as exc:
    assert 'is not of type "number"' in str(exc)

Regular Expression Configuration

When validating schemas with regex patterns (in pattern or patternProperties), you can configure the underlying regex engine:

import jsonschema_rs
from jsonschema_rs import FancyRegexOptions, RegexOptions

# Default fancy-regex engine with backtracking limits
# (supports advanced features but needs protection against DoS)
validator = jsonschema_rs.validator_for(
    {"type": "string", "pattern": "^(a+)+$"},
    pattern_options=FancyRegexOptions(backtrack_limit=10_000)
)

# Standard regex engine for guaranteed linear-time matching
# (prevents regex DoS attacks but supports fewer features)
validator = jsonschema_rs.validator_for(
    {"type": "string", "pattern": "^a+$"},
    pattern_options=RegexOptions()
)

# Both engines support memory usage configuration
validator = jsonschema_rs.validator_for(
    {"type": "string", "pattern": "^a+$"},
    pattern_options=RegexOptions(
        size_limit=1024 * 1024,   # Maximum compiled pattern size
        dfa_size_limit=10240      # Maximum DFA cache size
    )
)

The available options:

  • FancyRegexOptions: Default engine with lookaround and backreferences support

    • backtrack_limit: Maximum backtracking steps
    • size_limit: Maximum compiled regex size in bytes
    • dfa_size_limit: Maximum DFA cache size in bytes
  • RegexOptions: Safer engine with linear-time guarantee

    • size_limit: Maximum compiled regex size in bytes
    • dfa_size_limit: Maximum DFA cache size in bytes

This configuration is crucial when working with untrusted schemas where attackers might craft malicious regex patterns.

External References

By default, jsonschema-rs resolves HTTP references and file references from the local file system. You can implement a custom retriever to handle external references. Here's an example that uses a static map of schemas:

import jsonschema_rs

def retrieve(uri: str):
    schemas = {
        "https://example.com/person.json": {
            "type": "object",
            "properties": {
                "name": {"type": "string"},
                "age": {"type": "integer"}
            },
            "required": ["name", "age"]
        }
    }
    if uri not in schemas:
        raise KeyError(f"Schema not found: {uri}")
    return schemas[uri]

schema = {
    "$ref": "https://example.com/person.json"
}

validator = jsonschema_rs.validator_for(schema, retriever=retrieve)

# This is valid
validator.is_valid({
    "name": "Alice",
    "age": 30
})

# This is invalid (missing "age")
validator.is_valid({
    "name": "Bob"
})  # False

Schema Registry

For applications that frequently use the same schemas, you can create a registry to store and reference them efficiently:

import jsonschema_rs

# Create a registry with schemas
registry = jsonschema_rs.Registry([
    ("https://example.com/address.json", {
        "type": "object",
        "properties": {
            "street": {"type": "string"},
            "city": {"type": "string"}
        }
    }),
    ("https://example.com/person.json", {
        "type": "object",
        "properties": {
            "name": {"type": "string"},
            "address": {"$ref": "https://example.com/address.json"}
        }
    })
])

# Use the registry with any validator
validator = jsonschema_rs.validator_for(
    {"$ref": "https://example.com/person.json"},
    registry=registry
)

# Validate instances
assert validator.is_valid({
    "name": "John",
    "address": {"street": "Main St", "city": "Boston"}
})

The registry can be configured with a draft version and a retriever for external references:

import jsonschema_rs

registry = jsonschema_rs.Registry(
    resources=[
        (
            "https://example.com/address.json",
            {}
        )
    ],  # Your schemas
    draft=jsonschema_rs.Draft202012,  # Optional
    retriever=lambda uri: {}  # Optional
)

Error Handling

jsonschema-rs provides detailed validation errors through the ValidationError class, which includes both basic error information and specific details about what caused the validation to fail:

import jsonschema_rs

schema = {"type": "string", "maxLength": 5}

try:
    jsonschema_rs.validate(schema, "too long")
except jsonschema_rs.ValidationError as error:
    # Basic error information
    print(error.message)       # '"too long" is longer than 5 characters'
    print(error.instance_path) # Location in the instance that failed
    print(error.schema_path)   # Location in the schema that failed

    # Detailed error information via `kind`
    if isinstance(error.kind, jsonschema_rs.ValidationErrorKind.MaxLength):
        assert error.kind.limit == 5
        print(f"Exceeded maximum length of {error.kind.limit}")

For a complete list of all error kinds and their attributes, see the type definitions file

Error Message Masking

When working with sensitive data, you might want to hide actual values from error messages. You can mask instance values in error messages by providing a placeholder:

import jsonschema_rs

schema = {
    "type": "object",
    "properties": {
        "password": {"type": "string", "minLength": 8},
        "api_key": {"type": "string", "pattern": "^[A-Z0-9]{32}$"}
    }
}

# Use default masking (replaces values with "[REDACTED]")
validator = jsonschema_rs.validator_for(schema, mask="[REDACTED]")

try:
    validator.validate({
        "password": "123",
        "api_key": "secret_key_123"
    })
except jsonschema_rs.ValidationError as exc:
    assert str(exc) == '''[REDACTED] does not match "^[A-Z0-9]{32}$"

Failed validating "pattern" in schema["properties"]["api_key"]

On instance["api_key"]:
    [REDACTED]'''

Performance

jsonschema-rs is designed for high performance, outperforming other Python JSON Schema validators in most scenarios:

  • Up to 60-390x faster than jsonschema for complex schemas and large instances
  • Generally 3-7x faster than fastjsonschema on CPython

For detailed benchmarks, see our full performance comparison.

Python support

jsonschema-rs supports CPython 3.8 through 3.14.

Acknowledgements

This library draws API design inspiration from the Python jsonschema package. We're grateful to the Python jsonschema maintainers and contributors for their pioneering work in JSON Schema validation.

Support

If you have questions, need help, or want to suggest improvements, please use GitHub Discussions.

Sponsorship

If you find jsonschema-rs useful, please consider sponsoring its development.

Contributing

We welcome contributions! Here's how you can help:

See CONTRIBUTING.md for more details.

License

Licensed under MIT License.

Project details


Release history Release notifications | RSS feed

Download files

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

Source Distribution

jsonschema_rs-0.35.0.tar.gz (1.8 MB view details)

Uploaded Source

Built Distributions

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

jsonschema_rs-0.35.0-pp311-pypy311_pp73-win_amd64.whl (2.1 MB view details)

Uploaded PyPyWindows x86-64

jsonschema_rs-0.35.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.whl (2.3 MB view details)

Uploaded PyPymanylinux: glibc 2.24+ ARM64

jsonschema_rs-0.35.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.3 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

jsonschema_rs-0.35.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl (2.2 MB view details)

Uploaded PyPymacOS 10.12+ x86-64

jsonschema_rs-0.35.0-cp310-abi3-win_amd64.whl (2.1 MB view details)

Uploaded CPython 3.10+Windows x86-64

jsonschema_rs-0.35.0-cp310-abi3-win32.whl (1.9 MB view details)

Uploaded CPython 3.10+Windows x86

jsonschema_rs-0.35.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

jsonschema_rs-0.35.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.3 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

jsonschema_rs-0.35.0-cp310-abi3-manylinux_2_12_i686.manylinux2010_i686.whl (2.4 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.12+ i686

jsonschema_rs-0.35.0-cp310-abi3-macosx_10_12_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

jsonschema_rs-0.35.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (4.3 MB view details)

Uploaded CPython 3.10+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file jsonschema_rs-0.35.0.tar.gz.

File metadata

  • Download URL: jsonschema_rs-0.35.0.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for jsonschema_rs-0.35.0.tar.gz
Algorithm Hash digest
SHA256 c987c39ff57ebc62715f737040d870f30b722aa29547c49a5a0f98d9707b901d
MD5 4d69e48dcd329b3a77452b94a954fc38
BLAKE2b-256 03b51de70978c998398de58c77775422213ea41fbf5fba6c235076372b103b41

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-pp311-pypy311_pp73-win_amd64.whl.

File metadata

File hashes

Hashes for jsonschema_rs-0.35.0-pp311-pypy311_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 fa6e7a9f896006acef81b6218eb2424e93eebbe2347f06356d976205c4ff14fc
MD5 1150808c934e900ec28a7343af4976c1
BLAKE2b-256 f8752e899bfe11537668a9225f755c213952785d38ced074e6b1d769db82e959

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.whl.

File metadata

File hashes

Hashes for jsonschema_rs-0.35.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.whl
Algorithm Hash digest
SHA256 17bcf151ee948340a9ad97a8eb9c688546c363c7339b4c59afc60b54526a6f60
MD5 e5ff890b6730c24a1fda9524b491f727
BLAKE2b-256 ec4c7addb62cf6852ac423156c452f838f998f14e1bcdea65c905bd05f4acbf8

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for jsonschema_rs-0.35.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 58365021b4342e0f37a22ba62410dc0b833c1c4bb38ff3304997e9433dd2a7db
MD5 c9a1deb768fdb8e087ae172eff9a4d81
BLAKE2b-256 5c82d207003c9ad17276b03808c25da93f01f912b5c7702a156fcc2942762fba

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for jsonschema_rs-0.35.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d5f7aa5403febf853f5218f571dca80e5467bccb8b4afa15214417e517b02f90
MD5 f0637ca732cb620242aece97968df924
BLAKE2b-256 a4df04359b1ae0edfc25c4c545d8a69bf2d512b1bef95d3fd6ffa5c45c4333bc

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for jsonschema_rs-0.35.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 c6cfe369a6ad02d5b719cc4528d0bab2ae3fa191bcc72011f7c65d7cae8eab12
MD5 6c886efc0259e3c5f0d026cd765f27de
BLAKE2b-256 80e624e0c2403c1cbfca5a48d1b5ce64242232c030411bc20d5c2b7be0f28abd

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-cp310-abi3-win32.whl.

File metadata

  • Download URL: jsonschema_rs-0.35.0-cp310-abi3-win32.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: CPython 3.10+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for jsonschema_rs-0.35.0-cp310-abi3-win32.whl
Algorithm Hash digest
SHA256 1a082b30081678cc6f762f368cf5f1e5d42851fcf5065c47b24345b55633cd4a
MD5 692e98b241a622f1f04b4564eeb8917e
BLAKE2b-256 57ceec488a973e5ff110948b4704920012ff4301535b06395b9112c111e39be9

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for jsonschema_rs-0.35.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 00b5f1c2efb5d392f3b5524a60fa8ae90c0d48d2993620a1b4ff44adce267588
MD5 38bdd3441a6b8879b4d59047481db7d1
BLAKE2b-256 e280c4478d90eac836d3c6ad52bd7703e42df483b57ecaed1e93c288bf604319

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for jsonschema_rs-0.35.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5cdd216dccbd457a8278f1e11f3304ebe3f3b80b5b5f0d92a4f955204e1bd9fe
MD5 0525479593ee4f06956ec3a7c6bb8755
BLAKE2b-256 f3caa3dd745f899adc9b1e1bb069266a8323e580a264a25811d9a964ffb09fc1

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-cp310-abi3-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for jsonschema_rs-0.35.0-cp310-abi3-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 0816a5d53a09ba3d14b221379e183afacdc07c48727d430b3261991f167025e9
MD5 8b7924f985807642e6e0504b1fbceaad
BLAKE2b-256 313ffe834c93f960c32ad12b7256043f97c8a81cb97eb090a47c36e5c1080cad

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for jsonschema_rs-0.35.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 11ca5062c091bb021c9d43a7bba219798487ed7b9696d60029661c3043479989
MD5 60d957648a244f14b7014e285f99018d
BLAKE2b-256 2b0c97a2f1e49cccfb649fd05bf764ed406b6aa0c15291a098ffdf5d445073cb

See more details on using hashes here.

File details

Details for the file jsonschema_rs-0.35.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for jsonschema_rs-0.35.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 0e9e2522f6025d24dbaf97ae9389db8a2849711ff266e36e2dbc38a532f3886b
MD5 5a2e691f1888161c8b4d05de32e6c7c8
BLAKE2b-256 d1be0f8d9b8202e36c6fe16832919a67e058931e13b197a5b8d89d202037af6c

See more details on using hashes here.

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