╔════════════════════════════════════════════════════════════════════════════════════════════╗
║ ║
║ ██████╗ ██████╗ ███████╗███╗ ██╗ █████╗ ██████╗ ██╗ ║
║ ██╔═══██╗██╔══██╗██╔════╝████╗ ██║██╔══██╗██╔══██╗██║ ║
║ ██║ ██║██████╔╝█████╗ ██╔██╗ ██║███████║██████╔╝██║ ║
║ ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║██╔══██║██╔═══╝ ██║ ║
║ ╚██████╔╝██║ ███████╗██║ ╚████║██║ ██║██║ ██║ ║
║ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝ ║
║ ║
║ ██████╗ ██████╗ ██╗███████╗████████╗ ║
║ ██╔══██╗██╔══██╗██║██╔════╝╚══██╔══╝ ║
║ ██║ ██║██████╔╝██║█████╗ ██║ ║
║ ██║ ██║██╔══██╗██║██╔══╝ ██║ ║
║ ██████╔╝██║ ██║██║██║ ██║ ║
║ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ║
║ ║
║ does the service still do what the spec says ║
║ ║
╚════════════════════════════════════════════════════════════════════════════════════════════╝
Your OpenAPI document is a promise about a service. Nothing keeps the two together, so it quietly becomes a description of what the service used to do, and every consumer finds out one failed call at a time.
This answers two questions:
- Does the deployed service still do what this says?
- Can a machine read it and act on it?
pip install openapi-drift
openapi-drift openapi.json # static checks
openapi-drift https://api.example.com/openapi.json --live
openapi-drift openapi.json --live --base-url https://api.example.com
Exits 0 clean, 1 on drift, 2 when it could not check.
What it is not
| Not a fuzzer. | schemathesis generates traffic hunting for crashes. This calls what you documented and compares. |
| Not a syntax validator. | openapi-spec-validator tells you the document is well-formed. A perfectly valid document can be unusable. |
The check nobody else runs
A response schema behind a $ref is correct, valid, and useless to the
tools that turn an operation into a function signature — they do not
dereference. A validator sees a schema; a converter sees an argument with no
type.
That cost a working week to learn on a real spec that passed every other
check. It is reported as ref_in_response, and --allow-refs silences it if
nothing consuming your document does function calling.
What it finds
Drift — exits 1:
missing_path |
you document a path the service does not serve |
status_drift |
it answered with a status you do not describe |
content_type_drift |
it answered in a media type you do not declare |
schema_drift |
a required field vanished, or a type changed |
ref_in_response |
a schema no function-calling converter can read |
dangling_ref |
a pointer to a definition that is not there |
duplicate_operation_id |
two operations collide under one name |
Warnings — exit 0 unless --warnings-as-errors:
untyped_schema · no_operation_id · no_description · relative_server ·
undocumented_field
It will not tell you it passed when it did not
An empty document, a document with no paths, and one where every operation needs an argument all exit 2, not 0. A pass on something never examined is the most dangerous sentence a build tool can say, and it is the reason this exists at all.
In CI
- uses: vince-gonzalez/openapi-drift@v1
with:
spec: https://api.example.com/openapi.json
live: "true"
Or directly:
- run: pip install openapi-drift
- run: openapi-drift openapi.json --live
Only safe calls
--live calls parameterless GETs only. A path with a placeholder, or a
required query parameter, is skipped rather than guessed at — a guessed value
reports drift that is the checker's fault. Nothing is written, ever.
Licence
MIT.
Metadata
Release files for openapi-drift 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 | |
|---|---|---|---|
| openapi_drift-0.1.0.tar.gz | 13.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| openapi_drift-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.6 kB
Release files / openapi_drift-0.1.0.tar.gz
| Download URL | openapi_drift-0.1.0.tar.gz |
|---|---|
| Size | 13.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a9b54c43a52e0f7f589f0ebb8e90c9c39a1bfcaddf54a9201c76fee091266d45
|
|
BLAKE2b-256 checksum How to use checksums |
3bff0ae1f744049e438f75efac86ddad234297fe3390cd8aac0a26917d9629e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / openapi_drift-0.1.0-py3-none-any.whl
| Download URL | openapi_drift-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7b023544d97fd482f9ce4cd6a09f0eabf96c272938faacffb7be7718ebbdbcdf
|
|
BLAKE2b-256 checksum How to use checksums |
26b0e92fd9bd5ddb73b10d416f3dd5134460641973e572efd36c1bee2e4f1ed8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|