Skip to main content

A conservative JSON Schema subschema prover

Project description

subschema

subschema is a conservative prover for JSON Schema subschema checks.

For JSON Schemas lhs and rhs, lhs <: rhs means every JSON instance that validates against lhs also validates against rhs.

Install

uv add subschema

For local development:

uv sync --locked --group dev
uv run pytest -q
uv run ruff check .
uv run mypy --strict src/subschema

CLI

subschema lhs.json rhs.json

The command prints whether lhs.json <: rhs.json.

External resources can be supplied explicitly. Resource keys are absolute document URIs without fragments; schemas are loaded from local files and are never fetched from the network:

subschema --resource https://example.com/external external.json lhs.json rhs.json

Finite expensive proof products can be enabled explicitly:

subschema --endeavor --max-work 20000 --timeout-ms 3000 lhs.json rhs.json

max_work and timeout_ms are only accepted with --endeavor. A value of -1 means unlimited for that control.

Python API

from subschema import Dialect, SchemaError, UnsupportedProofError, is_subschema

lhs = {"type": "integer"}
rhs = {"type": "number"}
resources = {
    "https://example.com/common": {
        "$defs": {"positive": {"type": "integer", "minimum": 0}}
    }
}

try:
    print(is_subschema(lhs, rhs, dialect=Dialect.DRAFT202012, resources=resources))
except SchemaError as error:
    print(error)
except UnsupportedProofError as error:
    print(error)

Available public entrypoints accept dialect=None, endeavor=False, max_work=None, timeout_ms=None, and resources=None unless noted otherwise:

  • is_subschema(lhs, rhs, ...)
  • is_equivalent(lhs, rhs, ...)
  • is_empty(schema, ...)
  • is_disjoint(lhs, rhs, ...)
  • covers(lhs, rhs_alternatives, ...)
  • meet_schemas(lhs, rhs, ...)
  • join_schemas(lhs, rhs, ...)
  • canonicalize_schema(schema, *, dialect=None)
  • SchemaError, SubschemaError, and UnsupportedProofError as stable catch points.

Proof Behavior

subschema proves sound results when it can. If a query is outside the current proof model, public boolean helpers raise UnsupportedProofError instead of guessing.

Use endeavor=True or --endeavor for finite but potentially expensive proof products. In endeavor mode, max_work limits proof frontier expansion and timeout_ms limits solver calls. These controls are accepted only when endeavor is enabled.

unsupported is a proof-capability boundary. resource_exhausted is a budget or timeout boundary. Neither means the input schema is invalid.

Current intentional boundaries:

  • external references are resolved only from explicit resources; they are not fetched from the network;
  • recursive and dynamic-reference proofs are supported only for narrow, explicitly modeled fragments; other recursive or dynamic cases raise UnsupportedProofError;
  • format and content keywords are treated as annotations unless a future assertion or decoding backend is provided;
  • non-regular ECMAScript regex features such as backreferences and lookaround are reported as unsupported;
  • unsupported means “not proven by this model,” not “the schema is invalid.”

Dialects

Draft 2020-12 is the default dialect for calls without an explicit dialect or $schema declaration. Older dialects can be selected by passing dialect=... or by using a $schema declaration.

Supported dialects:

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

Resource exhaustion is reported separately from unsupported proof fragments when an endeavor proof exceeds its configured work or timeout limit.

Acknowledgement

This project is a rewrite based on IBM's jsonsubschema project and may retain portions of its source code. Credit to IBM and contributors.

License

Apache License 2.0. See LICENSE.

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

subschema-0.1.0.tar.gz (263.1 kB view details)

Uploaded Source

Built Distribution

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

subschema-0.1.0-py3-none-any.whl (228.4 kB view details)

Uploaded Python 3

File details

Details for the file subschema-0.1.0.tar.gz.

File metadata

  • Download URL: subschema-0.1.0.tar.gz
  • Upload date:
  • Size: 263.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for subschema-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e475523b4d823ea9e1e92b1dcd1e00012e5fed199203c1355519f67e843887c4
MD5 377d859051cb3e0cd2e42488fea53e4a
BLAKE2b-256 c26a3f4a2210fa56416b303397347d878e2ae53b50f7729bc34330c0f0ea8065

See more details on using hashes here.

File details

Details for the file subschema-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: subschema-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 228.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for subschema-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ea0ae1d8fb97ad42296fe8d1819ee1e69f2300863aea2eb321f6ec9a9c988ec1
MD5 51d695a4cdeb0347ec7e56d2f1764633
BLAKE2b-256 c65fb0f07bf0bfde916455cb3d61fe11d9f0c8c4981d482a1e9aeefe359f967e

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