Skip to content

Commit 41ec538

Browse files
committed
chore: add utility script for testing SFU connection and retry behavior
1 parent 66708cd commit 41ec538

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

scripts/test_sfu_connect.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Utility script for testing SFU connection and retry behavior.
4+
5+
Connects to a call as a given user and logs each step of the connection
6+
process — useful for verifying SFU assignment, retry on transient errors
7+
(e.g. SFU_FULL), and reassignment via the coordinator.
8+
9+
Environment variables
10+
---------------------
11+
STREAM_API_KEY — Stream API key (required)
12+
STREAM_API_SECRET — Stream API secret (required)
13+
STREAM_BASE_URL — Coordinator URL (default: Stream cloud).
14+
Set to http://127.0.0.1:3030 for a local coordinator.
15+
USER_ID — User ID to join as (default: "test-user").
16+
CALL_TYPE — Call type (default: "default").
17+
CALL_ID — Call ID. If not set, a random UUID is generated.
18+
19+
Usage
20+
-----
21+
# Connect via cloud coordinator
22+
STREAM_API_KEY=... STREAM_API_SECRET=... \\
23+
uv run --extra webrtc python scripts/test_sfu_connect.py
24+
25+
# Connect via local coordinator
26+
STREAM_BASE_URL=http://127.0.0.1:3030 \\
27+
uv run --extra webrtc python scripts/test_sfu_connect.py
28+
"""
29+
30+
import asyncio
31+
import logging
32+
import os
33+
import uuid
34+
35+
from dotenv import load_dotenv
36+
37+
from getstream import AsyncStream
38+
from getstream.models import CallRequest
39+
from getstream.video.rtc import ConnectionManager
40+
41+
load_dotenv()
42+
43+
logging.basicConfig(
44+
level=logging.INFO,
45+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
46+
)
47+
logger = logging.getLogger(__name__)
48+
49+
50+
async def run():
51+
base_url = os.getenv("STREAM_BASE_URL")
52+
user_id = os.getenv("USER_ID", "test-user")
53+
call_type = os.getenv("CALL_TYPE", "default")
54+
call_id = os.getenv("CALL_ID", str(uuid.uuid4()))
55+
56+
logger.info("Configuration:")
57+
logger.info(f" Coordinator: {base_url or 'cloud (default)'}")
58+
logger.info(f" User: {user_id}")
59+
logger.info(f" Call: {call_type}:{call_id}")
60+
61+
client_kwargs = {}
62+
if base_url:
63+
client_kwargs["base_url"] = base_url
64+
65+
client = AsyncStream(timeout=10.0, **client_kwargs)
66+
67+
call = client.video.call(call_type, call_id)
68+
logger.info("Creating call...")
69+
await call.get_or_create(data=CallRequest(created_by_id=user_id))
70+
logger.info("Call created")
71+
72+
cm = ConnectionManager(
73+
call=call,
74+
user_id=user_id,
75+
create=False,
76+
)
77+
78+
logger.info("Connecting to SFU...")
79+
80+
async with cm:
81+
join = cm.join_response
82+
if join and join.credentials:
83+
logger.info(f"Connected to SFU: {join.credentials.server.edge_name}")
84+
logger.info(f" WS endpoint: {join.credentials.server.ws_endpoint}")
85+
logger.info(f" Session ID: {cm.session_id}")
86+
87+
logger.info("Holding connection for 3s...")
88+
await asyncio.sleep(3)
89+
90+
logger.info("Leaving call")
91+
92+
logger.info("Done")
93+
94+
95+
if __name__ == "__main__":
96+
asyncio.run(run())

0 commit comments

Comments
 (0)