API Contract Guard
api-contract-guard detects breaking changes between an approved API contract and a new response. It supports raw JSON response comparison, OpenAPI/Swagger response-schema comparison, wildcard ignore rules, machine-readable JSON reports, HTML reports, coloured terminal output, and CI-friendly exit codes.
Installation
pip install api-contract-guard
Python 3.10 or newer is required.
Quick start
api-contract-guard expected.json actual.json
Example output:
3 breaking change(s), 2 non-breaking change(s)
------------------------------------------------------
REMOVED id (was "123")
REMOVED isSelected (was true)
REMOVED portNumber (was 104)
ADDED port = "104"
ADDED uuid = "123"
Fail a build when breaking changes are detected:
api-contract-guard expected.json actual.json --fail-on-breaking
Python usage
from api_contract_guard import compare, to_text
expected = {
"id": "123",
"portNumber": 104,
"isSelected": True,
}
actual = {
"uuid": "123",
"port": "104",
}
report = compare(expected, actual)
print(to_text(report))
if report.has_breaking_changes:
print("The new response breaks the approved contract")
Report formats
JSON report
api-contract-guard expected.json actual.json \
--format json \
--output contract-report.json
The report includes a summary and a structured list of changes:
{
"summary": {
"total": 1,
"breaking": 1,
"non_breaking": 0
},
"changes": [
{
"path": "patient.id",
"kind": "removed",
"expected": "123",
"actual": null,
"breaking": true
}
]
}
HTML report
api-contract-guard expected.json actual.json \
--format html \
--output contract-report.html
Open contract-report.html in a browser to view a readable, shareable report.
Wildcard ignore rules
Dynamic values such as timestamps, IDs, request tokens, and list-item metadata can be ignored.
Ignore one path:
api-contract-guard expected.json actual.json --ignore modified_at
Ignore the same field in every list item:
api-contract-guard expected.json actual.json \
--ignore 'users[*].updated_at'
Multiple ignore rules can be supplied:
api-contract-guard expected.json actual.json \
--ignore request_id \
--ignore 'users[*].updated_at' \
--ignore 'items.*.trace_id'
OpenAPI and Swagger comparison
Compare response schemas in OpenAPI 3.x or Swagger 2.x JSON documents:
api-contract-guard old-openapi.json new-openapi.json \
--mode openapi \
--fail-on-breaking
The OpenAPI comparator reports:
- removed operations or response status codes
- added operations or response status codes
- removed schema properties
- changed schema types
- changed required-property lists and other schema values
- local
$refresponse/schema targets
Current OpenAPI support focuses on response contracts. Request bodies, parameters, security schemes, and YAML input are planned for later releases.
Comparison options
--strict-additions Treat newly added fields as breaking
--check-values Report scalar value changes
--check-list-length Treat list-length changes as breaking
--ignore PATH Ignore a path; repeatable and wildcard-aware
--mode json|openapi Select JSON response or OpenAPI comparison
--format text|json|html Select output format
--output FILE Write the report to a file
--no-colour Disable terminal colours
--fail-on-breaking Exit with code 1 for breaking changes
Exit codes
| Exit code | Meaning |
|---|---|
0 |
Comparison completed |
1 |
Breaking changes found with --fail-on-breaking |
2 |
Invalid input, missing file, or malformed JSON |
CI integration
A full GitHub Actions example is available in docs/CI_USAGE.md. A ready-to-adapt workflow is also included at .github/workflows/contract-check-example.yml.
Minimal example:
- run: pip install api-contract-guard
- run: api-contract-guard expected.json actual.json --fail-on-breaking
Development
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
pytest
ruff check .
Build and validate a release:
rm -rf build dist src/*.egg-info
python -m build
python -m twine check dist/*
Release notes
See CHANGELOG.md.
Contributing
Bug reports and focused pull requests are welcome. Please include tests for behavioural changes and run pytest and ruff check . before submitting a pull request.
Licence
MIT
Metadata
Release files for api-contract-guard 0.2.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 | |
|---|---|---|---|
| api_contract_guard-0.2.0.tar.gz | 13.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| api_contract_guard-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.6 kB
Release files / api_contract_guard-0.2.0.tar.gz
| Download URL | api_contract_guard-0.2.0.tar.gz |
|---|---|
| Size | 13.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
32141f5cd4eea4cd2953832fd121610abe32a961acba82e1c7268338cffea553
|
|
BLAKE2b-256 checksum How to use checksums |
23d0ce595f00576b0195ebc8cd7d8b24a348ad5f9f7fc83bc4fc5f953bea40fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / api_contract_guard-0.2.0-py3-none-any.whl
| Download URL | api_contract_guard-0.2.0-py3-none-any.whl |
|---|---|
| Size | 12.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c822960f47228f479252c253616a9a2912cd85fcc83263cb2c77b96b3933442a
|
|
BLAKE2b-256 checksum How to use checksums |
8cc357138705193226976bd62b861daa03c22a330bbbdabc97c354ebba612dfc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|