@@ -91,12 +91,12 @@ class ArchiveModes(Enum):
9191
9292
9393valid_archive_resolutions = {
94- ' 640x480' ,
95- ' 480x640' ,
96- ' 1280x720' ,
97- ' 720x1280' ,
98- ' 1920x1080' ,
99- ' 1080x1920' ,
94+ " 640x480" ,
95+ " 480x640" ,
96+ " 1280x720" ,
97+ " 720x1280" ,
98+ " 1920x1080" ,
99+ " 1080x1920" ,
100100}
101101
102102logger = logging .getLogger ("opentok" )
@@ -125,6 +125,9 @@ def __init__(
125125 self ._proxies = None
126126 self .endpoints = Endpoints (api_url , self .api_key )
127127 self ._app_version = __version__ if app_version == None else app_version
128+ self ._user_agent = (
129+ f"OpenTok-Python-SDK/{ self .app_version } python/{ platform .python_version ()} "
130+ )
128131 # JWT custom claims - Default values
129132 self ._jwt_livetime = 3 # In minutes
130133
@@ -144,6 +147,13 @@ def app_version(self):
144147 def app_version (self , value ):
145148 self ._app_version = value
146149
150+ @property
151+ def user_agent (self ):
152+ return self ._user_agent
153+
154+ def append_to_user_agent (self , value ):
155+ self ._user_agent = self ._user_agent + value
156+
147157 @property
148158 def jwt_livetime (self ):
149159 return self ._jwt_livetime
@@ -408,7 +418,7 @@ def create_session(
408418 "A session with always archive mode must also have the routed media mode."
409419 )
410420 )
411-
421+
412422 if archive_name is not None :
413423 if archive_mode == ArchiveModes .manual :
414424 raise OpenTokException (
@@ -418,7 +428,7 @@ def create_session(
418428 raise OpenTokException (
419429 "archive_name must be between 1 and 80 characters in length."
420430 )
421-
431+
422432 if archive_resolution is not None :
423433 if archive_mode == ArchiveModes .manual :
424434 raise OpenTokException (
@@ -631,13 +641,13 @@ def start_archive(
631641 }
632642
633643 if layout is not None :
634- payload [' layout' ] = layout
644+ payload [" layout" ] = layout
635645
636646 logger .debug (
637647 "POST to %r with params %r, headers %r, proxies %r" ,
638648 self .endpoints .archive_url (),
639649 json .dumps (payload ),
640- self .json_headers (),
650+ self .get_json_headers (),
641651 self .proxies ,
642652 )
643653
@@ -683,7 +693,7 @@ def stop_archive(self, archive_id):
683693 logger .debug (
684694 "POST to %r with headers %r, proxies %r" ,
685695 self .endpoints .archive_url (archive_id ) + "/stop" ,
686- self .json_headers (),
696+ self .get_json_headers (),
687697 self .proxies ,
688698 )
689699
@@ -718,7 +728,7 @@ def delete_archive(self, archive_id):
718728 logger .debug (
719729 "DELETE to %r with headers %r, proxies %r" ,
720730 self .endpoints .archive_url (archive_id ),
721- self .json_headers (),
731+ self .get_json_headers (),
722732 self .proxies ,
723733 )
724734
@@ -748,7 +758,7 @@ def get_archive(self, archive_id):
748758 logger .debug (
749759 "GET to %r with headers %r, proxies %r" ,
750760 self .endpoints .archive_url (archive_id ),
751- self .json_headers (),
761+ self .get_json_headers (),
752762 self .proxies ,
753763 )
754764
@@ -794,7 +804,7 @@ def get_archives(self, offset=None, count=None, session_id=None):
794804 logger .debug (
795805 "GET to %r with headers %r, proxies %r" ,
796806 endpoint ,
797- self .json_headers (),
807+ self .get_json_headers (),
798808 self .proxies ,
799809 )
800810
@@ -942,7 +952,7 @@ def send_signal(self, session_id, payload, connection_id=None):
942952 "POST to %r with params %r, headers %r, proxies %r" ,
943953 self .endpoints .signaling_url (session_id , connection_id ),
944954 json .dumps (payload ),
945- self .json_headers (),
955+ self .get_json_headers (),
946956 self .proxies ,
947957 )
948958
@@ -997,7 +1007,7 @@ def get_stream(self, session_id, stream_id):
9971007 logger .debug (
9981008 "GET to %r with headers %r, proxies %r" ,
9991009 endpoint ,
1000- self .json_headers (),
1010+ self .get_json_headers (),
10011011 self .proxies ,
10021012 )
10031013
@@ -1034,7 +1044,7 @@ def list_streams(self, session_id):
10341044 logger .debug (
10351045 "GET to %r with headers %r, proxies %r" ,
10361046 endpoint ,
1037- self .json_headers (),
1047+ self .get_json_headers (),
10381048 self .proxies ,
10391049 )
10401050
@@ -1072,7 +1082,7 @@ def force_disconnect(self, session_id, connection_id):
10721082 logger .debug (
10731083 "DELETE to %r with headers %r, proxies %r" ,
10741084 endpoint ,
1075- self .json_headers (),
1085+ self .get_json_headers (),
10761086 self .proxies ,
10771087 )
10781088
@@ -1134,7 +1144,7 @@ def set_archive_layout(
11341144 "PUT to %r with params %r, headers %r, proxies %r" ,
11351145 endpoint ,
11361146 json .dumps (payload ),
1137- self .json_headers (),
1147+ self .get_json_headers (),
11381148 self .proxies ,
11391149 )
11401150
@@ -1263,7 +1273,7 @@ def dial(self, session_id, token, sip_uri, options=[]):
12631273 "POST to %r with params %r, headers %r, proxies %r" ,
12641274 endpoint ,
12651275 json .dumps (payload ),
1266- self .json_headers (),
1276+ self .get_json_headers (),
12671277 self .proxies ,
12681278 )
12691279
@@ -1317,7 +1327,7 @@ class names (Strings) to apply to the stream. For example:
13171327 "PUT to %r with params %r, headers %r, proxies %r" ,
13181328 endpoint ,
13191329 json .dumps (items_payload ),
1320- self .json_headers (),
1330+ self .get_json_headers (),
13211331 self .proxies ,
13221332 )
13231333
@@ -1354,6 +1364,10 @@ def start_broadcast(
13541364
13551365 :param String session_id: The session ID of the OpenTok session you want to broadcast
13561366
1367+ :param Boolean optional hasAudio: Whether the stream is broadcast with audio.
1368+
1369+ :param Boolean optional hasVideo: Whether the stream is broadcast with video.
1370+
13571371 :param Dictionary options, with the following properties:
13581372
13591373 Dictionary 'layout' optional: Specify this to assign the initial layout type for the
@@ -1414,18 +1428,18 @@ def start_broadcast(
14141428 BroadcastStreamModes.manual to explicitly select streams to include in the the broadcast, using the
14151429 OpenTok.add_broadcast_stream() and OpenTok.remove_broadcast_stream() methods.
14161430
1417- :rtype A Broadcast object, which contains information of the broadcast: id, sessionId
1431+ :rtype A Broadcast object, which contains information of the broadcast: id, sessionId,
14181432 projectId, createdAt, updatedAt, resolution, status and broadcastUrls
14191433 """
14201434
1421- if ' hls' in options [' outputs' ]:
1435+ if " hls" in options [" outputs" ]:
14221436 if (
1423- ' lowLatency' in options [' outputs' ][ ' hls' ]
1424- and ' dvr' in options [' outputs' ][ ' hls' ]
1437+ " lowLatency" in options [" outputs" ][ " hls" ]
1438+ and " dvr" in options [" outputs" ][ " hls" ]
14251439 ):
14261440 if (
1427- options [' outputs' ][ ' hls' ][ ' lowLatency' ] == True
1428- and options [' outputs' ][ ' hls' ][ ' dvr' ] == True
1441+ options [" outputs" ][ " hls" ][ " lowLatency" ] == True
1442+ and options [" outputs" ][ " hls" ][ " dvr" ] == True
14291443 ):
14301444 raise BroadcastHLSOptionsError (
14311445 'HLS options "lowLatency" and "dvr" cannot both be set to "True".'
@@ -1441,7 +1455,7 @@ def start_broadcast(
14411455 "POST to %r with params %r, headers %r, proxies %r" ,
14421456 endpoint ,
14431457 json .dumps (payload ),
1444- self .json_headers (),
1458+ self .get_json_headers (),
14451459 self .proxies ,
14461460 )
14471461
@@ -1484,7 +1498,7 @@ def stop_broadcast(self, broadcast_id):
14841498 logger .debug (
14851499 "POST to %r with headers %r, proxies %r" ,
14861500 endpoint ,
1487- self .json_headers (),
1501+ self .get_json_headers (),
14881502 self .proxies ,
14891503 )
14901504
@@ -1621,7 +1635,7 @@ def get_broadcast(self, broadcast_id):
16211635 logger .debug (
16221636 "GET to %r with headers %r, proxies %r" ,
16231637 endpoint ,
1624- self .json_headers (),
1638+ self .get_json_headers (),
16251639 self .proxies ,
16261640 )
16271641
@@ -1680,7 +1694,7 @@ def set_broadcast_layout(
16801694 "PUT to %r with params %r, headers %r, proxies %r" ,
16811695 endpoint ,
16821696 json .dumps (payload ),
1683- self .json_headers (),
1697+ self .get_json_headers (),
16841698 self .proxies ,
16851699 )
16861700
@@ -1929,10 +1943,10 @@ def connect_audio_to_websocket(
19291943 def validate_websocket_options (self , options ):
19301944 if type (options ) is not dict :
19311945 raise InvalidWebSocketOptionsError (
1932- ' Must pass WebSocket options as a dictionary.'
1946+ " Must pass WebSocket options as a dictionary."
19331947 )
1934- if ' uri' not in options :
1935- raise InvalidWebSocketOptionsError (' Provide a WebSocket URI.' )
1948+ if " uri" not in options :
1949+ raise InvalidWebSocketOptionsError (" Provide a WebSocket URI." )
19361950
19371951 def _sign_string (self , string , secret ):
19381952 return hmac .new (
@@ -1974,9 +1988,9 @@ def mute_all(
19741988
19751989 try :
19761990 if excludedStreamIds :
1977- options = {' active' : True , ' excludedStreams' : excludedStreamIds }
1991+ options = {" active" : True , " excludedStreams" : excludedStreamIds }
19781992 else :
1979- options = {' active' : True , ' excludedStreams' : []}
1993+ options = {" active" : True , " excludedStreams" : []}
19801994
19811995 response = requests .post (
19821996 url , headers = self .get_headers (), data = json .dumps (options )
@@ -2012,7 +2026,7 @@ def disable_force_mute(self, session_id: str) -> requests.Response:
20122026 :param session_id The session ID.
20132027 """
20142028
2015- options = {' active' : False }
2029+ options = {" active" : False }
20162030 url = self .endpoints .get_mute_all_url (session_id )
20172031
20182032 response = requests .post (
@@ -2162,9 +2176,9 @@ def mute_all(
21622176
21632177 try :
21642178 if excludedStreamIds :
2165- options = {' active' : True , ' excludedStreams' : excludedStreamIds }
2179+ options = {" active" : True , " excludedStreams" : excludedStreamIds }
21662180 else :
2167- options = {' active' : True , ' excludedStreams' : []}
2181+ options = {" active" : True , " excludedStreams" : []}
21682182
21692183 response = requests .post (
21702184 url , headers = self .get_headers (), data = json .dumps (options )
@@ -2198,7 +2212,7 @@ def disable_force_mute(self, session_id: str) -> requests.Response:
21982212 :param session_id The session ID.
21992213 """
22002214
2201- options = {' active' : False }
2215+ options = {" active" : False }
22022216 url = self .endpoints .get_mute_all_url (session_id )
22032217
22042218 response = requests .post (
0 commit comments