Skip to main content

apiver

Define API versions as deltas, not duplicates.

CI codecov Docs License: MIT PyPI - Python Version

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 real 0.1 tag lands. See Status and roadmap for what that means for you today.

📖 Full documentation →

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, and GET /api/v2/users/ still works — V2 never mentioned users, and the other 95% of the surface was never touched.
  • apiver init wraps 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 real Deprecation/Sunset headers and enforces 410 Gone on the wall clock — no deploy has to land on the date.
  • Tooling that answers "what does v3 actually serve?" apiver versions and a committed apiver.toml turn 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 diff says 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)

Source distribution for apiver 0.0.2
File Size Uploaded
apiver-0.0.2.tar.gz 357.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for apiver 0.0.2
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.0.2 This release

2 release files

0.0.1

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page