scvd-preflight (Python)
Zero-dependency client for scvd.store's free x402
door check, as a library and a command. One POST /api/preflight/v2
per door: the same single probe, the same battery, the same limiter
every caller gets. The store answers with a verdict, every check by
name, the advisories outside the verdict, and remediation rows (the
defect class, its definition URL, what the operator does, what the
buyer does). This package keeps that answer whole and adds the deploy
gate's exit law on top.
Standard library only — urllib, json, dataclasses. Nothing to
install beyond the package itself. It holds no key and cannot spend
money.
pip install scvd-preflight
Use
from scvd_preflight import preflight_one, exit_code_for, remediation
result = preflight_one("https://door.example/api/paid")
result.outcome # "ready" | "not_ready" | "unreachable" | "refused" | "store_unreachable"
result.body["checks"] # every check, named, from the store
remediation(result.body) # both halves per named defect, from the store
raise SystemExit(exit_code_for([result]))
scvd-preflight https://door.example/api/paid https://door.example/api/other --fail-on not_ready
The exit law
| code | meaning |
|---|---|
| 0 | every door answered ready, or was unreachable and unreachable is not in --fail-on |
| 1 | a door's verdict is in --fail-on (not_ready by default) |
| 2 | the store refused a URL before probing (not https, a custom port, a private address, the store's own host): nothing was probed, so a gate must not pass |
| 3 | the store, or the network between you and it, did not answer, including its probe-budget refusal |
unreachable does not fail by default. It is a fact about the network
path from the store's vantage at one moment and says nothing about the
door; a gate that failed on it would be drawing a conclusion the
evidence refuses. Choosing --fail-on not_ready,unreachable is yours,
in writing.
One law, three languages
This is a port of the npm package scvd-preflight, not a
reimplementation of the idea. The JavaScript is the reference; the
Python and Go clients answer the same questions
with the same words and the same exit codes, and all three are tested
against the same recorded reports in
../x402-preflight/fixtures — read from
there, never copied, so the day a battery is re-recorded there is one
place to re-record it.
The differences that remain are the ones a port should keep: names are
snake_case, preflight_one returns a dataclass, and the HTTP client
is swapped through an opener argument rather than a fetch one. A
port that reads like transliterated JavaScript is a library nobody
wants to import.
Verified byte-for-byte: all three commands print identical output and return identical exit codes for the same door.
What it is not
Not an uptime claim: a pass says the door served a well-formed, payable 402 to one request at one moment. Not a delivery claim: no probe can establish what a door does after payment. Nothing here derives a verdict; every line printed is the store's own answer.
Releasing
.github/workflows/publish-pypi.yml, run by hand from the Actions tab,
with a dry run as the default. It refuses three ways before it can do
damage: the name in pyproject.toml disagreeing with the button, the
version disagreeing with what was typed, or that version already being
on PyPI.
Authentication is PyPI Trusted Publishing over GitHub OIDC — there is
no token to store or rotate. It has to be authorised once on PyPI's
side (project → Publishing → add a GitHub publisher naming this repo
and publish-pypi.yml); until then the upload step gets a 403 and
nothing is sent, which is the correct failure for a publisher nobody
authorised.
Versioning
Versions are immutable once published. Minor versions add functions
and never change an existing function's result shape or an exit code;
a change to either is a major. The dated record is CHANGELOG.md.
Release files for scvd-preflight 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| scvd_preflight-0.1.0.tar.gz | 9.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| scvd_preflight-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.4 kB
Release files / scvd_preflight-0.1.0.tar.gz
| Download URL | scvd_preflight-0.1.0.tar.gz |
|---|---|
| Size | 9.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
04d59a8dc59f2e65918f79fcb7908c0bd5fc8953a264606ce9b4d79b308dbf6a
|
|
BLAKE2b-256 checksum How to use checksums |
cdce92a396487fe0f897bef6b8fb595005500aada96dc6c5c38067d88fb7c980
|
| 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 Sep 16, 2026.
Transparency logRelease files / scvd_preflight-0.1.0-py3-none-any.whl
| Download URL | scvd_preflight-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1d967ca48ab0df65a8d3b338d644a9fbb6be16ebd6c26d3e59966f33724b126d
|
|
BLAKE2b-256 checksum How to use checksums |
638cb7a1034af26f30bb796c79213f38e9aad48a0bf1f625641881ded69814be
|
| 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 Sep 16, 2026.
Transparency log