pyverge
Schema evolution and migrations for versioned data models. Version your models, define migrations between versions, and converge payloads to a target schema at runtime.
The engine is provider-agnostic: it works on plain dicts and only touches a
model library through the ModelAdapter seam. Pydantic and JSON Schema
adapters ship today; adapters for other providers (dataclasses, attrs,
marshmallow, MessagePack, etc.) plug in the same way.
Installation
# Core library (versioned registry, migration engine, diffing)
pip install pyverge
# With CLI (init, validate, migrate, diff, export commands)
pip install "pyverge[cli]"
# With MCP tool server
pip install "pyverge[fastmcp]"
Development dependencies are managed as a dependency group; install them with
uv sync --group dev (or hatch/your tool's equivalent).
Quick Start
from typing import Literal
import semver
from pydantic import BaseModel
from pyverge import Manager
from pyverge.migration import (
MigrationSettings,
PydanticModelAdapter,
)
# A manager binds a version strategy to an adapter and settings.
UserManager = Manager[semver.Version].configure(
MigrationSettings(),
PydanticModelAdapter(),
)
# Register versioned models. Version and kind are read from the class itself.
@UserManager.model()
class UserV1(BaseModel):
kind: Literal["User"] = "User"
version: Literal["1.0.0"] = "1.0.0"
name: str
email: str
@UserManager.model()
class UserV2(BaseModel):
kind: Literal["User"] = "User"
version: Literal["2.0.0"] = "2.0.0"
name: str
email: str
age: int | None = None
# Register a migration between two versions.
@UserManager.migration("User", "1.0.0", "2.0.0")
def add_age(data: dict) -> dict:
return {**data, "age": None}
manager = UserManager()
# Migrate data — converges every versioned entry to the configured target.
migrated = manager.migrate(
{"kind": "User", "version": "1.0.0", "name": "Alice", "email": "a@b.com"}
)
# -> {"kind": "User", "version": "2.0.0", "name": "Alice", "email": "a@b.com", "age": None}
CLI
# Requires: pip install "pyverge[cli]"
pyverge init # Bootstrap a new project
pyverge validate # Validate data against a schema version
pyverge migrate # Migrate data between versions
pyverge diff # Show differences between versions
pyverge export # Export JSON Schema definitions
pyverge info # List registered models and versions
pyverge managers # List available managers from configuration
Configuration lives in a pyverge.toml (or [tool.pyverge] in
pyproject.toml), pointing at the module that defines your manager.
# pyverge.toml
[managers]
user = "myapp.models:UserManager"
pyverge info # List registered models and versions
pyverge validate data.json --manager user --version 1.0.0
pyverge migrate data.json --manager user --to latest
pyverge diff --manager user --from 1.0.0 --to 2.0.0
pyverge export --manager user --version 2.0.0 > schema.json
Features
- Versioned model registry — decorator-based registration with semver or ISO date versioning
- Model reflection — when a migration endpoint has no concrete model, the engine reconstructs it from the other endpoint's model and the migration diff (
on_missing="reconstruct_model"), so every version in a chain is materializable - Migration proposal — when you hold both models but no migration,
Engine.propose_migrationdiffs their schemas into a declarative JSON Patch to review (on_missing="reconstruct_migration"). The two reconstruction strategies are mutually exclusive - Provider adapters — pluggable
ModelAdapter; Pydantic and JSON Schema ship today, other providers (dataclasses, attrs, marshmallow, MessagePack) plug in the same way - Declarative migrations — express a migration as an RFC 6902 JSON Patch op list (plus
set_default/coerce/map/split), compiled into aMigrationFuncviaJsonPatchMigration - Convergent migration engine — graph-driven, with automatic migration of nested versioned entries
- Target policies — converge to
latest,earliest, a pinned version, or per-kind overrides - Executors — sequential or level-parallel batch convergence
- Model diffing — breaking-change detection with JSON Patch rendering
- Migration hooks — observability via before/after/error callbacks, plus an OpenTelemetry hook
- FastMCP adapter — version FastMCP tools, prompts, and resources: reflect each versioned primitive into the graph and converge every call to the policy target
Documentation
- Getting Started
- Managers
- Concepts
- Execution Flow
- Target Policy
- Migrations
- Telemetry & Hooks
- FastMCP Integration
- Testing
- Common Usage Patterns
- Scenarios
- Showcases
Plan
Items intentionally out of scope for this documentation pass, tracked here for follow-up:
- CLI/manager facade alignment —
Managernow exposesget,get_latest, andlist_versions. The CLI still expectsvalidate_data,diff,list_models,dump_schemas, andmigrate(data, schema, from_version, to_version)before those commands work end-to-end. - Additional model providers — adapters for dataclasses, attrs, marshmallow, and MessagePack
- Real-source integrations —
showcases/projects wiring for document storage (converge on read), Kafka consumers, RabbitMQ/streams workers, and MQTT/IoT gateways on the high-levelManagerAPI, with thin adapters around real drivers (motor,confluent-kafka,aio-pika,paho-mqtt). The transport glue is not shipped yet. - API reference — an auto-generated API reference page will be restored once the SDK surface is stable.
Metadata
Release files for pyverge 0.10.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 | Provenance | |
|---|---|---|---|---|
| pyverge-0.10.0.tar.gz | 450.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyverge-0.10.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 547.6 kB
Release files / pyverge-0.10.0.tar.gz
| Download URL | pyverge-0.10.0.tar.gz |
|---|---|
| Size | 450.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3e514c5ecfef6da6a79072c9698d650f733884b82a6e819c349d36064124c92d
|
|
BLAKE2b-256 checksum How to use checksums |
c9aba0959710b1f06253bf11b49e9fca3852a1e6a797052f0897b93c502bb8d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / pyverge-0.10.0-py3-none-any.whl
| Download URL | pyverge-0.10.0-py3-none-any.whl |
|---|---|
| Size | 97.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b37c06e0b06e412a101ae68f6411799f29efb89b16781fadaf48df47435e5711
|
|
BLAKE2b-256 checksum How to use checksums |
fa19fede1ddebe5367ccfb1949db7333983b76add725a1d40ab71b1120ee69d6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for pyverge 0.10.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.