From 02d92402dc7a1c0300f99fd110c1d5f3223f2ae9 Mon Sep 17 00:00:00 2001 From: superchilled Date: Mon, 24 Aug 2026 15:49:04 +0100 Subject: [PATCH 1/9] Adding unit test for Audio Transport configuration --- video/tests/test_audio_connector.py | 43 +++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/video/tests/test_audio_connector.py b/video/tests/test_audio_connector.py index 32ee4ad0..1878d6c4 100644 --- a/video/tests/test_audio_connector.py +++ b/video/tests/test_audio_connector.py @@ -59,6 +59,49 @@ def test_audio_connector_options_model(): assert actual == expected +def test_audio_connector_options_model_with_audio_transport(): + options = AudioConnectorOptions( + session_id='test_session_id', + token='test_token', + websocket=AudioConnectorWebSocket( + uri='test_uri', + streams=['test_stream_id'], + headers={'test_header': 'test_value'}, + audio_rate=AudioSampleRate.KHZ_16, + bidirectional=True, + audio_transport=AudioTransportConfiguration( + transport=AudioTransportTransport.JSON, + encoding=AudioTransportEncoding.BASE64, + audio_field='audio', + receive_audio_field='audio', + static_fields={'foo': 'bar'} + ) + ), + ) + + actual = options.model_dump(by_alias=True) + expected = { + 'sessionId': 'test_session_id', + 'token': 'test_token', + 'websocket': { + 'uri': 'test_uri', + 'streams': ['test_stream_id'], + 'headers': {'test_header': 'test_value'}, + 'audioRate': 16000, + 'bidirectional': True, + 'audioTransport': { + 'transport': 'json', + 'encoding': 'base64', + 'audio_field': 'audio', + 'receive_audio_field': 'audio', + 'static_fields': { + 'foo': 'bar' + } + }, + }, + } + assert actual == expected + @responses.activate def test_start_audio_connector(): build_response( From 9278ffc88e3078e30ea11ba0ec5532401219087d Mon Sep 17 00:00:00 2001 From: superchilled Date: Mon, 24 Aug 2026 15:57:24 +0100 Subject: [PATCH 2/9] Defining AudioTransportConfiguration model --- .../src/vonage_video/models/audio_connector.py | 17 +++++++++++++++++ video/tests/test_audio_connector.py | 2 ++ 2 files changed, 19 insertions(+) diff --git a/video/src/vonage_video/models/audio_connector.py b/video/src/vonage_video/models/audio_connector.py index 4c8fc060..085b0f6d 100644 --- a/video/src/vonage_video/models/audio_connector.py +++ b/video/src/vonage_video/models/audio_connector.py @@ -3,6 +3,23 @@ from pydantic import BaseModel, Field from vonage_video.models.enums import AudioSampleRate +class AudioTransportConfiguration(BaseModel): + """The audio transport configuration. + + Args: + transport (AudioTransportTransport): 'binary' (raw PCM16, the default) or 'json'. + encoding (AudioTransportEncoding): Required when transport is 'json'. Set to 'base64'. + audio_field (str): The JSON key for the outbound audio data. Defaults to 'audio'. + receive_audio_field (str): The JSON key for inbound audio data (when bidirectional is enabled). Defaults to the same value as audio_field. + static_fields (dict): A dictionary of extra key-value pairs included in every outbound JSON audio message. + """ + + transport: Optional[AudioTransportTransport] = None + encoding: Optional[AudioTransportEncoding] = None + audio_field: Optional[str] = None + receive_audio_field: Optional[str] = None + static_fields: Optional[dict] = None + class AudioConnectorWebSocket(BaseModel): """The audio connector websocket options. diff --git a/video/tests/test_audio_connector.py b/video/tests/test_audio_connector.py index 1878d6c4..11c05555 100644 --- a/video/tests/test_audio_connector.py +++ b/video/tests/test_audio_connector.py @@ -11,6 +11,8 @@ Video, ) +from vonage_video.models.audio_connector import AudioTransportConfiguration + from testutils import build_response, get_mock_jwt_auth path = abspath(__file__) From c427f286eedc31f684fe38550992a418dba81ca4 Mon Sep 17 00:00:00 2001 From: superchilled Date: Mon, 24 Aug 2026 16:09:02 +0100 Subject: [PATCH 3/9] Defining enums for audio transport configuration --- video/src/vonage_video/models/audio_connector.py | 1 + video/src/vonage_video/models/enums.py | 13 +++++++++++++ video/tests/test_audio_connector.py | 1 + 3 files changed, 15 insertions(+) diff --git a/video/src/vonage_video/models/audio_connector.py b/video/src/vonage_video/models/audio_connector.py index 085b0f6d..514ad877 100644 --- a/video/src/vonage_video/models/audio_connector.py +++ b/video/src/vonage_video/models/audio_connector.py @@ -2,6 +2,7 @@ from pydantic import BaseModel, Field from vonage_video.models.enums import AudioSampleRate +from vonage_video.models.enums import AudioTransportEncoding, AudioTransportTransport class AudioTransportConfiguration(BaseModel): """The audio transport configuration. diff --git a/video/src/vonage_video/models/enums.py b/video/src/vonage_video/models/enums.py index 24e594ac..9ec91602 100644 --- a/video/src/vonage_video/models/enums.py +++ b/video/src/vonage_video/models/enums.py @@ -55,6 +55,19 @@ class AudioSampleRate(int, Enum): KHZ_16 = 16000 +class AudioTransportEncoding(str, Enum): + """Audio encoding type when using JSON transport.""" + + BASE64 = 'base64' + + +class AudioTransportTransport(str, Enum): + """Audio transport type for the WebSocket connection.""" + + BINARY = 'binary' + JSON = 'json' + + class VideoResolution(str, Enum): """The resolution of the archive or broadcast. diff --git a/video/tests/test_audio_connector.py b/video/tests/test_audio_connector.py index 11c05555..8b8adb04 100644 --- a/video/tests/test_audio_connector.py +++ b/video/tests/test_audio_connector.py @@ -12,6 +12,7 @@ ) from vonage_video.models.audio_connector import AudioTransportConfiguration +from vonage_video.models.enums import AudioTransportEncoding, AudioTransportTransport from testutils import build_response, get_mock_jwt_auth From 760dc5d91085c20ef2ce6d84ffe739fa1aaa4ed4 Mon Sep 17 00:00:00 2001 From: superchilled Date: Mon, 24 Aug 2026 16:19:08 +0100 Subject: [PATCH 4/9] Updating AudioConnectorWebSocket model to add audio_transport param --- video/src/vonage_video/models/audio_connector.py | 4 ++++ video/tests/test_audio_connector.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/video/src/vonage_video/models/audio_connector.py b/video/src/vonage_video/models/audio_connector.py index 514ad877..0d49fb71 100644 --- a/video/src/vonage_video/models/audio_connector.py +++ b/video/src/vonage_video/models/audio_connector.py @@ -31,6 +31,7 @@ class AudioConnectorWebSocket(BaseModel): headers (dict): The headers to send to your WebSocket server. audio_rate (AudioSampleRate): The audio sample rate in Hertz. bidirectional (bool): Whether the websocket is bidirectional. + audio_transport (AudioTransportConfiguration): The audio transport configuration. Configures how audio is serialized on the WebSocket wire. By default, audio is sent as raw binary PCM 16-bit frames. """ uri: str @@ -40,6 +41,9 @@ class AudioConnectorWebSocket(BaseModel): bidirectional: Optional[bool] = Field( None, description="Whether the websocket is bidirectional." ) + audio_transport: Optional[AudioTransportConfiguration] = Field( + None, serialization_alias='audioTransport' + ) def model_dump(self, *args, **kwargs): data = super().model_dump(*args, **kwargs) diff --git a/video/tests/test_audio_connector.py b/video/tests/test_audio_connector.py index 8b8adb04..daca84c2 100644 --- a/video/tests/test_audio_connector.py +++ b/video/tests/test_audio_connector.py @@ -47,7 +47,7 @@ def test_audio_connector_options_model(): ), ) - actual = options.model_dump(by_alias=True) + actual = options.model_dump(by_alias=True, exclude_none=True) expected = { 'sessionId': 'test_session_id', 'token': 'test_token', @@ -82,7 +82,7 @@ def test_audio_connector_options_model_with_audio_transport(): ), ) - actual = options.model_dump(by_alias=True) + actual = options.model_dump(by_alias=True, exclude_none=True) expected = { 'sessionId': 'test_session_id', 'token': 'test_token', From 8855a7f11fcfe0a61ecc418e0c9db1a3d3723fa1 Mon Sep 17 00:00:00 2001 From: superchilled Date: Mon, 24 Aug 2026 16:39:55 +0100 Subject: [PATCH 5/9] Updating imports in __init__.py --- video/src/vonage_video/models/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/video/src/vonage_video/models/__init__.py b/video/src/vonage_video/models/__init__.py index 83697351..13071441 100644 --- a/video/src/vonage_video/models/__init__.py +++ b/video/src/vonage_video/models/__init__.py @@ -3,6 +3,7 @@ AudioConnectorData, AudioConnectorOptions, AudioConnectorWebSocket, + AudioTransportConfiguration, ) from .broadcast import ( Broadcast, @@ -22,6 +23,8 @@ ArchiveMode, ArchiveStatus, AudioSampleRate, + AudioTransportEncoding, + AudioTransportTransport, ExperienceComposerStatus, LanguageCode, LayoutType, @@ -48,6 +51,9 @@ "AudioConnectorData", "AudioConnectorOptions", "AudioConnectorWebSocket", + "AudioTransportConfiguration", + "AudioTransportEncoding", + "AudioTransportTransport", "Archive", "ListArchivesFilter", "Transcription", From c9e2902351d33e864184bd7dacc37d329a4f7d10 Mon Sep 17 00:00:00 2001 From: superchilled Date: Mon, 24 Aug 2026 16:42:31 +0100 Subject: [PATCH 6/9] Linting --- video/src/vonage_video/models/audio_connector.py | 8 ++++++-- video/tests/test_audio_connector.py | 10 ++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/video/src/vonage_video/models/audio_connector.py b/video/src/vonage_video/models/audio_connector.py index 0d49fb71..2448d0ae 100644 --- a/video/src/vonage_video/models/audio_connector.py +++ b/video/src/vonage_video/models/audio_connector.py @@ -1,8 +1,12 @@ from typing import Optional from pydantic import BaseModel, Field -from vonage_video.models.enums import AudioSampleRate -from vonage_video.models.enums import AudioTransportEncoding, AudioTransportTransport +from vonage_video.models.enums import ( + AudioSampleRate, + AudioTransportEncoding, + AudioTransportTransport, +) + class AudioTransportConfiguration(BaseModel): """The audio transport configuration. diff --git a/video/tests/test_audio_connector.py b/video/tests/test_audio_connector.py index daca84c2..2310dc59 100644 --- a/video/tests/test_audio_connector.py +++ b/video/tests/test_audio_connector.py @@ -10,7 +10,6 @@ TokenRole, Video, ) - from vonage_video.models.audio_connector import AudioTransportConfiguration from vonage_video.models.enums import AudioTransportEncoding, AudioTransportTransport @@ -77,8 +76,8 @@ def test_audio_connector_options_model_with_audio_transport(): encoding=AudioTransportEncoding.BASE64, audio_field='audio', receive_audio_field='audio', - static_fields={'foo': 'bar'} - ) + static_fields={'foo': 'bar'}, + ), ), ) @@ -97,14 +96,13 @@ def test_audio_connector_options_model_with_audio_transport(): 'encoding': 'base64', 'audio_field': 'audio', 'receive_audio_field': 'audio', - 'static_fields': { - 'foo': 'bar' - } + 'static_fields': {'foo': 'bar'}, }, }, } assert actual == expected + @responses.activate def test_start_audio_connector(): build_response( From f4c41921699f9cc91efa065d5516b48d8cd57b31 Mon Sep 17 00:00:00 2001 From: superchilled Date: Tue, 25 Aug 2026 10:22:41 +0100 Subject: [PATCH 7/9] Adding unit test for invalid transport and encoding combination --- video/tests/test_audio_connector.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/video/tests/test_audio_connector.py b/video/tests/test_audio_connector.py index 2310dc59..cf90972d 100644 --- a/video/tests/test_audio_connector.py +++ b/video/tests/test_audio_connector.py @@ -1,6 +1,8 @@ from os.path import abspath import responses +import pytest +from pydantic import ValidationError from vonage_http_client import HttpClient from vonage_video import ( AudioConnectorOptions, @@ -103,6 +105,12 @@ def test_audio_connector_options_model_with_audio_transport(): assert actual == expected +def test_audio_transport_configuration_model_with_json_transport_and_encoding_not_set(): + with pytest.raises(ValidationError) as err: + config = AudioTransportConfiguration(transport=AudioTransportTransport.JSON) + assert "encoding must be specified when transport is JSON" in str(err.value) + + @responses.activate def test_start_audio_connector(): build_response( From 683db1ef3c1db8d127ae60230a6c7f9f1a2c9be5 Mon Sep 17 00:00:00 2001 From: superchilled Date: Tue, 25 Aug 2026 10:25:59 +0100 Subject: [PATCH 8/9] Adding model validator for json transport and encoding param requirement --- video/src/vonage_video/models/audio_connector.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/video/src/vonage_video/models/audio_connector.py b/video/src/vonage_video/models/audio_connector.py index 2448d0ae..9baf999c 100644 --- a/video/src/vonage_video/models/audio_connector.py +++ b/video/src/vonage_video/models/audio_connector.py @@ -1,6 +1,6 @@ from typing import Optional -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, model_validator from vonage_video.models.enums import ( AudioSampleRate, AudioTransportEncoding, @@ -25,6 +25,14 @@ class AudioTransportConfiguration(BaseModel): receive_audio_field: Optional[str] = None static_fields: Optional[dict] = None + @model_validator(mode='after') + def encoding_must_be_specified_for_json_transport(self): + if self.transport == AudioTransportTransport.JSON and not self.encoding: + raise ValueError( + "encoding must be specified when transport is JSON" + ) + return self + class AudioConnectorWebSocket(BaseModel): """The audio connector websocket options. From 16a4882ab88643487086bf8cd1132928cb6a22f2 Mon Sep 17 00:00:00 2001 From: superchilled Date: Tue, 25 Aug 2026 10:32:51 +0100 Subject: [PATCH 9/9] Linting --- video/src/vonage_video/models/audio_connector.py | 4 +--- video/tests/test_audio_connector.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/video/src/vonage_video/models/audio_connector.py b/video/src/vonage_video/models/audio_connector.py index 9baf999c..def7e76f 100644 --- a/video/src/vonage_video/models/audio_connector.py +++ b/video/src/vonage_video/models/audio_connector.py @@ -28,9 +28,7 @@ class AudioTransportConfiguration(BaseModel): @model_validator(mode='after') def encoding_must_be_specified_for_json_transport(self): if self.transport == AudioTransportTransport.JSON and not self.encoding: - raise ValueError( - "encoding must be specified when transport is JSON" - ) + raise ValueError("encoding must be specified when transport is JSON") return self diff --git a/video/tests/test_audio_connector.py b/video/tests/test_audio_connector.py index cf90972d..9cade010 100644 --- a/video/tests/test_audio_connector.py +++ b/video/tests/test_audio_connector.py @@ -1,7 +1,7 @@ from os.path import abspath -import responses import pytest +import responses from pydantic import ValidationError from vonage_http_client import HttpClient from vonage_video import (