Skip to main content

jsonvet

CI codecov pre-commit License: MIT release

jsonvet checks JSON, I-JSON, JSONC, HuJSON (JWCC), JSON5 and JSON Lines files for syntax errors, duplicate keys and the rules of each dialect. Each problem comes with its file, line, column and rule. Columns count Unicode code points from 1, and a byte order mark is column 1. A duplicate key also gets its JSONPath and the position of the first copy:

config.json:4:5: error[duplicate-key] duplicate key $.server.port (first at 2:5)
package.json:3:3: error[syntax] expected `,` or `}`, found `"`
events.jsonl:12:1: error[syntax] blank line; JSON Lines needs a value on every line

A file jsonvet cannot read gets a line with no position and no rule, such as gone.json: error: no such file; in SARIF it is a result under the rule unreadable.

It runs as a pre-commit or prek hook, a GitHub Action, a command and a Rust library. Up to 1.4 it was check-json5, a Python hook. 2.0 rewrote it in Rust with the same verdicts (see Coming from check-json5).

Use it as a hook

In .pre-commit-config.yaml (pre-commit or prek):

- repo: https://github.com/simonvanlierde/jsonvet
  rev: v3.0.0
  hooks:
    - id: jsonvet

Options go in args. This holds package.json to strict JSON and checks .vscode files as JSONC:

    - id: jsonvet
      args: [--strict, package.json, --dialect, "jsonc:.vscode/*.json"]

It checks files by name: .json, .jsonc, .json5, .jsonl, .ndjson, .geojson, .jsonld, .hujson, .jwcc, .code-workspace, .code-snippets, .webmanifest and .babelrc.

The hook and the Action install a prebuilt binary from PyPI, so they need no Rust. In GitHub Actions each problem also becomes an annotation on the pull request.

Use it as a GitHub Action

- uses: simonvanlierde/jsonvet@v3

The step fails when a file has an error. It runs on Linux, macOS and Windows runners with no other setup. All inputs are optional:

Input What it does
files paths or globs to check, separated by spaces; by default every tracked file the hook checks
args extra options, separated by spaces, such as --strict package.json
sarif also write a SARIF file to this path (see GitHub code scanning)
version the jsonvet version to install: X.Y.Z (also with a suffix such as rc1 or .post1), X.*, X.Y.* or latest

In files, ** matches folders at any depth on every runner. The Action skips symlinks, and by default also submodules. Any other version value stops the step.

By default the Action installs the release that matches its own tag: @v3 gets the newest 3.x, @v3.0.0 gets 3.0.0. Pinned to a commit SHA or a branch, it installs the release named in that commit's Cargo.toml. Between releases that is the last release, not the code in the commit. The step log names the version it installed. Pinning the Action does not pin the wheel's bytes: pip installs jsonvet==X.Y.Z from PyPI without a hash check.

Use it from the command line

uvx jsonvet config/*.json        # from PyPI, without installing
pip install jsonvet              # as a Python package
cargo install jsonvet-cli        # from source

The Rust library is the jsonvet crate:

use jsonvet::{check, Config, Dialect};

let report = check("{\"a\": 1, \"a\": 2}", &Config::new(Dialect::Json));
for problem in report.problems() {
    let at = report.location(problem.offset());
    println!("{}:{}: {}[{}] {problem}", at.line, at.column, problem.severity(), problem.rule());
}

Options

--dialect DIALECT[:GLOB]   check files matching GLOB (every file, without one) as DIALECT,
                           or as `auto`, the extension's default; the last match wins
--strict GLOB              the same as --dialect json:GLOB, kept from check-json5
--error RULE, --warn RULE, --ignore RULE
--max-warnings N
--format text|sarif        text lines (the default), or one SARIF 2.1.0 document on stdout
--schema FILE              also check every file against the JSON Schema in FILE
--config FILE, --no-config

A glob without / matches the file name at any depth. A glob with / matches the whole path, and * also matches /. A glob compares exact code points, with no Unicode normalization, and a \ in a path is read as /. A glob on the command line matches the path as you typed it, so it is relative to the working directory. pre-commit runs from the repository root.

pre-commit passes file names with no -- before them. So an unknown -x or --name, or a known option with a value such as --dialect=json, is a file name when a file of exactly that name exists. Otherwise an unknown one is a usage error (unknown option). Put -- before the file names to be sure: jsonvet -- --x.json.

Exit status: 0 when no file has an error, 1 when one does, 2 for a usage error. With no files, jsonvet exits 0. A file that does not exist or cannot be read prints name: error: <reason>, with no line or column, and makes the run exit 1. jsonvet reads regular files only, and follows a symlink to one. A directory, device, FIFO or socket prints error: not a regular file. The hook (types: [text]) skips tracked symlinks and submodules. When the output pipe closes early, as in jsonvet … | head -1, jsonvet stops quietly and exits with the verdict for the files it has checked.

Configuration

Settings can also live in jsonvet.toml, or in a [tool.jsonvet] table in pyproject.toml. jsonvet looks in the working directory and its parents up to the repository root. The command line wins.

rules = { byte-order-mark = "ignore", missing-final-newline = "error" }

# Checked in order; the last matching entry wins.
dialects = [
  { files = ".vscode/*.json", dialect = "jsonc" },
  { files = "package.json", dialect = "json" },
]

A glob in a config file is relative to the directory that holds the file. So data/*.json in the root's jsonvet.toml matches data/x.json when jsonvet runs in the root, in data/, or with an absolute path. A file outside that directory matches none of its globs.

A severity is error, warning (or warn), or ignore (or off). Any key other than rules and dialects, at the top or in a dialects entry, is a usage error, so a typo never goes unnoticed.

Dialects

Each file is checked in the dialect its extension implies. --dialect or the config file can pick another. JSONC, JWCC and JSON5 each add syntax to the one before. The exception is where a // comment ends: JWCC ends it at LF only, JSONC also at a lone CR, and JSON5 also at U+2028 and U+2029.

Dialect Adds to JSON Default for
json nothing (RFC 8259) none; choose it with --dialect or --strict
i-json stricter content (RFC 7493): lone surrogates, noncharacters and numbers a double cannot hold are errors none
jsonc // and /* */ comments .jsonc, .code-workspace, .code-snippets
jwcc comments and trailing commas (HuJSON) .hujson, .jwcc
json5 the JSON5 1.0.0 grammar .json, .json5, .geojson, .jsonld, .webmanifest, .babelrc
jsonl one JSON value per line (JSON Lines) .jsonl, .ndjson

Any other extension is checked as JSON5. Extensions match in lower case only, so DATA.JSONL is checked as JSON5, not JSON Lines.

.json defaults to JSON5 because most .json files that fail as JSON are config files with comments. Hold the files a strict parser reads to JSON: --dialect json:package.json.

Rules

Rule Reports Default
syntax the first syntax error; checking stops there error
duplicate-key a key repeated in one object, with both positions and its path error
invalid-number a number a double cannot hold, or an integer past ±(2⁵³ − 1) error in i-json, off elsewhere
invalid-code-point a lone surrogate or a noncharacter in a string error in i-json, off elsewhere
byte-order-mark a byte order mark at the start of the file warning in json and i-json, error in jsonl
missing-final-newline a JSON Lines file that does not end with a newline warning in jsonl

Warnings fail a run only when there are more than --max-warnings N. A file jsonvet cannot read is reported under unreadable. That is not a rule you can set: it always fails the run.

jsonvet escapes control, bidirectional and invisible characters in file names and messages, so no output line can drive a terminal or pass for a GitHub workflow command. The exact forms are in docs/design.md.

JSON Schema

--schema FILE checks each file's values against one JSON Schema. Each error is reported at the line and column of its value, in every dialect, with comments and JSON5 syntax:

$ jsonvet --schema server.schema.json server.json5
server.json5:3:9: error[schema] "80" is not of type "integer" (at $.port)
server.json5:6:3: error[schema] Additional properties are not allowed ('debug' was unexpected) (at $.debug)

In the hook, give each schema its own entry, with files naming the files it covers:

    - id: jsonvet
      name: jsonvet (server schema)
      files: ^config/server\.json5$
      args: [--schema, schemas/server.schema.json]

Each message ends with the JSONPath of the value, written as duplicate-key paths are: $ is the root, $.tags[1] an array element, $[""] the empty key. The rule id schema and the position are stable. The message wording comes from the jsonschema crate and may change between releases.

Schema errors are always errors, in text, annotations and SARIF. --error, --warn, --ignore and the config file do not take schema, and exit 2 if given it. The limits:

  • Errors. A document lists at most 100 schema errors: the first 100 jsonschema finds, which takes an object's keys in sorted order, not file order. They print in file order. Then one more line, ... and N more schema errors in this document, sits at the document's start. SARIF leaves that line out. additionalProperties gives one error per key it does not allow, at that key, and each counts toward the 100.
  • Messages. A message quotes the value unless that makes it long; then it says value. A message, with its path, is cut at 200 bytes and ends in ....
  • Depth. With --schema, a file nested deeper than 512 levels is a syntax error. A file with a syntax error gets no schema errors.
  • Values. Each line of a JSON Lines file is checked on its own. NaN, Infinity and numbers past a double's range have no JSON Schema value, so a document holding one is reported once and not checked. So is a document with two keys in one object that differ only in lone surrogates such as "\ud800", since both become U+FFFD. In the schema file, either is a usage error.
  • Memory. jsonvet holds each file's values in memory: 14 to 27 times the file's size, the most for many small records such as JSON Lines. Without --schema, memory stays near the file's size.
  • Regexes. A pattern with a back-reference or lookaround may backtrack 5,000 times per string. A key or string that needs more is an error at that key or string: the pattern could not be checked. jsonvet tries each patternProperties pattern on every key, and each pattern on every string, so this error can name a string the pattern does not apply to.
  • The schema file. It may be in any dialect. Its $schema picks the draft, from draft 4 to 2020-12. A $ref must point inside the file: jsonvet fetches nothing, from the network or from disk. A schema jsonvet cannot read or use is a usage error (exit 2). That covers a $ref to another file, and nesting deeper than 128 levels, where each $ref followed counts as a level. It also covers a schema of more than 5,000,000 objects and arrays once each $ref is replaced by what it points at, every time it is followed. SchemaStore's 1.6 MB azure-pipelines.json comes to about 2,560,000. A $ref back to a schema it is inside, as in {"items": {"$ref": "#"}}, is recursion and is fine: it is not followed again.

Why each limit exists: docs/design.md.

GitHub code scanning

--format sarif prints one SARIF 2.1.0 document instead of text lines, for GitHub code scanning and other tools. Each problem is a result with its rule, severity, message and position, and a duplicate key also points at the first copy. A file jsonvet cannot read is a result under the rule unreadable. The exit status and --max-warnings work as with text, and no annotations are printed. GitHub keeps only 5,000 results of a run with more than 25,000, so jsonvet writes the first 25,000 and counts the rest in a tool notification and on stderr.

jsonvet --format sarif $(git ls-files '*.json') > jsonvet.sarif

The Action's sarif input writes that file as well as the usual log and annotations. Upload it with github/codeql-action/upload-sarif, which needs security-events: write:

jobs:
  jsonvet:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
        with:
          persist-credentials: false
      - uses: simonvanlierde/jsonvet@v3
        with:
          sarif: jsonvet.sarif
      # Upload when jsonvet found problems too: that is when the step fails.
      - uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
        if: success() || failure()
        with:
          sarif_file: jsonvet.sarif

Coming from check-json5

Bump rev to the newest tag. The check-json5 hook id, the check-json5 command and --strict keep working through 3.x, and the check-json5 package on PyPI now installs jsonvet.

For .json, .json5, .geojson, .jsonld, .webmanifest and .babelrc files, and in strict mode, jsonvet gives the same pass or fail as 1.4.1, the same exit codes and the same duplicate-key paths. The evidence, a comparison on 20,184 files, and the speed figures are in docs/design.md.

One change can fail a file that passed: .jsonc, .code-workspace and .code-snippets files are now checked as JSONC, and .hujson and .jwcc files as JWCC. 1.4.1 read every file as JSON5, so JSON5-only syntax such as {'a': 1, b: 2} passed there. To keep the old verdict, pass --dialect json5:GLOB or add a dialects entry to the config file. The output line, the syntax-error wording, positions after a lone CR (or after U+2028 in JSON5), the new .jsonl and .ndjson files and the removed Python module are in the CHANGELOG under 2.0.0 and 3.0.0.

How it is tested

jsonvet runs the json5-tests suite, a snapshot of edge cases in every dialect, property tests, fuzzing, mutation testing and the comparison with check-json5 1.4.1, on Linux, macOS and Windows. A conformance matrix runs the same files against 17 other parsers in four languages. Details: docs/design.md.

dialect files share of files where each parser gives the expected verdict
JSON5 166 js-json5 100%, jsonvet-json5 100%, rs-json5 100%, py-json5 99%, py-pyjson5 99%, rs-serde-json5 94%, go-json5 91%
JSONC 9 js-jsonc-parser 100%, jsonvet-jsonc 100%, go-tidwall-jsonc 89%, js-strip-json-comments 89%, rs-jsonc-parser 78%
JWCC (HuJSON) 10 jsonvet-jwcc 100%, go-hujson 90%
JSON Lines 11 jsonvet-jsonl 100%, py-jsonlines 82%, go-json-stream 64%, rs-serde-json-stream 64%
Strict JSON (baseline) 129 js-json-parse 100%, jsonvet-json 100%, rs-serde-json 98%, py-json 96%

Run on 2026-10-14. The full grid, and where each expected verdict comes from: docs/conformance.md.

Development

Clone with --recurse-submodules, run just setup once, and run just check before a pull request. Setup, the checks, snapshots, fuzzing and releases are in CONTRIBUTING.md.

Credits

I (Simon van Lierde) started this as a fork of check-json5 by Ben Mares, which is based on the pre-commit-hooks repository by Anthony Sottile and contributors.

License

MIT, like the projects it started from (Ben Mares, pre-commit-hooks).

Metadata

Release files for jsonvet 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jsonvet 3.0.0
File Size Uploaded
jsonvet-3.0.0.tar.gz 116.4 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for jsonvet 3.0.0
File
jsonvet-3.0.0-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details
jsonvet-3.0.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
jsonvet-3.0.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details
jsonvet-3.0.0-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details
jsonvet-3.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
jsonvet-3.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
jsonvet-3.0.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
jsonvet-3.0.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details

Total release size: 32.0 MB

Release files / jsonvet-3.0.0.tar.gz

Download URL jsonvet-3.0.0.tar.gz
Size 116.4 kB
Tags Source
SHA-256 checksum
How to use checksums
e44f1708b2cdd54b0f813db24dded0a1a7bbe0d17ba8dd6a67cd988bae6310e2
BLAKE2b-256 checksum
How to use checksums
744a688db7cecf5262e15eb44f076776cfe4d29f198ad233253b392e262b629c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / jsonvet-3.0.0-py3-none-win_arm64.whl

Download URL jsonvet-3.0.0-py3-none-win_arm64.whl
Size 3.5 MB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
6e0eb224d1790f5232bfb75f38c7d23ce602241c3d827e89cec5136c38a4460d
BLAKE2b-256 checksum
How to use checksums
76d8aad902d5786cb05c76896cf7a0332c4f0646527e4a6cb6d7d206764b796b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / jsonvet-3.0.0-py3-none-win_amd64.whl

Download URL jsonvet-3.0.0-py3-none-win_amd64.whl
Size 3.9 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
94b3c4cb10df05151a0041542c8c225c15730731f5f19eefa9927e4ee2c3462d
BLAKE2b-256 checksum
How to use checksums
ed16ba60b59ece3504398d61ae6b90513d59a63c027b1f3ab1a5dc84d3b9c264
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / jsonvet-3.0.0-py3-none-musllinux_1_2_x86_64.whl

Download URL jsonvet-3.0.0-py3-none-musllinux_1_2_x86_64.whl
Size 4.5 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
3c014ff2324198c4f0a95ad784e8ea206977ca14121ca19662da8adb1772379b
BLAKE2b-256 checksum
How to use checksums
5614faaa8addd8ba96838ce7cbb071c83884243b8a33224032f3629c6a064258
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / jsonvet-3.0.0-py3-none-musllinux_1_2_aarch64.whl

Download URL jsonvet-3.0.0-py3-none-musllinux_1_2_aarch64.whl
Size 4.0 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
8a458a8540b5314a470231217557aa01810026346bd3a29eeda32989afc0e122
BLAKE2b-256 checksum
How to use checksums
b01167f5af880c6029bddaeb33aaf391391649379ce71da72e690df64b5172f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / jsonvet-3.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL jsonvet-3.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 4.3 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
a2bc475e1e463ee4038c96f0415d585e1abe6a3f808094042e3e4cea7cf341f8
BLAKE2b-256 checksum
How to use checksums
475b8076db0e3aec3468aa5a852d1c96d754bb3808b67e6752e210acfc471a0c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / jsonvet-3.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL jsonvet-3.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 4.0 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
4698fbd6048e973ff0937554761bd883a1bf5a6ce30261c10e1d5379841bc572
BLAKE2b-256 checksum
How to use checksums
db2e947305d36e8781ad723c76286421328b19fa54d5f25a631a219e2047703a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / jsonvet-3.0.0-py3-none-macosx_11_0_arm64.whl

Download URL jsonvet-3.0.0-py3-none-macosx_11_0_arm64.whl
Size 3.6 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
0ba85d5a84cc5ccb1cb8d26bde569d23b4318c9cfd60f4342a929e33901b07e4
BLAKE2b-256 checksum
How to use checksums
50a5574abbd93379faf436ecdbdea14b59eea175141b7e571ec2700c0eafa7d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / jsonvet-3.0.0-py3-none-macosx_10_12_x86_64.whl

Download URL jsonvet-3.0.0-py3-none-macosx_10_12_x86_64.whl
Size 4.1 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
8d6634559f3627d07d9b733c93aedfc2dbcc476b06cf788a0efcdb857fa072be
BLAKE2b-256 checksum
How to use checksums
3348f4517107ec2a32845cb4871d1464810f97fc4083ab3737dad71f28a7c485
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

3.0.0 This release

9 release files

2.0.0

9 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page