1919from enum import Enum
2020
2121from .version import __version__
22+ from .endpoints import Endpoints
2223from .session import Session
2324from .archives import Archive , ArchiveList , OutputModes
24- from .exceptions import OpenTokException , RequestError , AuthError , NotFoundError , ArchiveError , SignalingError
25+ from .stream import Stream
26+ from .exceptions import (
27+ OpenTokException ,
28+ RequestError ,
29+ AuthError ,
30+ NotFoundError ,
31+ ArchiveError ,
32+ SignalingError ,
33+ GetStreamError
34+ )
2535
2636class Roles (Enum ):
2737 """List of valid roles for a token."""
@@ -62,9 +72,9 @@ class OpenTok(object):
6272 def __init__ (self , api_key , api_secret , api_url = 'https://api.opentok.com' , timeout = None ):
6373 self .api_key = str (api_key )
6474 self .api_secret = api_secret
65- self .api_url = api_url
6675 self .timeout = timeout
6776 self ._proxies = None
77+ self .endpoints = Endpoints (api_url , self .api_key )
6878
6979 @property
7080 def proxies (self ):
@@ -264,7 +274,7 @@ def create_session(self, location=None, media_mode=MediaModes.relayed, archive_m
264274 options [u ('location' )] = location
265275
266276 try :
267- response = requests .post (self .session_url (), data = options , headers = self .headers (), proxies = self .proxies , timeout = self .timeout )
277+ response = requests .post (self .endpoints . session_url (), data = options , headers = self .headers (), proxies = self .proxies , timeout = self .timeout )
268278 response .encoding = 'utf-8'
269279
270280 if response .status_code == 403 :
@@ -299,29 +309,6 @@ def json_headers(self):
299309 result ['Content-Type' ] = 'application/json'
300310 return result
301311
302- def session_url (self ):
303- """For internal use."""
304- url = self .api_url + '/session/create'
305- return url
306-
307- def archive_url (self , archive_id = None ):
308- """For internal use."""
309- url = self .api_url + '/v2/project/' + self .api_key + '/archive'
310- if archive_id :
311- url = url + '/' + archive_id
312- return url
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-
325312 def start_archive (self , session_id , has_audio = True , has_video = True , name = None , output_mode = OutputModes .composed , resolution = None ):
326313 """
327314 Starts archiving an OpenTok session.
@@ -372,7 +359,7 @@ def start_archive(self, session_id, has_audio=True, has_video=True, name=None, o
372359 'resolution' : resolution ,
373360 }
374361
375- response = requests .post (self .archive_url (), data = json .dumps (payload ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
362+ response = requests .post (self .endpoints . archive_url (), data = json .dumps (payload ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
376363
377364 if response .status_code < 300 :
378365 return Archive (self , response .json ())
@@ -405,7 +392,7 @@ def stop_archive(self, archive_id):
405392
406393 :rtype: The Archive object corresponding to the archive being stopped.
407394 """
408- response = requests .post (self .archive_url (archive_id ) + '/stop' , headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
395+ response = requests .post (self .endpoints . archive_url (archive_id ) + '/stop' , headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
409396
410397 if response .status_code < 300 :
411398 return Archive (self , response .json ())
@@ -428,7 +415,7 @@ def delete_archive(self, archive_id):
428415
429416 :param String archive_id: The archive ID of the archive to be deleted.
430417 """
431- response = requests .delete (self .archive_url (archive_id ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
418+ response = requests .delete (self .endpoints . archive_url (archive_id ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
432419
433420 if response .status_code < 300 :
434421 pass
@@ -446,7 +433,7 @@ def get_archive(self, archive_id):
446433
447434 :rtype: The Archive object.
448435 """
449- response = requests .get (self .archive_url (archive_id ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
436+ response = requests .get (self .endpoints . archive_url (archive_id ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
450437
451438 if response .status_code < 300 :
452439 return Archive (self , response .json ())
@@ -475,7 +462,7 @@ def get_archives(self, offset=None, count=None):
475462 if count is not None :
476463 params ['count' ] = count
477464
478- response = requests .get (self .archive_url () + "?" + urlencode (params ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
465+ response = requests .get (self .endpoints . archive_url () + "?" + urlencode (params ), headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout )
479466
480467 if response .status_code < 300 :
481468 return ArchiveList (self , response .json ())
@@ -502,7 +489,7 @@ def signal(self, session_id, payload, connection_id=None):
502489 connected to the session
503490 """
504491 response = requests .post (
505- self .signaling_url (session_id , connection_id ),
492+ self .endpoints . signaling_url (session_id , connection_id ),
506493 data = json .dumps (payload ),
507494 headers = self .json_headers (),
508495 proxies = self .proxies ,
@@ -522,6 +509,31 @@ def signal(self, session_id, payload, connection_id=None):
522509 else :
523510 raise RequestError ("An unexpected error occurred" , response .status_code )
524511
512+ def get_stream (self , session_id , stream_id ):
513+ """
514+ Returns an Stream object that contains information of an OpenTok stream:
515+
516+ -id: The stream ID
517+ -videoType: "camera" or "screen"
518+ -name: The stream name (if one was set when the client published the stream)
519+ -layoutClassList: It's an array of the layout classes for the stream
520+ """
521+ endpoint = self .endpoints .get_stream_url (session_id , stream_id )
522+ response = requests .get (
523+ endpoint , headers = self .json_headers (), proxies = self .proxies , timeout = self .timeout
524+ )
525+
526+ if response .status_code == 200 :
527+ return Stream (response .json ())
528+ elif response .status_code == 400 :
529+ raise GetStreamError ('Invalid request. This response may indicate that data in your request data is invalid JSON. Or it may indicate that you do not pass in a session ID or you passed in an invalid stream ID.' )
530+ elif response .status_code == 403 :
531+ raise AuthError ('You passed in an invalid OpenTok API key or JWT token.' )
532+ elif response .status_code == 408 :
533+ raise GetStreamError ('You passed in an invalid stream ID.' )
534+ else :
535+ raise RequestError ('An unexpected error occurred' , response .status_code )
536+
525537 def _sign_string (self , string , secret ):
526538 return hmac .new (secret .encode ('utf-8' ), string .encode ('utf-8' ), hashlib .sha1 ).hexdigest ()
527539
0 commit comments