Complete API documentation for the vCon library - a Python implementation of the latest vCon specification for Virtual Conversation objects.
The vCon library provides a complete Python implementation of the latest vCon specification for representing virtual conversations. It supports all features including parties, dialogs, attachments, analysis, digital signatures, extensibility, and advanced extensions for lawful basis management and standardized transcription formats.
pip install vconImage/PDF processing support is included by default with the standard installation.
The main class for working with vCon objects.
Vcon(vcon_dict: Dict[str, Any] = None, property_handling: str = "default")Parameters:
vcon_dict(Dict[str, Any], optional): Dictionary representing a vCon. Defaults to empty dict.property_handling(str): How to handle non-standard properties:"default": Keep non-standard properties (default)"strict": Remove non-standard properties"meta": Move non-standard properties to meta object
Create a new vCon object with default values.
vcon = Vcon.build_new()Create a vCon object from JSON string.
vcon = Vcon.build_from_json('{"uuid": "123", "created_at": "2024-01-01T00:00:00Z"}')Load a vCon from file or URL.
# From file
vcon = Vcon.load("conversation.vcon.json")
# From URL
vcon = Vcon.load("https://example.com/conversation.vcon.json")Load a vCon from a local file.
Load a vCon from a URL.
Validate a vCon file.
is_valid, errors = Vcon.validate_file("conversation.vcon.json")Validate a vCon JSON string.
Generate RSA key pair for digital signatures.
private_key, public_key = Vcon.generate_key_pair()Generate UUID8 with domain name.
Generate UUID8 with custom time bits.
Add a party to the vCon.
party = Party(tel="+1234567890", name="Alice", role="caller")
vcon.add_party(party)Find party index by field value.
index = vcon.find_party_index("tel", "+1234567890")Add a dialog to the vCon.
dialog = Dialog(type="text", start=datetime.now(), parties=[0, 1], body="Hello")
vcon.add_dialog(dialog)Find dialog by field value.
dialog = vcon.find_dialog("type", "text")Find all dialogs of a specific type.
text_dialogs = vcon.find_dialogs_by_type("text")add_transfer_dialog(start: Union[datetime, str], transfer_data: Dict[str, Any], parties: List[int]) -> None
Add a transfer dialog.
transfer_data = {
"transferee": 0,
"transferor": 1,
"transfer_target": 2
}
vcon.add_transfer_dialog(datetime.now(), transfer_data, [0, 1, 2])Add an incomplete dialog.
vcon.add_incomplete_dialog(datetime.now(), "no-answer", [0])Add an attachment to the vCon.
attachment = vcon.add_attachment("transcript", "Full conversation...", "none")Add an image attachment from file.
attachment = vcon.add_image("screenshot.png", "screenshot")Find attachment by type.
transcript = vcon.find_attachment_by_purpose("transcript")add_analysis(type: str, dialog: Union[int, List[int]], vendor: str, body: Any, encoding: str = "none") -> None
Add analysis data to the vCon.
vcon.add_analysis(
type="sentiment",
dialog=[0, 1],
vendor="SentimentAnalyzer",
body={"sentiment": "positive", "confidence": 0.85},
encoding="json"
)Find analysis by type.
sentiment = vcon.find_analysis_by_type("sentiment")Add a tag to the vCon.
vcon.add_tag("customer_id", "12345")Get a tag value.
customer_id = vcon.get_tag("customer_id")Add an extension to the vCon.
vcon.add_extension("video")Get list of extensions.
extensions = vcon.get_extensions()Remove an extension.
vcon.remove_extension("video")Add a must-support extension.
vcon.add_critical("encryption")Get list of must-support extensions.
critical = vcon.get_critical()Remove a must-support extension.
add_lawful_basis_attachment(lawful_basis: str, expiration: str, purpose_grants: list, party_index: Optional[int] = None, dialog_index: Optional[int] = None, **kwargs) -> None
Add a lawful basis attachment to the vCon.
vcon.add_lawful_basis_attachment(
lawful_basis="consent",
expiration="2026-01-01T00:00:00Z",
purpose_grants=[
{"purpose": "recording", "granted": True, "granted_at": "2025-01-01T00:00:00Z"}
],
party_index=0
)add_wtf_transcription_attachment(transcript: Dict[str, Any], segments: List[Dict[str, Any]], metadata: Dict[str, Any], party_index: Optional[int] = None, dialog_index: Optional[int] = None, **kwargs) -> None
Add a WTF transcription attachment to the vCon.
vcon.add_wtf_transcription_attachment(
transcript={"text": "Hello world", "language": "en", "duration": 2.0, "confidence": 0.95},
segments=[{"id": 0, "start": 0.0, "end": 2.0, "text": "Hello world", "confidence": 0.95}],
metadata={"created_at": "2025-01-01T00:00:00Z", "provider": "whisper", "model": "whisper-1"}
)Find lawful basis attachments in the vCon.
attachments = vcon.find_lawful_basis_attachments(party_index=0)Find WTF transcription attachments in the vCon.
attachments = vcon.find_wtf_attachments(party_index=0)Check if permission is granted for a specific purpose.
has_permission = vcon.check_lawful_basis_permission("recording", party_index=0)Validate all extensions in the vCon.
results = vcon.validate_extensions()Process all extensions in the vCon.
results = vcon.process_extensions()Sign the vCon with a private key.
vcon.sign(private_key)Verify the vCon signature.
is_valid = vcon.verify(public_key)Validate the vCon object.
is_valid, errors = vcon.is_valid()Convert vCon to JSON string.
json_str = vcon.to_json()Convert vCon to dictionary.
vcon_dict = vcon.to_dict()Alias for to_json().
Save vCon to file.
vcon.save_to_file("conversation.vcon.json")Post vCon to URL.
response = vcon.post_to_url("https://api.example.com/vcon", headers={"Authorization": "Bearer token"})Set the creation timestamp.
Set the update timestamp.
Get the vCon UUID.
Get the vCon version (optional field).
Get the vCon subject.
Get the creation timestamp.
Get the update timestamp.
Get the redacted flag.
Get the amended flag.
Get the group information.
Get the metadata.
Get list of parties.
Get list of dialogs.
Get list of attachments.
Get list of analysis data.
Get all tags.
Represents a participant in a vCon conversation.
Party(
tel: Optional[str] = None,
stir: Optional[str] = None,
mailto: Optional[str] = None,
name: Optional[str] = None,
validation: Optional[str] = None,
gmlpos: Optional[str] = None,
civicaddress: Optional[CivicAddress] = None,
uuid: Optional[str] = None,
role: Optional[str] = None,
contact_list: Optional[str] = None,
meta: Optional[dict] = None,
sip: Optional[str] = None,
did: Optional[str] = None,
jCard: Optional[dict] = None,
timezone: Optional[str] = None,
**kwargs
)Parameters:
tel(str, optional): Telephone numberstir(str, optional): STIR identifiermailto(str, optional): Email addressname(str, optional): Display namevalidation(str, optional): Validation informationgmlpos(str, optional): GML position coordinatescivicaddress(CivicAddress, optional): Civic address informationuuid(str, optional): Unique identifierrole(str, optional): Role in conversation (e.g., "caller", "agent")contact_list(str, optional): Contact list referencemeta(dict, optional): Additional metadatasip(str, optional): SIP URI for VoIP communicationdid(str, optional): Decentralized IdentifierjCard(dict, optional): vCard format contact informationtimezone(str, optional): Party's timezone
Convert Party to dictionary.
party_dict = party.to_dict()Represents a dialog segment in a vCon conversation.
Dialog(
type: str,
start: Union[datetime, str],
parties: List[int],
originator: Optional[int] = None,
mediatype: Optional[str] = None,
filename: Optional[str] = None,
body: Optional[str] = None,
encoding: Optional[str] = None,
url: Optional[str] = None,
disposition: Optional[str] = None,
party_history: Optional[List[PartyHistory]] = None,
transferee: Optional[int] = None,
transferor: Optional[int] = None,
transfer_target: Optional[int] = None,
original: Optional[int] = None,
consultation: Optional[int] = None,
target_dialog: Optional[int] = None,
campaign: Optional[str] = None,
interaction: Optional[str] = None,
skill: Optional[str] = None,
duration: Optional[float] = None,
meta: Optional[dict] = None,
metadata: Optional[Dict[str, Any]] = None,
transfer: Optional[Dict[str, Any]] = None,
signaling: Optional[Dict[str, Any]] = None,
resolution: Optional[str] = None,
frame_rate: Optional[float] = None,
codec: Optional[str] = None,
bitrate: Optional[int] = None,
thumbnail: Optional[str] = None,
session_id: Optional[Union[Dict[str, str], List[Dict[str, str]]]] = None,
content_hash: Optional[str] = None,
application: Optional[str] = None,
message_id: Optional[str] = None,
**kwargs
)Parameters:
type(str): Dialog type ("text", "recording", "transfer", "incomplete", "audio", "video")start(Union[datetime, str]): Start timeparties(List[int]): List of party indicesoriginator(int, optional): Originator party indexmediatype(str, optional): MIME type of contentfilename(str, optional): Filenamebody(str, optional): Content bodyencoding(str, optional): Content encodingurl(str, optional): External URLdisposition(str, optional): Disposition for incomplete dialogsparty_history(List[PartyHistory], optional): Party event historytransferee(int, optional): Transferee party indextransferor(int, optional): Transferor party indextransfer_target(int, optional): Transfer target party indexoriginal(int, optional): Original dialog indexconsultation(int, optional): Consultation dialog indextarget_dialog(int, optional): Target dialog indexcampaign(str, optional): Campaign identifierinteraction(str, optional): Interaction identifierskill(str, optional): Skill identifierduration(float, optional): Dialog durationmeta(dict, optional): Additional metadatametadata(Dict[str, Any], optional): Structured metadatatransfer(Dict[str, Any], optional): Transfer-specific informationsignaling(Dict[str, Any], optional): Signaling informationresolution(str, optional): Video resolution (e.g., "1920x1080")frame_rate(float, optional): Video frame ratecodec(str, optional): Video codecbitrate(int, optional): Video bitratethumbnail(str, optional): Base64-encoded thumbnailsession_id(dict or list, optional): Session identifier (SessionId or list of SessionId)content_hash(str, optional): Content hash for external filesapplication(str, optional): Application identifiermessage_id(str, optional): Message identifier
Convert Dialog to dictionary.
Add external data to dialog.
Add inline data to dialog.
Check if dialog has external data.
Check if dialog has inline data.
Check if dialog is text type.
Check if dialog is recording type.
Check if dialog is transfer type.
Check if dialog is incomplete type.
Check if dialog has audio content.
Check if dialog has video content.
Check if dialog is email type.
Check if dialog has image content.
Check if dialog has PDF content.
add_video_data(video_data, filename: Optional[str] = None, mediatype: Optional[str] = None, inline: bool = True, metadata: Optional[dict] = None) -> None
Add video data to dialog.
Extract video metadata using FFmpeg.
generate_thumbnail(timestamp: float = 0.0, width: int = 320, height: int = 240, quality: int = 90) -> bytes
Generate video thumbnail.
add_streaming_video_reference(reference_id: str, mediatype: str, metadata: Optional[dict] = None) -> None
Add streaming video reference.
add_video_with_optimal_storage(video_data, filename: str, mediatype: Optional[str] = None, size_threshold_mb: int = 10) -> None
Add video with optimal storage method.
transcode_video(target_format: str, codec: Optional[str] = None, bit_rate: Optional[int] = None, width: Optional[int] = None, height: Optional[int] = None) -> None
Transcode video to different format.
Add image data from file.
Extract image metadata.
Generate image thumbnail.
Check if external data has changed.
Convert external data to inline data.
Set session identifier.
Get session identifier.
Set content hash.
Get content hash.
Calculate content hash.
Verify content hash.
Represents civic address information according to GEOPRIV specification.
CivicAddress(
country: Optional[str] = None,
a1: Optional[str] = None,
a2: Optional[str] = None,
a3: Optional[str] = None,
a4: Optional[str] = None,
a5: Optional[str] = None,
a6: Optional[str] = None,
prd: Optional[str] = None,
pod: Optional[str] = None,
sts: Optional[str] = None,
hno: Optional[str] = None,
hns: Optional[str] = None,
lmk: Optional[str] = None,
loc: Optional[str] = None,
flr: Optional[str] = None,
nam: Optional[str] = None,
pc: Optional[str] = None
)Parameters:
country(str, optional): Country code (ISO 3166-1 alpha-2)a1(str, optional): Administrative area 1 (state/province)a2(str, optional): Administrative area 2 (county/municipality)a3(str, optional): Administrative area 3 (city/town)a4(str, optional): Administrative area 4 (neighborhood/district)a5(str, optional): Administrative area 5 (postal code)a6(str, optional): Administrative area 6 (building/floor)prd(str, optional): Premier (department/suite number)pod(str, optional): Post office box identifiersts(str, optional): Street namehno(str, optional): House numberhns(str, optional): House namelmk(str, optional): Landmark nameloc(str, optional): Location nameflr(str, optional): Floornam(str, optional): Name of locationpc(str, optional): Postal code
Convert CivicAddress to dictionary.
Represents party history events in a vCon dialog.
PartyHistory(party: int, event: str, time: datetime)Parameters:
party(int): Index of the partyevent(str): Event type ("join", "drop", "hold", "unhold", "mute", "unmute")time(datetime): Time of the event
Convert PartyHistory to dictionary.
Represents an attachment in a vCon.
Attachment(type: str, body: Any, encoding: str = "none")Parameters:
type(str): Type of attachmentbody(Any): Content of attachmentencoding(str): Encoding format ("base64", "base64url", "none")
Convert Attachment to dictionary.
Create attachment from image file.
The vCon library includes a comprehensive extension framework that allows for standardized implementation of additional functionality. Two major extensions are currently implemented: the Lawful Basis extension for privacy compliance and the WTF (World Transcription Format) extension for standardized transcription data.
The extension framework provides a standardized way to add new functionality to vCon objects while maintaining compatibility and validation.
Enumeration of extension types:
COMPATIBLE: Safe to ignore, no breaking changesINCOMPATIBLE: Must be supported, breaking changesEXPERIMENTAL: Development/testing only
Abstract base class for extension validation logic.
Abstract base class for extension processing logic.
Central registry for managing extensions.
from vcon.extensions import get_extension_registry
# Get the global registry
registry = get_extension_registry()
# List all registered extensions
extensions = registry.list_extensions()The Lawful Basis extension provides comprehensive support for privacy compliance and consent management according to GDPR and other privacy regulations.
- Multiple Lawful Basis Types: consent, contract, legal_obligation, vital_interests, public_task, legitimate_interests
- Purpose-Specific Permissions: Granular permission grants with conditions
- Cryptographic Proof Mechanisms: Verbal confirmation, signed documents, cryptographic signatures, external systems
- Temporal Validity: Expiration dates and status intervals
- Content Integrity: Hash validation and canonicalization
- External Registry Integration: SCITT (Supply Chain Integrity, Transparency, and Trust) support
Main class representing a lawful basis attachment.
from vcon.extensions.lawful_basis import LawfulBasisAttachment, LawfulBasisType, PurposeGrant
from datetime import datetime, timezone, timedelta
# Create purpose grants
purpose_grants = [
PurposeGrant(
purpose="recording",
granted=True,
granted_at=datetime.now(timezone.utc).isoformat()
),
PurposeGrant(
purpose="analysis",
granted=True,
granted_at=datetime.now(timezone.utc).isoformat(),
conditions=["anonymized_data_only"]
)
]
# Create lawful basis attachment
attachment = LawfulBasisAttachment(
lawful_basis=LawfulBasisType.CONSENT,
expiration=(datetime.now(timezone.utc) + timedelta(days=365)).isoformat(),
purpose_grants=purpose_grants
)Represents a purpose-specific permission grant.
grant = PurposeGrant(
purpose="recording",
granted=True,
granted_at=datetime.now(timezone.utc).isoformat(),
conditions=["anonymized_data_only"]
)Represents content integrity information.
from vcon.extensions.lawful_basis import ContentHash, HashAlgorithm, CanonicalizationMethod
content_hash = ContentHash(
algorithm=HashAlgorithm.SHA_256,
canonicalization=CanonicalizationMethod.JCS,
value="computed_hash_value"
)Represents a proof mechanism for lawful basis.
from vcon.extensions.lawful_basis import ProofMechanism, ProofType
proof = ProofMechanism(
proof_type=ProofType.VERBAL_CONFIRMATION,
timestamp=datetime.now(timezone.utc).isoformat(),
proof_data={
"dialog_reference": 0,
"confirmation_text": "I consent to recording"
}
)Validates lawful basis attachments and extension usage.
from vcon.extensions.lawful_basis import LawfulBasisValidator
validator = LawfulBasisValidator()
result = validator.validate_attachment(attachment_dict)Processes lawful basis attachments and evaluates permissions.
from vcon.extensions.lawful_basis import LawfulBasisProcessor
processor = LawfulBasisProcessor()
result = processor.check_permission(vcon_dict, "recording", party_index=0)Client for SCITT (Supply Chain Integrity, Transparency, and Trust) registries.
from vcon.extensions.lawful_basis import SCITTRegistryClient
client = SCITTRegistryClient("https://registry.example.com", auth_token="token")
receipt_id = client.submit_attestation(lawful_basis_attachment)The WTF (World Transcription Format) extension provides standardized representation of speech-to-text transcription data from multiple providers.
- Multi-Provider Support: Whisper, Deepgram, AssemblyAI, Google, Amazon, Azure, and more
- Standardized Format: Hierarchical structure with transcripts, segments, words, and speakers
- Quality Metrics: Audio quality assessment and confidence scoring
- Export Capabilities: SRT and WebVTT subtitle formats
- Provider Adapters: Automatic conversion from provider-specific formats
- Analysis Tools: Keyword extraction, confidence analysis, and transcription comparison
Main class representing a WTF transcription attachment.
from vcon.extensions.wtf import WTFAttachment, Transcript, Segment, Metadata
from datetime import datetime, timezone
# Create transcript
transcript = Transcript(
text="Hello world",
language="en",
duration=2.0,
confidence=0.95
)
# Create segments
segments = [
Segment(
id=0,
start=0.0,
end=2.0,
text="Hello world",
confidence=0.95
)
]
# Create metadata
metadata = Metadata(
created_at=datetime.now(timezone.utc).isoformat(),
processed_at=datetime.now(timezone.utc).isoformat(),
provider="whisper",
model="whisper-1"
)
# Create WTF attachment
attachment = WTFAttachment(
transcript=transcript,
segments=segments,
metadata=metadata
)Represents high-level transcript information.
transcript = Transcript(
text="Hello world",
language="en",
duration=2.0,
confidence=0.95
)Represents a logical chunk of transcribed content.
segment = Segment(
id=0,
start=0.0,
end=2.0,
text="Hello world",
confidence=0.95,
speaker=0
)Represents a single word in the transcription.
word = Word(
id=0,
start=0.0,
end=1.0,
text="Hello",
confidence=0.95,
speaker=0
)Represents speaker information for diarization.
speaker = Speaker(
id=0,
label="Speaker 1",
segments=[0, 1, 2],
total_time=10.5,
confidence=0.9
)Represents quality metrics for the transcription.
quality = Quality(
audio_quality="high",
background_noise=0.1,
multiple_speakers=True,
overlapping_speech=False,
silence_ratio=0.2,
average_confidence=0.95,
low_confidence_words=5,
processing_warnings=[]
)Converts Whisper transcription data to WTF format.
from vcon.extensions.wtf import WhisperAdapter
adapter = WhisperAdapter()
wtf_attachment = adapter.convert(whisper_data)Converts Deepgram transcription data to WTF format.
from vcon.extensions.wtf import DeepgramAdapter
adapter = DeepgramAdapter()
wtf_attachment = adapter.convert(deepgram_data)Converts AssemblyAI transcription data to WTF format.
from vcon.extensions.wtf import AssemblyAIAdapter
adapter = AssemblyAIAdapter()
wtf_attachment = adapter.convert(assemblyai_data)Export transcription to SRT subtitle format.
srt_content = attachment.export_to_srt()Export transcription to WebVTT format.
vtt_content = attachment.export_to_vtt()Extract keywords from high-confidence words.
keywords = attachment.extract_keywords(min_confidence=0.8)Find segments with confidence below threshold.
low_confidence_segments = attachment.find_low_confidence_segments(threshold=0.5)Calculate speaking time for each speaker.
speaking_times = attachment.get_speaking_time()Validates WTF transcription attachments.
from vcon.extensions.wtf import WTFValidator
validator = WTFValidator()
result = validator.validate_attachment(attachment_dict)Processes WTF transcription attachments and provides analysis.
from vcon.extensions.wtf import WTFProcessor
processor = WTFProcessor()
analysis = processor.analyze_transcription(attachment)PROPERTY_HANDLING_DEFAULT = "default" # Keep non-standard properties
PROPERTY_HANDLING_STRICT = "strict" # Remove non-standard properties
PROPERTY_HANDLING_META = "meta" # Move non-standard properties to metaVALID_TYPES = ["recording", "text", "transfer", "incomplete", "audio", "video"]VALID_DISPOSITIONS = [
"no-answer", "congestion", "failed", "busy",
"hung-up", "voicemail-no-message"
]VALID_EVENTS = ["join", "drop", "hold", "unhold", "mute", "unmute"]VALID_ENCODINGS = ["base64", "base64url", "none"]MIME_TYPES = [
"text/plain",
"audio/x-wav", "audio/wav", "audio/wave", "audio/mpeg", "audio/mp3",
"audio/x-mp3", "audio/x-mp4", "audio/ogg", "audio/webm", "audio/x-m4a", "audio/aac",
"video/x-mp4", "video/ogg", "video/mp4", "video/quicktime", "video/webm",
"video/x-msvideo", "video/x-matroska", "video/mpeg", "video/x-flv", "video/3gpp", "video/x-m4v",
"multipart/mixed", "message/rfc822",
"image/jpeg", "image/tiff", "application/pdf", "application/json"
]from vcon.extensions.base import ExtensionType
ExtensionType.COMPATIBLE # Safe to ignore, no breaking changes
ExtensionType.INCOMPATIBLE # Must be supported, breaking changes
ExtensionType.EXPERIMENTAL # Development/testing onlyfrom vcon.extensions.lawful_basis import LawfulBasisType
LawfulBasisType.CONSENT # Explicit consent
LawfulBasisType.CONTRACT # Contractual necessity
LawfulBasisType.LEGAL_OBLIGATION # Legal obligation
LawfulBasisType.VITAL_INTERESTS # Vital interests
LawfulBasisType.PUBLIC_TASK # Public task
LawfulBasisType.LEGITIMATE_INTERESTS # Legitimate interestsfrom vcon.extensions.lawful_basis import ProofType
ProofType.VERBAL_CONFIRMATION # Verbal confirmation
ProofType.SIGNED_DOCUMENT # Signed document
ProofType.CRYPTOGRAPHIC_SIGNATURE # Cryptographic signature
ProofType.EXTERNAL_SYSTEM # External system attestationfrom vcon.extensions.lawful_basis import HashAlgorithm
HashAlgorithm.SHA_256 # SHA-256
HashAlgorithm.SHA_384 # SHA-384
HashAlgorithm.SHA_512 # SHA-512from vcon.extensions.lawful_basis import CanonicalizationMethod
CanonicalizationMethod.JCS # JSON Canonicalization Schemefrom vcon.extensions.wtf import (
WhisperAdapter, # OpenAI Whisper
DeepgramAdapter, # Deepgram
AssemblyAIAdapter, # AssemblyAI
ProviderAdapter # Base adapter class
)from vcon import Vcon
from vcon.party import Party
from vcon.dialog import Dialog
from datetime import datetime
# Create new vCon
vcon = Vcon.build_new()
# Add parties
caller = Party(tel="+1234567890", name="Alice", role="caller")
agent = Party(tel="+1987654321", name="Bob", role="agent")
vcon.add_party(caller)
vcon.add_party(agent)
# Add dialog
dialog = Dialog(
type="text",
start=datetime.now(),
parties=[0, 1],
originator=0,
body="Hello, I need help with my account."
)
vcon.add_dialog(dialog)
# Save to file
vcon.save_to_file("conversation.vcon.json")# Load vCon
vcon = Vcon.load("conversation.vcon.json")
# Validate
is_valid, errors = vcon.is_valid()
if not is_valid:
print("Validation errors:", errors)
# Access data
print(f"UUID: {vcon.uuid}")
print(f"Parties: {len(vcon.parties)}")
print(f"Dialogs: {len(vcon.dialog)}")# Generate key pair
private_key, public_key = Vcon.generate_key_pair()
# Sign vCon
vcon.sign(private_key)
# Verify signature
is_valid = vcon.verify(public_key)
print(f"Signature valid: {is_valid}")# Add extensions
vcon.add_extension("video")
vcon.add_extension("encryption")
# Add must-support
vcon.add_critical("encryption")
print(f"Extensions: {vcon.get_extensions()}")
print(f"Critical: {vcon.get_critical()}")# Add analysis
vcon.add_analysis(
type="sentiment",
dialog=[0, 1],
vendor="SentimentAnalyzer",
body={"sentiment": "positive", "confidence": 0.85},
encoding="json"
)
# Add attachment
vcon.add_attachment(
type="transcript",
body="Full conversation transcript...",
encoding="none"
)
# Add tags
vcon.add_tag("customer_id", "12345")
vcon.add_tag("priority", "high")# Add video dialog
video_dialog = Dialog(
type="video",
start=datetime.now(),
parties=[0, 1],
mediatype="video/mp4",
resolution="1920x1080",
frame_rate=30.0,
codec="H.264"
)
# Add video data
video_dialog.add_video_data(
video_data=binary_video_data,
filename="recording.mp4",
mediatype="video/mp4",
inline=True
)
# Extract metadata
metadata = video_dialog.extract_video_metadata()
# Generate thumbnail
thumbnail = video_dialog.generate_thumbnail(timestamp=10.0)
vcon.add_dialog(video_dialog)from vcon.civic_address import CivicAddress
# Create civic address
address = CivicAddress(
country="US",
a1="CA",
a3="San Francisco",
sts="Market Street",
hno="123",
pc="94102"
)
# Add to party
party = Party(
name="Jane",
tel="+1555123456",
civicaddress=address
)from vcon.party import PartyHistory
# Create party history
history = [
PartyHistory(0, "join", datetime.now()),
PartyHistory(1, "join", datetime.now()),
PartyHistory(0, "hold", datetime.now()),
PartyHistory(0, "unhold", datetime.now()),
PartyHistory(1, "drop", datetime.now())
]
# Add to dialog
dialog = Dialog(
type="recording",
start=datetime.now(),
parties=[0, 1],
party_history=history
)# Post vCon to server
response = vcon.post_to_url(
"https://api.example.com/vcon",
headers={
"Authorization": "Bearer your-token",
"Content-Type": "application/json"
}
)
if response.status_code == 200:
print("Successfully posted vCon")
else:
print(f"Error: {response.status_code}")# Strict mode - remove non-standard properties
vcon = Vcon.load("file.json", property_handling="strict")
# Meta mode - move non-standard properties to meta
vcon = Vcon.load("file.json", property_handling="meta")
# Default mode - keep all properties
vcon = Vcon.load("file.json", property_handling="default")from vcon import Vcon
from vcon.party import Party
from vcon.dialog import Dialog
from datetime import datetime, timezone, timedelta
# Create vCon with parties and dialog
vcon = Vcon.build_new()
caller = Party(tel="+1234567890", name="Alice", role="caller")
agent = Party(tel="+1987654321", name="Bob", role="agent")
vcon.add_party(caller)
vcon.add_party(agent)
# Add dialog
dialog = Dialog(
type="recording",
start=datetime.now(timezone.utc),
parties=[0, 1],
mediatype="audio/mp3"
)
vcon.add_dialog(dialog)
# Add lawful basis attachment
vcon.add_lawful_basis_attachment(
lawful_basis="consent",
expiration=(datetime.now(timezone.utc) + timedelta(days=365)).isoformat(),
purpose_grants=[
{
"purpose": "recording",
"granted": True,
"granted_at": datetime.now(timezone.utc).isoformat()
},
{
"purpose": "analysis",
"granted": True,
"granted_at": datetime.now(timezone.utc).isoformat(),
"conditions": ["anonymized_data_only"]
}
],
party_index=0,
dialog_index=0
)
# Check permissions
recording_permission = vcon.check_lawful_basis_permission("recording", party_index=0)
marketing_permission = vcon.check_lawful_basis_permission("marketing", party_index=0)
print(f"Recording permission: {recording_permission}")
print(f"Marketing permission: {marketing_permission}")
# Find lawful basis attachments
attachments = vcon.find_lawful_basis_attachments(party_index=0)
print(f"Found {len(attachments)} lawful basis attachments")from vcon import Vcon
from vcon.party import Party
from vcon.dialog import Dialog
from datetime import datetime, timezone
# Create vCon with parties and dialog
vcon = Vcon.build_new()
caller = Party(tel="+1234567890", name="Alice", role="caller")
agent = Party(tel="+1987654321", name="Bob", role="agent")
vcon.add_party(caller)
vcon.add_party(agent)
# Add dialog
dialog = Dialog(
type="recording",
start=datetime.now(timezone.utc),
parties=[0, 1],
mediatype="audio/mp3"
)
vcon.add_dialog(dialog)
# Add WTF transcription attachment
vcon.add_wtf_transcription_attachment(
transcript={
"text": "Hello, this is a test transcription.",
"language": "en",
"duration": 3.5,
"confidence": 0.95
},
segments=[
{
"id": 0,
"start": 0.0,
"end": 1.5,
"text": "Hello, this is",
"confidence": 0.95,
"speaker": 0
},
{
"id": 1,
"start": 1.5,
"end": 3.5,
"text": "a test transcription.",
"confidence": 0.94,
"speaker": 0
}
],
metadata={
"created_at": datetime.now(timezone.utc).isoformat(),
"processed_at": datetime.now(timezone.utc).isoformat(),
"provider": "whisper",
"model": "whisper-1",
"audio_quality": "high",
"background_noise": 0.1
},
party_index=0,
dialog_index=0
)
# Find WTF attachments
attachments = vcon.find_wtf_attachments(party_index=0)
print(f"Found {len(attachments)} WTF attachments")
# Export to SRT format
if attachments:
from vcon.extensions.wtf import WTFAttachment
wtf_attachment = WTFAttachment.from_dict(attachments[0]["body"])
srt_content = wtf_attachment.export_to_srt()
print("SRT Export:")
print(srt_content)# Validate all extensions
validation_results = vcon.validate_extensions()
print("Extension validation results:")
for extension, result in validation_results.items():
if extension != "attachments":
status = "✓ Valid" if result["is_valid"] else "✗ Invalid"
print(f" {extension}: {status}")
if result["errors"]:
for error in result["errors"]:
print(f" Error: {error}")
if result["warnings"]:
for warning in result["warnings"]:
print(f" Warning: {warning}")
# Process all extensions
processing_results = vcon.process_extensions()
print("Extension processing completed")from vcon.extensions.wtf import WhisperAdapter, DeepgramAdapter
# Convert Whisper data to WTF format
whisper_data = {
"text": "Hello world from Whisper",
"segments": [
{
"start": 0.0,
"end": 2.0,
"text": "Hello world from Whisper"
}
]
}
whisper_adapter = WhisperAdapter()
wtf_attachment = whisper_adapter.convert(whisper_data)
# Add to vCon
vcon.add_wtf_transcription_attachment(
transcript=wtf_attachment.transcript.to_dict(),
segments=[segment.to_dict() for segment in wtf_attachment.segments],
metadata=wtf_attachment.metadata.to_dict()
)from vcon import Vcon
from vcon.party import Party
from vcon.dialog import Dialog
from datetime import datetime, timezone, timedelta
# Create comprehensive vCon with extensions
vcon = Vcon.build_new()
# Add parties
caller = Party(tel="+1234567890", name="Alice", role="caller")
agent = Party(tel="+1987654321", name="Bob", role="agent")
vcon.add_party(caller)
vcon.add_party(agent)
# Add dialog
dialog = Dialog(
type="recording",
start=datetime.now(timezone.utc),
parties=[0, 1],
mediatype="audio/mp3"
)
vcon.add_dialog(dialog)
# Add lawful basis for consent
vcon.add_lawful_basis_attachment(
lawful_basis="consent",
expiration=(datetime.now(timezone.utc) + timedelta(days=365)).isoformat(),
purpose_grants=[
{
"purpose": "recording",
"granted": True,
"granted_at": datetime.now(timezone.utc).isoformat()
},
{
"purpose": "transcription",
"granted": True,
"granted_at": datetime.now(timezone.utc).isoformat()
}
],
party_index=0
)
# Add transcription
vcon.add_wtf_transcription_attachment(
transcript={
"text": "Hello, I need help with my account.",
"language": "en",
"duration": 4.2,
"confidence": 0.92
},
segments=[
{
"id": 0,
"start": 0.0,
"end": 4.2,
"text": "Hello, I need help with my account.",
"confidence": 0.92,
"speaker": 0
}
],
metadata={
"created_at": datetime.now(timezone.utc).isoformat(),
"processed_at": datetime.now(timezone.utc).isoformat(),
"provider": "whisper",
"model": "whisper-1"
},
party_index=0,
dialog_index=0
)
# Validate and process
validation_results = vcon.validate_extensions()
processing_results = vcon.process_extensions()
# Check permissions
can_record = vcon.check_lawful_basis_permission("recording", party_index=0)
can_transcribe = vcon.check_lawful_basis_permission("transcription", party_index=0)
print(f"Can record: {can_record}")
print(f"Can transcribe: {can_transcribe}")
# Save vCon
vcon.save_to_file("conversation_with_extensions.vcon.json")
print("Saved vCon with extensions")This API reference covers all the main functionality of the vCon library, including the new extension framework. For more detailed examples and use cases, see the Quickstart Guide and the samples directory.