Skip to content

Commit eb96b78

Browse files
authored
fix: add separate realtime_base_url defaulting to wss://api3.decart.ai (#35)
Aligns Python SDK with JS SDK which uses separate base URLs for batch (https://api.decart.ai) and realtime (wss://api3.decart.ai). Previously, the Python SDK used the same base_url for both, converting https://api.decart.ai to wss://api.decart.ai for WebSocket connections. Changes: - Add realtime_base_url param to DecartClient (default: wss://api3.decart.ai) - Update all examples and tests to use client.realtime_base_url for realtime - Update lipsync client default to wss://api3.decart.ai
1 parent b6b5712 commit eb96b78

7 files changed

Lines changed: 32 additions & 29 deletions

File tree

decart/client.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class DecartClient:
2323
2424
Args:
2525
api_key: Your Decart API key. Defaults to the DECART_API_KEY environment variable.
26-
base_url: API base URL (defaults to production)
26+
base_url: API base URL for batch/process/queue endpoints (defaults to https://api.decart.ai)
27+
realtime_base_url: WebSocket base URL for realtime streaming (defaults to wss://api3.decart.ai)
2728
integration: Optional integration identifier (e.g., "langchain/0.1.0")
2829
2930
Example:
@@ -52,6 +53,7 @@ def __init__(
5253
self,
5354
api_key: Optional[str] = None,
5455
base_url: str = "https://api.decart.ai",
56+
realtime_base_url: str = "wss://api3.decart.ai",
5557
integration: Optional[str] = None,
5658
) -> None:
5759
resolved_api_key = api_key or os.environ.get("DECART_API_KEY", "").strip() or None
@@ -64,6 +66,7 @@ def __init__(
6466

6567
self.api_key = resolved_api_key
6668
self.base_url = base_url
69+
self.realtime_base_url = realtime_base_url
6770
self.integration = integration
6871
self._session: Optional[aiohttp.ClientSession] = None
6972
self._queue: Optional[QueueClient] = None

decart/lipsync/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class RealtimeLipsyncClient:
2929
def __init__(
3030
self,
3131
api_key: str,
32-
base_url: str = "https://api.decart.ai",
32+
base_url: str = "wss://api3.decart.ai",
3333
audio_sample_rate: int = 16000,
3434
video_fps: int = VIDEO_FPS,
3535
sync_latency: float = 0.0,

examples/avatar_live.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def on_error(error):
115115

116116
try:
117117
realtime_client = await RealtimeClient.connect(
118-
base_url=client.base_url,
118+
base_url=client.realtime_base_url,
119119
api_key=client.api_key,
120120
local_track=audio_track, # Can be None if no audio
121121
options=RealtimeConnectOptions(

examples/realtime_file.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def on_error(error):
7979
from decart.types import ModelState, Prompt
8080

8181
realtime_client = await RealtimeClient.connect(
82-
base_url=client.base_url,
82+
base_url=client.realtime_base_url,
8383
api_key=client.api_key,
8484
local_track=player.video,
8585
options=RealtimeConnectOptions(

examples/realtime_synthetic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def on_error(error):
105105
from decart.types import ModelState, Prompt
106106

107107
realtime_client = await RealtimeClient.connect(
108-
base_url=client.base_url,
108+
base_url=client.realtime_base_url,
109109
api_key=client.api_key,
110110
local_track=video_track,
111111
options=RealtimeConnectOptions(

playground/playground.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ def on_error(error: Exception) -> None:
321321
client = DecartClient(api_key=api_key)
322322

323323
realtime = await RealtimeClient.connect(
324-
base_url=client.base_url,
324+
base_url=client.realtime_base_url,
325325
api_key=client.api_key,
326326
local_track=local_track,
327327
options=RealtimeConnectOptions(

tests/test_realtime_unit.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ async def test_realtime_client_creation_with_mock():
8282
from decart.types import ModelState, Prompt
8383

8484
realtime_client = await RealtimeClient.connect(
85-
base_url=client.base_url,
85+
base_url=client.realtime_base_url,
8686
api_key=client.api_key,
8787
local_track=mock_track,
8888
options=RealtimeConnectOptions(
@@ -143,7 +143,7 @@ def register_prompt_wait(prompt):
143143
from decart.realtime.types import RealtimeConnectOptions
144144

145145
realtime_client = await RealtimeClient.connect(
146-
base_url=client.base_url,
146+
base_url=client.realtime_base_url,
147147
api_key=client.api_key,
148148
local_track=mock_track,
149149
options=RealtimeConnectOptions(
@@ -182,7 +182,7 @@ async def test_buffered_events_delivered_after_handler_registration():
182182
from decart.realtime.types import RealtimeConnectOptions
183183

184184
realtime_client = await RealtimeClient.connect(
185-
base_url=client.base_url,
185+
base_url=client.realtime_base_url,
186186
api_key=client.api_key,
187187
local_track=mock_track,
188188
options=RealtimeConnectOptions(
@@ -219,7 +219,7 @@ async def test_realtime_events():
219219
from decart.realtime.types import RealtimeConnectOptions
220220

221221
realtime_client = await RealtimeClient.connect(
222-
base_url=client.base_url,
222+
base_url=client.realtime_base_url,
223223
api_key=client.api_key,
224224
local_track=mock_track,
225225
options=RealtimeConnectOptions(
@@ -281,7 +281,7 @@ def register_prompt_wait(prompt):
281281
from decart.realtime.types import RealtimeConnectOptions
282282

283283
realtime_client = await RealtimeClient.connect(
284-
base_url=client.base_url,
284+
base_url=client.realtime_base_url,
285285
api_key=client.api_key,
286286
local_track=mock_track,
287287
options=RealtimeConnectOptions(
@@ -328,7 +328,7 @@ def register_prompt_wait(prompt):
328328
from decart.realtime.types import RealtimeConnectOptions
329329

330330
realtime_client = await RealtimeClient.connect(
331-
base_url=client.base_url,
331+
base_url=client.realtime_base_url,
332332
api_key=client.api_key,
333333
local_track=mock_track,
334334
options=RealtimeConnectOptions(
@@ -396,7 +396,7 @@ async def test_avatar_live_connect_with_initial_image():
396396
from decart.types import ModelState
397397

398398
realtime_client = await RealtimeClient.connect(
399-
base_url=client.base_url,
399+
base_url=client.realtime_base_url,
400400
api_key=client.api_key,
401401
local_track=mock_track,
402402
options=RealtimeConnectOptions(
@@ -444,7 +444,7 @@ async def test_avatar_live_set_image():
444444
from decart.realtime.types import RealtimeConnectOptions
445445

446446
realtime_client = await RealtimeClient.connect(
447-
base_url=client.base_url,
447+
base_url=client.realtime_base_url,
448448
api_key=client.api_key,
449449
local_track=mock_track,
450450
options=RealtimeConnectOptions(
@@ -487,7 +487,7 @@ async def test_set_image_works_for_any_model():
487487
from decart.realtime.types import RealtimeConnectOptions
488488

489489
realtime_client = await RealtimeClient.connect(
490-
base_url=client.base_url,
490+
base_url=client.realtime_base_url,
491491
api_key=client.api_key,
492492
local_track=mock_track,
493493
options=RealtimeConnectOptions(
@@ -524,7 +524,7 @@ async def test_set_image_null_clears_image():
524524
from decart.realtime.types import RealtimeConnectOptions
525525

526526
realtime_client = await RealtimeClient.connect(
527-
base_url=client.base_url,
527+
base_url=client.realtime_base_url,
528528
api_key=client.api_key,
529529
local_track=mock_track,
530530
options=RealtimeConnectOptions(
@@ -565,7 +565,7 @@ async def test_set_image_with_prompt_and_enhance():
565565
from decart.realtime.types import RealtimeConnectOptions
566566

567567
realtime_client = await RealtimeClient.connect(
568-
base_url=client.base_url,
568+
base_url=client.realtime_base_url,
569569
api_key=client.api_key,
570570
local_track=mock_track,
571571
options=RealtimeConnectOptions(
@@ -610,7 +610,7 @@ async def test_avatar_live_set_image_timeout():
610610
from decart.realtime.types import RealtimeConnectOptions
611611

612612
realtime_client = await RealtimeClient.connect(
613-
base_url=client.base_url,
613+
base_url=client.realtime_base_url,
614614
api_key=client.api_key,
615615
local_track=mock_track,
616616
options=RealtimeConnectOptions(
@@ -655,7 +655,7 @@ async def test_avatar_live_set_image_server_error():
655655
from decart.realtime.types import RealtimeConnectOptions
656656

657657
realtime_client = await RealtimeClient.connect(
658-
base_url=client.base_url,
658+
base_url=client.realtime_base_url,
659659
api_key=client.api_key,
660660
local_track=mock_track,
661661
options=RealtimeConnectOptions(
@@ -698,7 +698,7 @@ async def test_set_rejects_when_neither_prompt_nor_image():
698698
from decart.errors import InvalidInputError
699699

700700
realtime_client = await RealtimeClient.connect(
701-
base_url=client.base_url,
701+
base_url=client.realtime_base_url,
702702
api_key=client.api_key,
703703
local_track=mock_track,
704704
options=RealtimeConnectOptions(
@@ -736,7 +736,7 @@ async def test_set_rejects_empty_prompt():
736736
from decart.errors import InvalidInputError
737737

738738
realtime_client = await RealtimeClient.connect(
739-
base_url=client.base_url,
739+
base_url=client.realtime_base_url,
740740
api_key=client.api_key,
741741
local_track=mock_track,
742742
options=RealtimeConnectOptions(
@@ -774,7 +774,7 @@ async def test_set_sends_prompt_only():
774774
from decart.realtime.client import SetInput
775775

776776
realtime_client = await RealtimeClient.connect(
777-
base_url=client.base_url,
777+
base_url=client.realtime_base_url,
778778
api_key=client.api_key,
779779
local_track=mock_track,
780780
options=RealtimeConnectOptions(
@@ -820,7 +820,7 @@ async def test_set_sends_prompt_with_enhance():
820820
from decart.realtime.client import SetInput
821821

822822
realtime_client = await RealtimeClient.connect(
823-
base_url=client.base_url,
823+
base_url=client.realtime_base_url,
824824
api_key=client.api_key,
825825
local_track=mock_track,
826826
options=RealtimeConnectOptions(
@@ -869,7 +869,7 @@ async def test_set_sends_image_only():
869869
from decart.realtime.client import SetInput
870870

871871
realtime_client = await RealtimeClient.connect(
872-
base_url=client.base_url,
872+
base_url=client.realtime_base_url,
873873
api_key=client.api_key,
874874
local_track=mock_track,
875875
options=RealtimeConnectOptions(
@@ -919,7 +919,7 @@ async def test_set_sends_prompt_and_image():
919919
from decart.realtime.client import SetInput
920920

921921
realtime_client = await RealtimeClient.connect(
922-
base_url=client.base_url,
922+
base_url=client.realtime_base_url,
923923
api_key=client.api_key,
924924
local_track=mock_track,
925925
options=RealtimeConnectOptions(
@@ -968,7 +968,7 @@ async def test_set_converts_bytes_image():
968968
from decart.realtime.client import SetInput
969969

970970
realtime_client = await RealtimeClient.connect(
971-
base_url=client.base_url,
971+
base_url=client.realtime_base_url,
972972
api_key=client.api_key,
973973
local_track=mock_track,
974974
options=RealtimeConnectOptions(
@@ -1017,7 +1017,7 @@ async def test_connect_with_initial_prompt():
10171017
from decart.types import ModelState, Prompt
10181018

10191019
realtime_client = await RealtimeClient.connect(
1020-
base_url=client.base_url,
1020+
base_url=client.realtime_base_url,
10211021
api_key=client.api_key,
10221022
local_track=mock_track,
10231023
options=RealtimeConnectOptions(
@@ -1123,7 +1123,7 @@ async def test_connect_without_initial_state_sends_passthrough():
11231123
from decart.realtime.types import RealtimeConnectOptions
11241124

11251125
realtime_client = await RealtimeClient.connect(
1126-
base_url=client.base_url,
1126+
base_url=client.realtime_base_url,
11271127
api_key=client.api_key,
11281128
local_track=mock_track,
11291129
options=RealtimeConnectOptions(
@@ -1195,7 +1195,7 @@ async def test_subscribe_mode_skips_passthrough():
11951195
from decart.realtime.subscribe import SubscribeOptions
11961196

11971197
sub_client = await RealtimeClient.subscribe(
1198-
base_url=client.base_url,
1198+
base_url=client.realtime_base_url,
11991199
api_key=client.api_key,
12001200
options=SubscribeOptions(
12011201
token=token,

0 commit comments

Comments
 (0)