Package: opentok
The OpenTok Python SDK lets you generatesessionsandtokensforOpenTokapplications, andarchiveOpenTok sessions.Installation using Pip (recommended):Pip helps manage dependencies for Python projects using the PyPI index. Find more info here:http://www.pip-installer.org/en/latest/Add theopentokpackage as a dependency in your project. The most common way is to add it to yourrequirements.txtfile:opentok>=3.0Next, install the dependencies:$ pip install -r requirements.txtUsageInitializingImport the package at the top of any file where you will use it. At the very least you will need theClientclass. Then initialize a Client instance with your own API Key and API Secret.fromopentokimportClientopentok=Client(api_key,api_secret)Creating SessionsTo create an OpenTok Session, use theopentok.create_session()method. There are optional
keyword parameters for this method:locationwhich can be set to a string containing an IP address.media_modewhich is a String (defined by the MediaModes class).
This determines whether the session will use theOpenTok Media Routeror attempt to send streams directly between clients. A routed session is required for some
OpenTok features (such as archiving).archive_modewhich specifies whether the session will be automatically archived (always)
or not (manual).archive_namewhich indicates the archive name for all the archives in auto archived session.
A session that begins with archive mode ‘always’ will be using this archive name for all archives of that session.
Passing ‘archive_name’ with archive mode ‘manual’ will cause an error response.archive_resolutionwhich indicates the archive resolution for all the archives in auto archived session.
Valid values are ‘640x480’, ‘480x640’, ‘1280x720’, ‘720x1280’, ‘1920x1080’ and ‘1080x1920’.
A session that begins with archive mode ‘always’ will be using this resolution for all archives of that session.
Passing ‘archive_resolution’ with archive mode ‘manual’ will cause an error response.e2eewhich is a boolean. This specifies whether to enableend-to-end encryptionfor the OpenTok session.This method returns aSessionobject. Itssession_idattribute is useful when saving to a persistent
store (such as a database).# Create a session that attempts to send streams directly between clients (falling back# to use the OpenTok TURN server to relay streams if the clients cannot connect):session=opentok.create_session()fromopentokimportMediaModes# A session that uses the OpenTok Media Router, which is required for archiving:session=opentok.create_session(media_mode=MediaModes.routed)# An automatically archived session:session=opentok.create_session(media_mode=MediaModes.routed,archive_mode=ArchiveModes.always)# An automatically archived session with the archive name and resolution specified:session=opentok.create_session(media_mode=MediaModes.routed,archive_mode=ArchiveModes.always,archive_name='my_archive',archive_resolution='1920x1080')# A session with a location hintsession=opentok.create_session(location=u'12.34.56.78')# Store this session ID in the databasesession_id=session.session_idGenerating TokensOnce a Session is created, you can start generating Tokens for clients to use when connecting to it.
You can generate a token either by calling theopentok.generate_token(session_id)method or by
calling thesession.generate_token()method on aSessioninstance after creating it. Both
have a set of optional keyword parameters:role,expire_time,data, andinitial_layout_class_list.# Generate a Token from just a session_id (fetched from a database)token=opentok.generate_token(session_id)# Generate a Token by calling the method on the Session (returned from create_session)token=session.generate_token()fromopentokimportRoles# Set some options in a tokentoken=session.generate_token(role=Roles.moderator,expire_time=int(time.time())+10,data=u'name=Johnny'initial_layout_class_list=[u'focus'])Working with ArchivesYou can only archive sessions that use the OpenTok Media
Router (sessions with the media mode set to routed).You can start the recording of an OpenTok Session using theopentok.start_archive(session_id)method. This method takes an optional keyword argumentnameto assign a name to the archive.
This method will return anArchiveinstance. Note that you can only start an Archive on
a Session that has clients connected.archive=opentok.start_archive(session_id,name=u'Important Presentation')# Store this archive_id in the databasearchive_id=archive.idYou can also disable audio or video recording by setting thehas_audioorhas_videoproperty of
theoptionsparameter tofalse:archive=opentok.start_archive(session_id,name=u'Important Presentation',has_video=False)# Store this archive_id in the databasearchive_id=archive.idBy default, all streams are recorded to a single (composed) file. You can record the different
streams in the session to individual files (instead of a single composed file) by setting theoutput_modeparameter of theopentok.start_archive()methodOutputModes.individual.archive=opentok.start_archive(session_id,name=u'Important Presentation',output_mode=OutputModes.individual)# Store this archive_id in the databasearchive_id=archive.idTo add an individual stream to an archive, use theopentok.add_archive_stream(archive_id, stream_id, has_audio, has_video)method:opentok.add_archive_stream(archive.id,stream_id,has_audio=True,has_video=True)To remove a stream from an archive, use theopentok.remove_archive_stream()method:opentok.remove_archive_stream(archive.id,stream_id)Composed archives (output_mode=OutputModes.composed) have an optionalresolutionparameter.
If no value is supplied, the archive will use the default resolution, “640x480”.
You can set this to another resolution by setting theresolutionparameter of theopentok.start_archive()method.You can specify the following archive resolutions:“640x480” (SD landscape, default resolution)“480x640” (SD portrait)“1280x720” (HD landscape)“720x1280” (HD portrait)“1920x1080” (FHD landscape)“1080x1920” (FHD portrait)Setting theresolutionparameter while setting theoutput_modeparameter toOutputModes.individualresults in an error.archive=opentok.start_archive(session_id,name=u'Important Presentation',resolution="1280x720")# Store this archive_id in the databasearchive_id=archive.idYou can enable multiple simultaneous archives by specifying a unique value for themulti_archive_tagparameter in thestart_archivemethod.archive=opentok.start_archive(session_id,name=u'Important Presentation',multi_archive_tag='MyArchiveTag')You can stop the recording of a started Archive using theopentok.stop_archive(archive_id)``method.You can also do this using the ``archive.stop()method of anArchiveinstance.# Stop an Archive from an archive_id (fetched from database)opentok.stop_archive(archive_id)# Stop an Archive from an instance (returned from opentok.start_archive)archive.stop()To get anArchiveinstance (and all the information about it) from an archive ID, use theopentok.get_archive(archive_id)method.archive=opentok.get_archive(archive_id)To delete an Archive, you can call theopentok.delete_archive(archive_id)method or thearchive.delete()method of anArchiveinstance.# Delete an Archive from an archive ID (fetched from database)opentok.delete_archive(archive_id)# Delete an Archive from an Archive instance (returned from opentok.start_archive oropentok.get_archive)archive.delete()You can also get a list of all the Archives you’ve created (up to 1000) with your API Key. This is
done using theopentok.list_archives()method. There are three optional keyword parameters:count,offsetandsession_id; they can help you paginate through the results and
filter by session ID. This method returns an instance of theArchiveListclass.archive_list=opentok.list_archives()# Get a specific Archive from the listarchive=archive_list.items[i]# Iterate over itemsforarchiveiniter(archive_list):pass# Get the total number of Archives for this API Keytotal=archive_list.totalNote that you can also create an automatically archived session, by passing inArchiveModes.alwaysas thearchive_modeparameter when you call theopentok.create_session()method (see “Creating Sessions,” above).For composed archives, you can change the layout dynamically, using theopentok.set_archive_layout(archive_id, type, stylesheet)method:opentok.set_archive_layout('ARCHIVEID','horizontalPresentation')Setting the layout of composed archives is optional. By default, composed archives use thebest fitlayout.  Other valid values are:custom,horizontalPresentation,pipandverticalPresentation. If you specify acustomlayout type, set the stylesheet parameter:opentok.set_archive_layout('ARCHIVEID','custom','stream.instructor {position: absolute; width: 100%;  height:50%;}')For other layout types, do not set the stylesheet property. For more information seeCustomizing the video layout for composed archives.For more information on archiving, see theOpenTok archivingprogramming guide.Sending SignalsOnce a Session is created, you can send signals to everyone in the session or to a specific connection. You can send a signal by calling thesignal(session_id, payload)method of theClientclass. Thepayloadparameter is a dictionary used to set thetype,datafields. Ỳou can also call the method with the parameterconnection_idto send a signal to a specific connectionsignal(session_id, data, connection_id).# payload structurepayload={'type':'type',#optional'data':'signal data'#required}connection_id='2a84cd30-3a33-917f-9150-49e454e01572'# To send a signal to everyone in the session:opentok.signal(session_id,payload)# To send a signal to a specific connection in the session:opentok.signal(session_id,payload,connection_id)Working with StreamsYou can get information about a stream by calling theget_stream(session_id, stream_id)method of theClientclass.The method returns a Stream object that contains information of an OpenTok stream:id: The stream IDvideoType: “camera” or “screen”name: The stream name (if one was set when the client published the stream)layoutClassList: It’s an array of the layout classes for the streamsession_id='SESSIONID'stream_id='8b732909-0a06-46a2-8ea8-074e64d43422'# To get stream info:stream=opentok.get_stream(session_id,stream_id)# Stream properties:printstream.id#8b732909-0a06-46a2-8ea8-074e64d43422printstream.videoType#cameraprintstream.name#stream nameprintstream.layoutClassList#['full']Also, you can get information about all the streams in a session by calling thelist_streams(session_id)method of theClientclass.The method returns a StreamList object that contains a list of all the streams# To get all streams in a session:stream_list=opentok.list_streams(session_id)# Getting the first stream of the liststream=stream_list.items[0]# Stream properties:printstream.id#8b732909-0a06-46a2-8ea8-074e64d43422printstream.videoType#cameraprintstream.name#stream nameprintstream.layoutClassList#['full']You can change the layout classes for streams in a session by calling theset_stream_class_lists(session_id, stream_list)method of theClientclass.The layout classes define how the stream is displayed in the layout of a composed OpenTok archive.# This list contains the information of the streams that will be updated. Each element# in the list is a dictionary with two properties: 'id' and 'layoutClassList'. The 'id'# property is the stream ID (a String), and the 'layoutClassList' is an array of class# names (Strings) to apply to the stream.payload=[{'id':'7b09ec3c-26f9-43d7-8197-f608f13d4fb6','layoutClassList':['focus']},{'id':'567bc941-6ea0-4c69-97fc-70a740b68976','layoutClassList':['top']},{'id':'307dc941-0450-4c09-975c-705740d08970','layoutClassList':['bottom']}]opentok.set_stream_class_lists('SESSIONID',payload)For more information seeChanging the composed archive layout classes for an OpenTok stream.Force DisconnectYour application server can disconnect a client from an OpenTok session by calling the force_disconnect(session_id, connection_id) method of the Client class, or the force_disconnect(connection_id) method of the Session class.session_id='SESSIONID'connection_id='CONNECTIONID'# To send a request to disconnect a client:opentok.force_disconnect(session_id,connection_id)Working with SIP InterconnectYou can connect your SIP platform to an OpenTok session, the audio from your end of the SIP call is added to the OpenTok session as an audio-only stream.
The OpenTok Media Router mixes audio from other streams in the session and sends the mixed audio to your SIP endpoint.session_id=u('SESSIONID')token=u('TOKEN')sip_uri=u('sip:user@sip.partner.com;transport=tls')# call the method with the required parameterssip_call=opentok.dial(session_id,token,sip_uri)# the method also supports aditional options to establish the sip calloptions={'from':'from@example.com','headers':{'headerKey':'headerValue'},'auth':{'username':'username','password':'password'},'secure':True,'video':True,'observeForceMute':True,'streams':['stream-id-1','stream-id-2']}# call the method with aditional optionssip_call=opentok.dial(session_id,token,sip_uri,options)For more information, including technical details and security considerations, see theOpenTok SIP interconnectdeveloper guide.Working with BroadcastsOpenTok broadcast lets you share live OpenTok sessions with many viewers.You can use theopentok.start_broadcast()method to start a live stream for an OpenTok session.
This broadcasts the session to HLS (HTTP live streaming) or to RTMP streams.To successfully start broadcasting a session, at least one client must be connected to the session.The live streaming broadcast can target one HLS endpoint and up to five RTMP servers simulteneously for a session. You can only start live streaming for sessions that use the OpenTok Media Router; you cannot use live streaming with sessions that have the media mode set to relayed.session_id='SESSIONID'options={'layout':{'type':'custom','stylesheet':'the layout stylesheet (only used with type == custom)'},'maxDuration':5400,'hasAudio':True,'hasVideo':True,'maxBitrate':2000000,'outputs':{'hls':{},'rtmp':[{'id':'foo','serverUrl':'rtmp://myfooserver/myfooapp','streamName':'myfoostream'},{'id':'bar','serverUrl':'rtmp://mybarserver/mybarapp','streamName':'mybarstream'}]},'resolution':'640x480'}broadcast=opentok.start_broadcast(session_id,options)You can specify the following broadcast resolutions:“640x480” (SD landscape, default resolution)“480x640” (SD portrait)“1280x720” (HD landscape)“720x1280” (HD portrait)“1920x1080” (FHD landscape)“1080x1920” (FHD portrait)You can specify a maximum bitrate between 100000 and 6000000.session_id='SESSIONID'options={'multiBroadcastTag':'unique_broadcast_tag''layout':{'type':'custom','stylesheet':'the layout stylesheet (only used with type == custom)'},'maxDuration':5400,'maxBitrate':2000000,'outputs':{'hls':{},'rtmp':[{'id':'foo','serverUrl':'rtmp://myfooserver/myfooapp','streamName':'myfoostream'},{'id':'bar','serverUrl':'rtmp://mybarserver/mybarapp','streamName':'mybarstream'}]},'resolution':'640x480'}broadcast=opentok.start_broadcast(session_id,options)To enable multiple simultaneous broadcasts on the same session, specify a unique value for themultiBroadcastTagparameter inoptionswhen calling theopentok.start_broadcastmethod.You can broadcast only audio, or only video, for a stream by settinghasAudioorhasVideotoFalseas required. These fields areTrueby default.session_id='SESSIONID'options={'layout':{'type':'custom','stylesheet':'the layout stylesheet (only used with type == custom)'},'maxDuration':5400,'hasAudio':True,'hasVideo':False,'maxBitrate':2000000,'outputs':{'hls':{},'rtmp':[{'id':'foo','serverUrl':'rtmp://myfooserver/myfooapp','streamName':'myfoostream'},{'id':'bar','serverUrl':'rtmp://mybarserver/mybarapp','streamName':'mybarstream'}]},'resolution':'640x480'}broadcast=opentok.start_broadcast(session_id,options)You can stop a started Broadcast using theopentok.stop_broadcast(broadcast_id)method.# getting the ID from a broadcast objectbroadcast_id=broadcast.id# stop a broadcastbroadcast=opentok.stop_broadcast(broadcast_id)You can get details on a broadcast that is in-progress using the methodopentok.get_broadcast(broadcast_id).broadcast_id='1748b7070a81464c9759c46ad10d3734'# get broadcast detailsbroadcast=opentok.get_broadcast(broadcast_id)printbroadcast.json()# print result# {#   "createdAt": 1437676551000,#   "id": "1748b707-0a81-464c-9759-c46ad10d3734",#   "projectId": 100,#   "resolution": "640x480",#   "sessionId": "2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4",#   "status": "started",#   "updatedAt": 1437676551000,#   "broadcastUrls": {#       "hls": "http://server/fakepath/playlist.m3u8",#       "rtmp": {#           "bar": {#               "serverUrl": "rtmp://mybarserver/mybarapp",#               "status": "live",#               "streamName": "mybarstream"#           },#           "foo": {#               "serverUrl": "rtmp://myfooserver/myfooapp",#               "status": "live",#               "streamName": "myfoostream"#           }#       }#   }# }You can dynamically change the layout type of a live streaming broadcast.# Valid values to 'layout_type' are: 'custom', 'horizontalPresentation',# 'pip' and 'verticalPresentation'opentok.set_broadcast_layout('BROADCASTID','horizontalPresentation')# if you specify a 'custom' layout type, set the stylesheet parameter:opentok.set_broadcast_layout('BROADCASTID','custom','stream.instructor {position: absolute; width: 100%;  height:50%;}')You can add streams to a broadcast using theopentok.add_broadcast_stream()method:opentok.add_broadcast_stream(broadcast_id,stream_id)Conversely, streams can be removed from a broadcast with theopentok.remove_broadcast_stream()method.opentok.remove_broadcast_stream(broadcast_id,stream_id)For more information about OpenTok live streaming broadcasts, see theBroadcast developer guide.Connecting audio to a WebSocketYou can send audio to a WebSocket with theopentok.connect_audio_to_websocketmethod.
For more information, see theAudio Connector developer guide.websocket_options={"uri":"wss://service.com/ws-endpoint"}websocket_audio_connection=opentok.connect_audio_to_websocket(session_id,opentok_token,websocket_options)Additionally, you can list only the specific streams you want to send to the WebSocket, and/or the additional headers that are sent,
by adding these fields to thewebsocket_optionsobject.websocket_options={"uri":"wss://service.com/ws-endpoint","streams":["streamId-1","streamId-2"],"headers":{"headerKey":"headerValue"}}Using the Live Captions APIYou can enable live captioning for an OpenTok session with theopentok.start_captionsmethod.
For more information, see theLive Captions API developer guide <https://tokbox.com/developer/guides/live-captions/>.captions=opentok.start_captions(session_id,opentok_token)You can also specify optional parameters, as shown below.captions=opentok.start_captions(session_id,opentok_token,language_code='en-GB',max_duration=10000,partial_captions=False,status_callback_url='https://example.com',)You can stop an ongoing live captioning session by calling theopentok.stop_captionsmethod.opentok.stop_captions(captions_id)Configuring TimeoutTimeout is passed in the Client constructor:self.timeout = timeoutIn order to configure timeout, first create an instance:opentok =Client(....,timeout=value)And then proceed to change the value withopentok.timeout = valueMuting streamsYou can mute all streams in a session using theopentok.mute_all()method:opentok.mute_all(session_id)# You can also specify streams to exclude (e.g. main presenter)excluded_stream_ids=['1234','5678']opentok.mute_all(session_id,excluded_stream_ids)In addition to existing streams, any streams that are published after the call to
this method are published with audio muted. You can remove the mute state of a session
by calling theopentok.disableForceMute()method:opentok.disable_force_mute(session_id)After calling theopentok.disableForceMute()method, new streams that are published
to the session will not be muted.You can mute a single stream using theopentok.mute_stream()method:opentok.mute_stream(session_id,stream_id)DTMFYou can send dual-tone multi-frequency (DTMF) digits to SIP endpoints. You can play DTMF tones
to all clients connected to session or to a specific connection:digits='12345'opentok.play_dtmf(session_id,digits)# To a specific connectionopentok.play_dtmf(session_id,connection_id,digits)Appending to the User AgentYou can append a string to the user agent that is sent with requests:opentok.append_to_user_agent('my-appended-string')SamplesThere are two sample applications included in this repository. To get going as fast as possible, clone the whole
repository and follow the Walkthroughs:HelloWorldArchivingDocumentationReference documentation is available athttps://tokbox.com/developer/sdks/python/reference/.RequirementsYou need an OpenTok API key and API secret, which you can obtain athttps://dashboard.tokbox.com/The OpenTok Python SDK requires Python 3.5 or higherRelease NotesSee theReleasespage for details about
each release.Important changes since v2.2Changes in v2.2.1:The default setting for the create_session() method is to create a session with the media mode set
to relayed. In previous versions of the SDK, the default setting was to use the OpenTok Media Router
(media mode set to routed). In a relayed session, clients will attempt to send streams directly
between each other (peer-to-peer); if clients cannot connect due to firewall restrictions, the
session uses the OpenTok TURN server to relay audio-video streams.Changes in v2.2.0:This version of the SDK includes support for working with OpenTok archives.The Client.create_session() method now includes a media_mode parameter, instead of a p2p parameter.Changes in v3.X.X:This version of the SDK includes significant improvements such as top level entity naming, where the Opentok class is nowClient.  We also implemented a standardised logging module, improved naming conventions and JWT generation to make developer experience more rewarding.For details, see the reference documentation athttps://tokbox.com/developer/sdks/python/reference/.Development and ContributingInterested in contributing? We :heart: pull requests! See theDevelopmentandContributionguidelines.Getting HelpWe love to hear from you so if you have questions, comments or find a bug in the project, let us know! You can either:Open an issue on this repositorySeehttps://support.tokbox.com/for support optionsTweet at us! We’re@VonageDev on TwitterOrjoin the Vonage Developer Community Slack