21
21
from .version import __version__
22
22
from .session import Session
23
23
from .archives import Archive , ArchiveList , OutputModes
24
- from .exceptions import OpenTokException , RequestError , AuthError , NotFoundError , ArchiveError
24
+ from .exceptions import OpenTokException , RequestError , AuthError , NotFoundError , ArchiveError , SignalingError
25
25
26
26
class Roles (Enum ):
27
27
"""List of valid roles for a token."""
@@ -293,7 +293,7 @@ def headers(self):
293
293
'X-OPENTOK-AUTH' : self ._create_jwt_auth_header ()
294
294
}
295
295
296
- def archive_headers (self ):
296
+ def json_headers (self ):
297
297
"""For internal use."""
298
298
result = self .headers ()
299
299
result ['Content-Type' ] = 'application/json'
@@ -311,6 +311,17 @@ def archive_url(self, archive_id=None):
311
311
url = url + '/' + archive_id
312
312
return url
313
313
314
+ def signaling_url (self , session_id , connection_id = None ):
315
+ """For internal use."""
316
+ url = self .api_url + '/v2/project/' + self .api_key + '/session/' + session_id
317
+
318
+ if connection_id :
319
+ url += '/connection/' + connection_id
320
+
321
+ url += '/signal'
322
+
323
+ return url
324
+
314
325
def start_archive (self , session_id , has_audio = True , has_video = True , name = None , output_mode = OutputModes .composed , resolution = None ):
315
326
"""
316
327
Starts archiving an OpenTok session.
@@ -361,7 +372,7 @@ def start_archive(self, session_id, has_audio=True, has_video=True, name=None, o
361
372
'resolution' : resolution ,
362
373
}
363
374
364
- response = requests .post (self .archive_url (), data = json .dumps (payload ), headers = self .archive_headers (), proxies = self .proxies , timeout = self .timeout )
375
+ response = requests .post (self .archive_url (), data = json .dumps (payload ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
365
376
366
377
if response .status_code < 300 :
367
378
return Archive (self , response .json ())
@@ -394,7 +405,7 @@ def stop_archive(self, archive_id):
394
405
395
406
:rtype: The Archive object corresponding to the archive being stopped.
396
407
"""
397
- response = requests .post (self .archive_url (archive_id ) + '/stop' , headers = self .archive_headers (), proxies = self .proxies , timeout = self .timeout )
408
+ response = requests .post (self .archive_url (archive_id ) + '/stop' , headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
398
409
399
410
if response .status_code < 300 :
400
411
return Archive (self , response .json ())
@@ -417,7 +428,7 @@ def delete_archive(self, archive_id):
417
428
418
429
:param String archive_id: The archive ID of the archive to be deleted.
419
430
"""
420
- response = requests .delete (self .archive_url (archive_id ), headers = self .archive_headers (), proxies = self .proxies , timeout = self .timeout )
431
+ response = requests .delete (self .archive_url (archive_id ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
421
432
422
433
if response .status_code < 300 :
423
434
pass
@@ -435,7 +446,7 @@ def get_archive(self, archive_id):
435
446
436
447
:rtype: The Archive object.
437
448
"""
438
- response = requests .get (self .archive_url (archive_id ), headers = self .archive_headers (), proxies = self .proxies , timeout = self .timeout )
449
+ response = requests .get (self .archive_url (archive_id ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
439
450
440
451
if response .status_code < 300 :
441
452
return Archive (self , response .json ())
@@ -464,7 +475,7 @@ def get_archives(self, offset=None, count=None):
464
475
if count is not None :
465
476
params ['count' ] = count
466
477
467
- response = requests .get (self .archive_url () + "?" + urlencode (params ), headers = self .archive_headers (), proxies = self .proxies , timeout = self .timeout )
478
+ response = requests .get (self .archive_url () + "?" + urlencode (params ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
468
479
469
480
if response .status_code < 300 :
470
481
return ArchiveList (self , response .json ())
@@ -475,6 +486,42 @@ def get_archives(self, offset=None, count=None):
475
486
else :
476
487
raise RequestError ("An unexpected error occurred" , response .status_code )
477
488
489
+ def signal (self , session_id , payload , connection_id = None ):
490
+ """
491
+ Send signals to all participants in an active OpenTok session or to a specific client
492
+ connected to that session.
493
+
494
+ :param String session_id: The session ID of the OpenTok session that receives the signal
495
+
496
+ :param Dictionary payload: Structure that contains both the type and data fields. These
497
+ correspond to the type and data parameters passed in the client signal received handlers
498
+
499
+ :param String connection_id: The connection_id parameter is an optional string used to
500
+ specify the connection ID of a client connected to the session. If you specify this value,
501
+ the signal is sent to the specified client. Otherwise, the signal is sent to all clients
502
+ connected to the session
503
+ """
504
+ response = requests .post (
505
+ self .signaling_url (session_id , connection_id ),
506
+ data = json .dumps (payload ),
507
+ headers = self .json_headers (),
508
+ proxies = self .proxies ,
509
+ timeout = self .timeout
510
+ )
511
+
512
+ if response .status_code == 204 :
513
+ pass
514
+ elif response .status_code == 400 :
515
+ raise SignalingError ('One of the signal properties - data, type, sessionId or connectionId - is invalid.' )
516
+ elif response .status_code == 403 :
517
+ raise AuthError ('You are not authorized to send the signal. Check your authentication credentials.' )
518
+ elif response .status_code == 404 :
519
+ raise SignalingError ('The client specified by the connectionId property is not connected to the session.' )
520
+ elif response .status_code == 413 :
521
+ raise SignalingError ('The type string exceeds the maximum length (128 bytes), or the data string exceeds the maximum size (8 kB).' )
522
+ else :
523
+ raise RequestError ("An unexpected error occurred" , response .status_code )
524
+
478
525
def _sign_string (self , string , secret ):
479
526
return hmac .new (secret .encode ('utf-8' ), string .encode ('utf-8' ), hashlib .sha1 ).hexdigest ()
480
527
0 commit comments