apiver
Define API versions as deltas, not duplicates.
apiver is a Django REST Framework library for composing complete API versions from deltas. Your existing code becomes the base version, exactly where it already lives; every later version declares only what changed against its parent, and everything untouched resolves straight through to the parent's actual handler objects — not copies of them.
Status: pre-1.0 (
0.0.1). Everything documented here exists and is covered by tests, but the public API can still move before a real0.1tag lands. See Status and roadmap for what that means for you today.
The problem
Shipping a breaking API change — drop a field, remove a resource, change a type — without breaking the
clients still calling the old shape has three bad answers today: copy the API into a v2/ package and
drag the unchanged 95% along with it; reach for DRF's URLPathVersioning, which sets request.version
and leaves composition as if request.version == "v2": branches smeared through the codebase; or promise
to only ever add fields and never remove one, until the response body is an archaeology dig of
status_v2/status_string/status_do_not_use that nobody remembers the meaning of.
None of them let you say "V2 is V1, except payments returns decimal strings and legacy-invoices is gone" and get a complete, correctly-documented V2 surface out of it. And none of them require your project to already be a mess before apiver is worth adopting — however you got here, apiver only needs to know what your next version changes. Read the full problem statement →
What you get
- A second complete API surface for the cost of one field. One
override()call, andGET /api/v2/users/still works — V2 never mentioned users, and the other 95% of the surface was never touched. apiver initwraps your project exactly as it is. No file moves, no big-bang migration to schedule. The first breaking change is the only time you touch apiver again.- Deltas that are ordinary, inspectable Python. An override is a subclass. No DSL, no parallel object model, no migration-chain classes to learn — if you can read a Django class hierarchy, you can read a delta.
- Correct per-version OpenAPI, automatically. Each version's schema document contains exactly its own routes — no leakage from siblings, no hand-maintained schema file to keep in sync.
- Lifecycle clients can actually see.
v1.deprecate(sunset=...)emits realDeprecation/Sunsetheaders and enforces410 Goneon the wall clock — no deploy has to land on the date. - Tooling that answers "what does v3 actually serve?"
apiver versionsand a committedapiver.tomlturn that from an archaeology project into a command. - No pretending it can see what it can't. A
SerializerMethodField's actual output, or a changed error-response shape, won't show up in a schema diff —apiver diffsays so out loud instead of quietly missing it. See exactly where the line is →
A taste of it
# apiversions/v1/registry.py — your existing code, untouched
from apiver.drf import Version
from products.views import ProductViewSet
v1 = Version("v1")
v1.register("products", ProductViewSet, basename="products")
# apiversions/v2/registry.py — the whole delta
from apiversions.v1.registry import v1
from products.views import ProductViewSetV2
v2 = v1.derive("v2")
v2.override("products", ProductViewSetV2, basename="products")
GET /api/v2/products/ now serves the new shape. Every other route V2 never mentioned still resolves,
unchanged, straight through to V1. Walk through the full adoption →
Installation
$ uv add apiver
or with pip:
$ pip install apiver
Requirements
Python 3.12–3.14 · Django ~5.2 · Django REST Framework ~3.18 · drf-spectacular ~0.30
Learn more
- Full documentation — the sales pitch, the philosophy, a real adoption walkthrough, and every command and setting.
- What If...? — the specific objections an adoption decision actually raises, answered plainly.
- docs/adr/ — the architectural decision records behind every non-obvious choice: route identity, the public API surface, layout and the manifest, squash feasibility, intra-version hyperlinking, field removal, the Aggregation Root, and version schemes.
- CONTRIBUTING.md — development setup, tests, and lint.
Release files for apiver 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| apiver-0.0.2.tar.gz | 357.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| apiver-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 427.1 kB
Release files / apiver-0.0.2.tar.gz
| Download URL | apiver-0.0.2.tar.gz |
|---|---|
| Size | 357.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
48366a87527d987eb26e442bf03a79f42867d6266094b2c423a7e1240e1d0192
|
|
BLAKE2b-256 checksum How to use checksums |
560dbfe647683671d4ac5f4e20f3d35a20d87d02fc9d146dcd4215d39ec59193
|
| 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 Aug 13, 2026.
Transparency logRelease files / apiver-0.0.2-py3-none-any.whl
| Download URL | apiver-0.0.2-py3-none-any.whl |
|---|---|
| Size | 69.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
967df1f5c082f7691c075d4e4ccaafe9507d413924c7eaa53c1065c177940151
|
|
BLAKE2b-256 checksum How to use checksums |
ecc7afd2031cdad1e0289e8ea713247539dff43a4911b613470b2937adbdf8e0
|
| 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 Aug 13, 2026.
Transparency log