jsonschema-changelog
Detect, document, and manage changes between JSON Schema versions.
Part of the Búho Zurdo ecosystem 🦉
🎯 Overview
jsonschema-changelog is a powerful tool for managing JSON Schema evolution in production systems. It helps you:
- Detect all changes between schema versions (properties, types, constraints, etc.)
- Classify changes as breaking, non-breaking, or deprecations
- Generate changelogs in Markdown, JSON, or HTML formats
- Validate backward and forward compatibility
- Create migration scripts for data transformation
Perfect for APIs, LIMS (Laboratory Information Management Systems), and any system where data schemas evolve over time.
📦 Installation
pip install jsonschema-changelog
Or with development dependencies:
pip install jsonschema-changelog[dev]
🚀 Quick Start
Python API
from jsonschema_changelog import SchemaDiff, ChangeClassifier, ChangelogGenerator
# Define your schemas
old_schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"status": {"type": "string", "enum": ["active", "inactive"]}
},
"required": ["name"]
}
new_schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"status": {"type": "string", "enum": ["active", "inactive", "pending"]},
"email": {"type": "string", "format": "email"} # New field
},
"required": ["name"]
}
# Detect changes
differ = SchemaDiff(old_version="1.0.0", new_version="2.0.0")
diff_result = differ.compare(old_schema, new_schema)
print(f"Found {diff_result.change_count} changes")
# Classify changes
classifier = ChangeClassifier()
classification = classifier.classify(diff_result)
print(f"Breaking: {len(classification.breaking_changes)}")
print(f"Non-breaking: {len(classification.non_breaking_changes)}")
print(f"Compatible: {classification.is_compatible}")
# Generate changelog
generator = ChangelogGenerator(title="API Schema Changelog")
changelog = generator.generate(classification)
markdown = generator.to_markdown(changelog)
print(markdown)
Command Line
# Compare two schemas
jsonschema-changelog diff old.json new.json
# Generate changelog
jsonschema-changelog changelog old.json new.json --format markdown -o CHANGELOG.md
# Validate compatibility (fails on breaking changes)
jsonschema-changelog validate old.json new.json --fail-on-breaking
# Generate migration script
jsonschema-changelog migrate old.json new.json --language python -o migrate.py
# Show schema information
jsonschema-changelog info schema.json
📋 Types of Changes Detected
Properties
- ➕ Added properties
- ➖ Removed properties
- 🔄 Modified properties (type, constraints, etc.)
Required Fields
- 🔒 Fields becoming required
- 🔓 Fields becoming optional
Types
- 📝 Type changes (string → integer, etc.)
- 📋 Type unions (adding/removing types)
Constraints
- 📏 Length constraints (minLength, maxLength)
- 🔢 Numeric constraints (minimum, maximum)
- 📊 Array constraints (minItems, maxItems)
Enums
- ✅ Added enum values
- ❌ Removed enum values
Other
- 📄 Format changes (email, date-time, etc.)
- 🔤 Pattern changes (regex)
- 📚 $ref changes
- ⚠️ Deprecations
- 📝 Documentation changes
🏷️ Change Classification
Changes are automatically classified by their impact:
🚨 Breaking Changes
- Removing a property
- Making a field required
- Reducing enum values
- Making constraints stricter (higher minLength, lower maximum)
- Changing type to a narrower type
✨ Non-Breaking Changes
- Adding optional properties
- Making a field optional
- Adding enum values
- Relaxing constraints
- Adding nullable to types
⚠️ Deprecations
- Marking fields as deprecated
- Adding deprecation notices in descriptions
📝 Documentation Changes
- Title/description updates
- Example changes
🔧 API Reference
SchemaDiff
from jsonschema_changelog import SchemaDiff
differ = SchemaDiff(
old_version="1.0.0",
new_version="2.0.0",
include_documentation=True # Include title/description changes
)
result = differ.compare(old_schema, new_schema)
# Access changes
for change in result.changes:
print(f"{change.change_type}: {change.path}")
print(f" {change.description}")
ChangeClassifier
from jsonschema_changelog import ChangeClassifier
classifier = ChangeClassifier(strict_mode=False)
classification = classifier.classify(diff_result)
# Access classified changes
for change in classification.breaking_changes:
print(f"🚨 {change.impact_description}")
print(f" Migration: {change.migration_hint}")
ChangelogGenerator
from jsonschema_changelog import ChangelogGenerator
generator = ChangelogGenerator(
title="My API Changelog",
description="Track schema changes",
include_documentation=False
)
changelog = generator.generate(classification, date="2024-01-15")
# Multiple formats
markdown = generator.to_markdown(changelog)
json_output = generator.to_json(changelog)
html = generator.to_html(changelog)
CompatibilityValidator
from jsonschema_changelog import CompatibilityValidator
validator = CompatibilityValidator(strict_mode=False)
result = validator.validate(old_schema, new_schema)
print(f"Level: {result.level}") # FULL, BACKWARD, FORWARD, or NONE
print(f"Backward compatible: {result.is_backward_compatible}")
print(f"Forward compatible: {result.is_forward_compatible}")
for issue in result.issues:
print(f"Issue: {issue.description}")
print(f"Suggestion: {issue.suggestion}")
MigrationStrategy
from jsonschema_changelog.migration import MigrationStrategy
strategy = MigrationStrategy()
plan = strategy.generate(classification)
# Generate migration scripts
python_script = plan.to_script("python")
js_script = plan.to_script("javascript")
# Execute migration on data
migrated_data = strategy.execute(plan, original_data)
🔄 CI/CD Integration
GitHub Actions
name: Schema Validation
on:
pull_request:
paths:
- 'schemas/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install jsonschema-changelog
- name: Validate schema compatibility
run: |
jsonschema-changelog validate \
schemas/schema_v1.json \
schemas/schema_v2.json \
--fail-on-breaking
- name: Generate changelog
if: always()
run: |
jsonschema-changelog changelog \
schemas/schema_v1.json \
schemas/schema_v2.json \
--format markdown \
--output SCHEMA_CHANGELOG.md
- name: Upload changelog
uses: actions/upload-artifact@v4
with:
name: schema-changelog
path: SCHEMA_CHANGELOG.md
Pre-commit Hook
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: schema-compatibility
name: Check Schema Compatibility
entry: jsonschema-changelog validate
language: python
files: \.json$
args: ['schemas/current.json', 'schemas/proposed.json']
🏥 LIMS Use Case
This tool was designed with Laboratory Information Management Systems in mind:
# Validate that patient data schema changes don't break existing records
from jsonschema_changelog import CompatibilityValidator
validator = CompatibilityValidator()
result = validator.validate(
old_schema=patient_schema_v1,
new_schema=patient_schema_v2,
old_version="1.0.0",
new_version="2.0.0"
)
if not result.is_backward_compatible:
print("⚠️ Breaking changes detected!")
print("Existing patient records may be affected.")
for suggestion in result.suggestions:
print(f"• {suggestion}")
🛣️ Roadmap
- JSON Schema Draft 2020-12 full support
- Schema versioning with Git integration
- Visual diff in HTML output
- Migration validation with sample data
- OpenAPI/Swagger schema support
- AsyncAPI schema support
- Database schema comparison
🤝 Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
📄 License
MIT License - see LICENSE for details.
Part of the Búho Zurdo ecosystem
Building reliable software, one schema at a time
Metadata
Release files for jsonschema-changelog 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jsonschema_changelog-0.1.5.tar.gz | 40.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jsonschema_changelog-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.1 kB
Release files / jsonschema_changelog-0.1.5.tar.gz
| Download URL | jsonschema_changelog-0.1.5.tar.gz |
|---|---|
| Size | 40.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2a232d3b2050d8887dfd14f687fda6fb107cdd757f5210904b52dd5adfec8a11
|
|
BLAKE2b-256 checksum How to use checksums |
4cac2ffc325e4beef76d1a621dff56b37328ac0640922594c9531a9ae0e63403
|
| 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 2, 2026.
Transparency logRelease files / jsonschema_changelog-0.1.5-py3-none-any.whl
| Download URL | jsonschema_changelog-0.1.5-py3-none-any.whl |
|---|---|
| Size | 5.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dbff2b38a797b90573d19a7588eecd275ba1bb033c67812ddbc8e0ff0c3d84fe
|
|
BLAKE2b-256 checksum How to use checksums |
41ac875cc7c67d30ea9e24c7dca932a17aa661ac8ccceac2941da4852bb25672
|
| 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 2, 2026.
Transparency log