This guide helps you migrate your existing vCon code to work with the updated version management system.
The vCon library has been updated to align with the latest vCon specification changes. The most significant change is that the version field is now optional and version management has been simplified. All changes are backward compatible, so existing code will continue to work without changes.
- The
vconfield is no longer required in vCon objects - No automatic version assignment or migration
- Existing vCons with version fields continue to work unchanged
- New vCons can be created without version fields
- Removed
strict_versionparameter from all methods - No more automatic version migration
- No more version enforcement or validation
extensions: List of extension names usedcritical: List of extensions that must be supported
sip: SIP URI for VoIP communicationdid: Decentralized Identifier for blockchain-based identityjCard: vCard format contact informationtimezone: Party's timezone
session_id: Session identifier for tracking conversationscontent_hash: Hash for content integrity verification (replaces alg/signature)
If you were using the strict_version parameter, you need to remove it:
# Old code (will cause errors)
vcon = Vcon.load("file.json", strict_version=True)
vcon = Vcon.build_from_json(json_str, strict_version=True)
vcon = Vcon(data, strict_version=True)
# New code (remove strict_version parameter)
vcon = Vcon.load("file.json")
vcon = Vcon.build_from_json(json_str)
vcon = Vcon(data)The version field is now optional. You can choose to:
Option A: Remove version fields from new vCons
# Old code
vcon = Vcon({"uuid": "123", "vcon": "0.4.0", "created_at": "2024-01-01T00:00:00Z"})
# New code (version field optional)
vcon = Vcon({"uuid": "123", "created_at": "2024-01-01T00:00:00Z"})Option B: Keep existing version fields
# This still works - no changes needed
vcon = Vcon({"uuid": "123", "vcon": "0.4.0", "created_at": "2024-01-01T00:00:00Z"})If you want to declare extension capabilities:
# Old code
vcon = Vcon.build_new()
# New code
vcon = Vcon.build_new()
vcon.add_extension("video")
vcon.add_extension("encryption")
vcon.add_critical("encryption")Add additional contact and identification methods:
# Old code
party = Party(
name="John Doe",
tel="+1234567890"
)
# New code
party = Party(
name="John Doe",
tel="+1234567890",
sip="sip:john@example.com",
did="did:example:123456789abcdef",
jCard={
"fn": "John Doe",
"tel": "+1234567890",
"email": "john@example.com"
},
timezone="America/New_York"
)Track conversation sessions:
# Old code
dialog = Dialog(
type="text",
start=datetime.now(),
parties=[0, 1],
body="Hello!"
)
# New code
dialog = Dialog(
type="text",
start=datetime.now(),
parties=[0, 1],
body="Hello!",
session_id={"local": "local-uuid", "remote": "remote-uuid"}
)Replace alg/signature with content_hash:
# Old code
dialog = Dialog(
type="text",
start=datetime.now(),
parties=[0, 1],
body="Hello!",
alg="sha256",
signature="abc123"
)
# New code
dialog = Dialog(
type="text",
start=datetime.now(),
parties=[0, 1],
body="Hello!",
session_id={"local": "local-uuid", "remote": "remote-uuid"}
)
# Calculate and set content hash
content_hash = dialog.calculate_content_hash()
dialog.set_content_hash(content_hash)from vcon import Vcon
from vcon.party import Party
from vcon.dialog import Dialog
from datetime import datetime
# Create vCon
vcon = Vcon.build_new()
# Add party
party = Party(name="Alice", tel="+1234567890")
vcon.add_party(party)
# Add dialog
dialog = Dialog(
type="text",
start=datetime.now(),
parties=[0],
body="Hello!"
)
vcon.add_dialog(dialog)
# Save
vcon.save_to_file("conversation.json")from vcon import Vcon
from vcon.party import Party
from vcon.dialog import Dialog
from datetime import datetime
# Create vCon with extensions
vcon = Vcon.build_new()
vcon.add_extension("video")
vcon.add_critical("encryption")
# Add party with enhanced information
party = Party(
name="Alice",
tel="+1234567890",
sip="sip:alice@example.com",
did="did:example:123456789abcdef",
jCard={
"fn": "Alice Johnson",
"tel": "+1234567890",
"email": "alice@example.com"
},
timezone="America/New_York"
)
vcon.add_party(party)
# Add dialog with session tracking and integrity
dialog = Dialog(
type="text",
start=datetime.now(),
parties=[0],
body="Hello!",
session_id={"local": "local-uuid", "remote": "remote-uuid"}
)
# Calculate and set content hash
content_hash = dialog.calculate_content_hash()
dialog.set_content_hash(content_hash)
vcon.add_dialog(dialog)
# Save
vcon.save_to_file("conversation.json"){
"uuid": "...",
"vcon": "0.4.0",
"parties": [{
"name": "Alice",
"tel": "+1234567890"
}],
"dialog": [{
"type": "text",
"start": "...",
"parties": [0],
"body": "Hello!"
}]
}{
"uuid": "...",
"vcon": "0.4.0",
"extensions": ["video"],
"critical": ["encryption"],
"parties": [{
"name": "Alice",
"tel": "+1234567890",
"sip": "sip:alice@example.com",
"did": "did:example:123456789abcdef",
"jCard": {
"fn": "Alice Johnson",
"tel": "+1234567890",
"email": "alice@example.com"
},
"timezone": "America/New_York"
}],
"dialog": [{
"type": "text",
"start": "...",
"parties": [0],
"body": "Hello!",
"session_id": {"local": "local-uuid", "remote": "remote-uuid"},
"content_hash": "..."
}]
}- Existing code continues to work: All new fields are optional
- No breaking changes: Existing vCon files will load correctly
- Gradual adoption: You can add new fields incrementally
- Property handling: New fields work with all property handling modes (default, strict, meta)
- Run existing tests: Ensure they still pass
- Test new functionality: Use the example in
samples/example_new_fields.py - Validate JSON output: Check that new fields appear correctly
- Verify backward compatibility: Load old vCon files to ensure they work
- Check the full documentation in
docs/source/new_required_fields.rst - Run the example:
python samples/example_new_fields.py - Review the test files for usage examples
- Open an issue if you encounter problems
0.10.0 retargets the library to draft-ietf-vcon-vcon-core-04. The
specification's body semantics did not change from prior guidance in this
library (a "json"-encoded body was always meant to be a JSON value, not a
string), but two behavior changes follow from aligning with the WG's
reference JSON schema:
- Legacy string bodies are now read transparently. If you (or an
adapter) previously wrote a
"json"-encoded body as ajson.dumpsstring -- for example atagsattachment body written as'["category:support"]'instead of["category:support"]--get_tag(),add_tag(), and the lawful-basis/WTF extension validators now decode that string automatically.add_tag()also normalizes a legacy string body back to a list, in place, the first time you call it on that vCon. You don't need to migrate existing data by hand. - New attachments get more defaults filled in.
add_attachment(),add_lawful_basis_attachment(), andadd_wtf_transcription_attachment()now defaultparty/dialogto0andstartto the vCon'screated_atwhen you don't supply them, because the WG JSON schema requiresstart,party, anddialogon every attachment. If your code checked for the absence of these keys (rather than their values), check the CHANGELOG's 0.10.0 entry before upgrading.