Codync
A free, open-source 1:1 alternative to Grok Bot and Muse. Message Claude Code, Codex, Cursor and 40+ coding agents as persistent bots from your iPhone, Mac or Linux desktop. Group chats, threads, appr
Catch breaking API changes in CI by diffing OpenAPI schemas, for Django, FastAPI and Flask.
Developer toolsPython · MakefileGitHub @Pythondeveloper6OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Catch breaking API changes in CI: diff your OpenAPI schema for Django, FastAPI and Flask
Taken from the repository README
Loading the full README.
Read the full README ↗Catch breaking API changes in CI, for Django, FastAPI and Flask.
A developer renames a serializer field, makes a parameter required, or changes
id from int to string. Tests pass, the deploy goes out, and the mobile app
(which can't be force-updated) starts crashing. API changes get reviewed as
Python diffs, not as contract diffs.
api-contract generates the OpenAPI schema from your app, compares it with a
committed snapshot, classifies each change as breaking, potentially
breaking or safe, and fails the build on breaking ones. It names the
serializer, model or handler behind each change.
| Framework | Schema from |
|---|---|
| Django REST framework | drf-spectacular |
| Django | django-ninja |
| FastAPI | FastAPI itself |
| Flask | APIFlask, flask-smorest, flask-openapi3; a route inventory for plain Flask |
| Anything else | an OpenAPI 3.0/3.1 or Swagger 2.0 JSON or YAML file |
Two small specs: the new one changes total from number to string, adds a
required currency field to a request, adds an enum value, and adds an
endpoint. The snapshot was taken from old.yaml
(api-contract snapshot --source file:old.yaml), and source points at
new.yaml.
$ api-contract check
API contract: 4 changes (2 breaking)
BREAKING
POST /api/orders/ new required request field "currency"
id: POST /api/orders/:request:currency:required-request-field-added
GET /api/orders/{id}/ response field "total" type changed: number -> string
id: GET /api/orders/{}/:response:200:total:type-changed
POTENTIALLY BREAKING
GET /api/orders/{id}/ response field "status" enum value added: "on_hold"
id: GET /api/orders/{}/:response:200:status:response-enum-value-added:"on_hold"
SAFE
POST /api/coupons/ new endpoint
Fix the change, or acknowledge it:
api-contract allow 'POST /api/orders/:request:currency:required-request-field-added' --reason "..." --expires 2026-11-24
$ echo $?
1
With a Django, FastAPI or Flask project, each change also gets an at: line:
POST /orders response field "total" removed
at: app.main.Order (app/main.py:7)
id: POST /orders:response:201:total:response-field-removed
pip install --pre "api-contract[django]"
The --pre is needed while releases are pre-releases (0.1.0aN).
Alternatively, install a tagged release straight from git:
pip install "git+https://github.com/Pythondeveloper6/[email protected]"
(Extras with git: "api-contract[fastapi] @ git+https://github.com/Pythondeveloper6/[email protected]".)
Pick the extra for your stack:
| Extra | Installs | For |
|---|---|---|
django | Django, DRF, drf-spectacular | Django REST framework (not django-ninja: that is ninja) |
ninja | Django, django-ninja | django-ninja |
fastapi | FastAPI | FastAPI |
flask | Flask only | Not enough on its own: pick one of the three below, which bring Flask with them |
apiflask | APIFlask | APIFlask |
smorest | flask-smorest | flask-smorest |
flask-openapi3 | flask-openapi3 | flask-openapi3 |
Combine them if you need to: "api-contract[fastapi,flask-openapi3]". With no
extra you can still compare file: sources. Python 3.10 or newer.
The loader imports your app, so run api-contract in the environment where
your project's dependencies are installed.
Every framework follows the same steps: add [tool.api-contract] to
pyproject.toml, write a snapshot, commit it, and run check in CI. FastAPI
as the example:
api-contract init # detects the framework, writes the config, the first
# snapshot and a GitHub Actions workflow
or by hand:
# pyproject.toml
[tool.api-contract]
source = "fastapi:app.main:app" # module:FastAPI instance, or an app factory
api-contract snapshot # writes api-contract.json; commit it
api-contract check --against origin/main # exit 1 on a breaking change vs the target branch
snapshot refuses to overwrite a snapshot with breaking changes unless you
say why (--accept "reason", recorded in the allowlist), so a break can't be
approved by regenerating the file.
When a change is intentional, acknowledge it instead of weakening the rules:
api-contract allow "GET /api/orders/{id}/:response:200:total:type-changed" \
--reason "Mobile 4.2+ reads total_display instead" --expires 2026-12-01
Django (manage.py api_contract), Flask and plain file: sources work the
same way; see the Quickstart.
uses: Pythondeveloper6/api-contract@<tag> checks against
the base branch, writes the job summary and keeps one PR comment updated.pytest --api-contract, or the api_contract_check fixture./v1/* frozen while /v2/ evolves, removal allowed after an
x-sunset date.coverage (how much is declared), --usage access.log (traffic per change), verify-samples (recorded responses vs the
contract), explain <change> (how to ship it compatibly).Full documentation: https://pythondeveloper6.github.io/api-contract/ (an MkDocs Material site; run
mkdocs serve after pip install -e ".[docs]").
[tool.api-contract] key.manage.py api_contract.init, the GitHub Action, --against, pytest, GitLab CI, pre-commit, expiry reminders.--against in CI, refused snapshots.Changes between versions are in CHANGELOG.md.
A runnable end-to-end example is in
examples/orders-contract.
A complete GitHub Actions workflow is in
examples/github-actions.yml.
The loader imports your application, so run it only on code you trust, and give
CI read-only permissions. It makes no network calls. See the
security page and
SECURITY.md
to report a vulnerability.
It compares declared schemas, so behaviour the schema does not describe (semantics, side effects, undeclared fields) is not caught. This is an alpha: see Limitations and the stability policy.
Issues and pull requests are welcome. make install && make test lint typecheck docs
sets up and checks everything; details in the
contributing guide.
MIT