Code Monkey home page Code Monkey logo

opentok-python-sdk's Introduction

OpenTok Python SDK

Tokbox is now known as Vonage

The OpenTok Python SDK lets you generate sessions and tokens for OpenTok applications, and archive OpenTok sessions.

Note!

This library is designed to work with the Tokbox/OpenTok platform, part of the Vonage Video API. If you are looking to use the Vonage Video API and are using the Vonage Customer Dashboard, you will want to install the Vonage Server SDK for Python, which includes support for the Vonage Video API.

Not sure which exact platform you are using? Take a look at this guide.

If you are using the Tokbox platform, do not worry! The Tokbox platform is not going away, and this library will continue to be updated. While we encourage customers to check out the new Unified platform, there is no rush to switch. Both platforms run the exact same infrastructure and capabilities. The main difference is a unified billing interface and easier access to Vonage's other CPaaS APIs.

If you are new to the Vonage Video API, head on over to the Vonage Customer Dashboard to sign up for a developer account and check out the Vonage Server SDK for Python.

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 the opentok package as a dependency in your project. The most common way is to add it to your requirements.txt file:

opentok>=3.0

Next, install the dependencies:

$ pip install -r requirements.txt

Usage

Initializing

Import the package at the top of any file where you will use it. At the very least you will need the Client class. Then initialize a Client instance with your own API Key and API Secret.

from opentok import Client

opentok = Client(api_key, api_secret)

Creating Sessions

To create an OpenTok Session, use the opentok.create_session() method. There are optional keyword parameters for this method:

  • location which can be set to a string containing an IP address.
  • media_mode which is a String (defined by the MediaModes class). This determines whether the session will use the OpenTok Media Router or attempt to send streams directly between clients. A routed session is required for some OpenTok features (such as archiving).
  • archive_mode which specifies whether the session will be automatically archived (always) or not (manual).
  • archive_name which 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_resolution which 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.
  • e2ee which is a boolean. This specifies whether to enable end-to-end encryption for the OpenTok session.

This method returns a Session object. Its session_id attribute 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()

from opentok import MediaModes
# 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 hint
session = opentok.create_session(location=u'12.34.56.78')

# Store this session ID in the database
session_id = session.session_id

Generating Tokens

Once 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 the opentok.generate_token(session_id) method or by calling the session.generate_token() method on a Session instance after creating it. Both have a set of optional keyword parameters: role, expire_time, data, and initial_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()

from opentok import Roles
# Set some options in a token
token = session.generate_token(role=Roles.moderator,
                               expire_time=int(time.time()) + 10,
                               data=u'name=Johnny'
                               initial_layout_class_list=[u'focus'])

Working with Archives

You 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 the opentok.start_archive(session_id) method. This method takes an optional keyword argument name to assign a name to the archive. This method will return an Archive instance. 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 database
archive_id = archive.id

You can also disable audio or video recording by setting the has_audio or has_video property of the options parameter to false:

archive = opentok.start_archive(session_id, name=u'Important Presentation', has_video=False)

# Store this archive_id in the database
archive_id = archive.id

By 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 the output_mode parameter of the opentok.start_archive() method OutputModes.individual.

archive = opentok.start_archive(session_id, name=u'Important Presentation', output_mode=OutputModes.individual)

# Store this archive_id in the database
archive_id = archive.id

To add an individual stream to an archive, use the opentok.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 the opentok.remove_archive_stream() method:

opentok.remove_archive_stream(archive.id, stream_id)

Composed archives (output_mode=OutputModes.composed) have an optional resolution parameter. If no value is supplied, the archive will use the default resolution, "640x480". You can set this to another resolution by setting the resolution parameter of the opentok.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 the resolution parameter while setting the output_mode parameter to OutputModes.individual results in an error.

archive = opentok.start_archive(session_id, name=u'Important Presentation', resolution="1280x720")

# Store this archive_id in the database
archive_id = archive.id

You can enable multiple simultaneous archives by specifying a unique value for the multi_archive_tag parameter in the start_archive method.

archive = opentok.start_archive(session_id, name=u'Important Presentation', multi_archive_tag='MyArchiveTag')

You can stop the recording of a started Archive using the opentok.stop_archive(archive_id)``method. You can also do this using the ``archive.stop() method of an Archive instance.

# 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 an Archive instance (and all the information about it) from an archive ID, use the opentok.get_archive(archive_id) method.

archive = opentok.get_archive(archive_id)

To delete an Archive, you can call the opentok.delete_archive(archive_id) method or the archive.delete() method of an Archive instance.

# 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 or
opentok.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 the opentok.list_archives() method. There are three optional keyword parameters: count, offset and session_id; they can help you paginate through the results and filter by session ID. This method returns an instance of the ArchiveList class.

archive_list = opentok.list_archives()

# Get a specific Archive from the list
archive = archive_list.items[i]

# Iterate over items
for archive in iter(archive_list):
  pass

# Get the total number of Archives for this API Key
total = archive_list.total

Note that you can also create an automatically archived session, by passing in ArchiveModes.always as the archive_mode parameter when you call the opentok.create_session() method (see "Creating Sessions," above).

For composed archives, you can change the layout dynamically, using the opentok.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 the best fit layout. Other valid values are: custom, horizontalPresentation, pip and verticalPresentation. If you specify a custom layout 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 see Customizing the video layout for composed archives.

For more information on archiving, see the OpenTok archiving programming guide.

Sending Signals

Once 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 the signal(session_id, payload) method of the Client class. The payload parameter is a dictionary used to set the type, data fields. Ỳou can also call the method with the parameter connection_id to send a signal to a specific connection signal(session_id, data, connection_id).

# payload structure
payload = {
    '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 Streams

You can get information about a stream by calling the get_stream(session_id, stream_id) method of the Client class.

The method returns a Stream object that contains information of an OpenTok stream:

  • id: The stream ID
  • videoType: "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 stream
session_id = 'SESSIONID'
stream_id = '8b732909-0a06-46a2-8ea8-074e64d43422'

# To get stream info:
stream = opentok.get_stream(session_id, stream_id)

# Stream properties:
print stream.id #8b732909-0a06-46a2-8ea8-074e64d43422
print stream.videoType #camera
print stream.name #stream name
print stream.layoutClassList #['full']

Also, you can get information about all the streams in a session by calling the list_streams(session_id) method of the Client class.

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 list
stream = stream_list.items[0]

# Stream properties:
print stream.id #8b732909-0a06-46a2-8ea8-074e64d43422
print stream.videoType #camera
print stream.name #stream name
print stream.layoutClassList #['full']

You can change the layout classes for streams in a session by calling the set_stream_class_lists(session_id, stream_list) method of the Client class.

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 see Changing the composed archive layout classes for an OpenTok stream.

Force Disconnect

Your 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 Interconnect

You 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:[email protected];transport=tls')

# call the method with the required parameters
sip_call = opentok.dial(session_id, token, sip_uri)

# the method also supports aditional options to establish the sip call
options = {
    'from': '[email protected]',
    '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 options
sip_call = opentok.dial(session_id, token, sip_uri, options)

For more information, including technical details and security considerations, see the OpenTok SIP interconnect developer guide.

Working with Broadcasts

OpenTok broadcast lets you share live OpenTok sessions with many viewers.

You can use the opentok.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 the multiBroadcastTag parameter in options when calling the opentok.start_broadcast method.

You can broadcast only audio, or only video, for a stream by setting hasAudio or hasVideo to False as required. These fields are True by 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 the opentok.stop_broadcast(broadcast_id) method.

# getting the ID from a broadcast object
broadcast_id = broadcast.id

# stop a broadcast
broadcast = opentok.stop_broadcast(broadcast_id)

You can get details on a broadcast that is in-progress using the method opentok.get_broadcast(broadcast_id).

broadcast_id = '1748b7070a81464c9759c46ad10d3734'

# get broadcast details
broadcast = opentok.get_broadcast(broadcast_id)

print broadcast.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 the opentok.add_broadcast_stream() method:

opentok.add_broadcast_stream(broadcast_id, stream_id)

Conversely, streams can be removed from a broadcast with the opentok.remove_broadcast_stream() method.

opentok.remove_broadcast_stream(broadcast_id, stream_id)

For more information about OpenTok live streaming broadcasts, see the Broadcast developer guide.

Connecting audio to a WebSocket

You can send audio to a WebSocket with the opentok.connect_audio_to_websocket method. For more information, see the Audio 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 the websocket_options object.

websocket_options = {
  "uri": "wss://service.com/ws-endpoint",
  "streams": [
    "streamId-1",
    "streamId-2"
  ],
  "headers": {
    "headerKey": "headerValue"
  }
}

Using the Live Captions API

You can enable live captioning for an OpenTok session with the opentok.start_captions method. For more information, see the Live 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 the opentok.stop_captions method.

opentok.stop_captions(captions_id)

Configuring Timeout

Timeout is passed in the Client constructor:

self.timeout = timeout

In order to configure timeout, first create an instance:

opentok = Client(...., timeout=value)

And then proceed to change the value with

opentok.timeout = value

Muting streams

You can mute all streams in a session using the opentok.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 the opentok.disableForceMute() method:

opentok.disable_force_mute(session_id)

After calling the opentok.disableForceMute() method, new streams that are published to the session will not be muted.

You can mute a single stream using the opentok.mute_stream() method:

opentok.mute_stream(session_id, stream_id)

DTMF

You 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 connection
opentok.play_dtmf(session_id, connection_id, digits)

Appending to the User Agent

You can append a string to the user agent that is sent with requests:

opentok.append_to_user_agent('my-appended-string')

Samples

There are two sample applications included in this repository. To get going as fast as possible, clone the whole repository and follow the Walkthroughs:

Documentation

Reference documentation is available at https://tokbox.com/developer/sdks/python/reference/.

Requirements

You need an OpenTok API key and API secret, which you can obtain at https://dashboard.tokbox.com/

The OpenTok Python SDK requires Python 3.5 or higher

Release Notes

See the Releases page for details about each release.

Important changes since v2.2

Changes 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 now Client. 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 at https://tokbox.com/developer/sdks/python/reference/.

Development and Contributing

Interested in contributing? We ❤️ pull requests! See the Development and Contribution guidelines.

Getting Help

We love to hear from you so if you have questions, comments or find a bug in the project, let us know! You can either:

opentok-python-sdk's People

Contributors

aiham avatar aoberoi avatar barbuza avatar dragonmantank avatar eauge avatar fernandogrd avatar geekchick avatar ggarber avatar hadrien avatar jcague avatar jeffswartz avatar juandebravo avatar kmoulder avatar maikthomas avatar maxkahan avatar michaeljolley avatar mkascel avatar msach22 avatar normanargueta avatar pardel avatar randalldegges-okta-2 avatar scitech avatar shivamthapar avatar songz avatar superchilled avatar superdiana avatar sushant-varanasi avatar tirkarthi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opentok-python-sdk's Issues

Show importing of MediaModes class in usage examples (docs)

I'm using python 3.4 and Opentok's 2.2.1 from PyPI. I am able to successfully create a normal session with just

session = opentok.create_session()

A session gets properly created and I get a session ID in the response.

The problem starts when I try to create a session that is forced to relayed. I want to connect a group of mobile devices from the start, so it makes sense to just initialize the session as relayed. When using your example docs,

session = opentok.create_session(media_mode=MediaModes.relayed)

throws a NameError exception that MediaModes isn't defined.

If I skip your docs and pass it as variables:

location = None
media_mode = "MediaModes.routed"    
session = opentok.create_session(location, media_mode)

throws an exception as well:

raise OpenTokException(u('Cannot create session, {0} is not a valid media mode').format(role))
NameError: name 'role' is not defined

Another note - your method comments mix MediaMode and MediaModes (singular/plural).

Staging / Production Param

Hey Guys,

What do you think about having an optional boolean param for the OpenTokSDK class, staging, which could be set to True to adjust the OpenTokSDK.API_URL value?

Right now, the library requires some tweaking to make it work in production--I think it should be the other way around.

Here's how it could look (I'd be happy to implement this, btw):

from OpenTokSDK import OpenTokSDK

o = OpenTokSDK(api_key='xxx', api_secret='xxx', staging=True) # staging would default to False for simplicity
session = o.create_session('ip')

I think that's a lot cleaner than the current solution, which requires users to write:

from OpenTokSDK import OpenTokSDK

o = OpenTokSDK(api_key='xxx', api_secret='xxx')
o.API_URL = 'https://api.opentok.com/hl'
session = o.create_session('ip')

Since the above isn't clear to developers unless they're actually reading through the API reference documentation on the main site.

What do ya think?

Standardize error handing

There needs to be a set of Error types defined and their meaning nailed down so that developers can predictably deal with error conditions.

This will also be subject to an internal API Review.

proxy support

this feature was requested in opentok-node and so it seems like a good idea to bring it here.

Replace dependency on httpretty

The tests have been failing since the merge of #73 due to httpretty. as @ggarber noted, python3 is not officially supported by httpretty, but should be supported by this library, so we should find a way to eliminate or replace httpretty as a dependency.

break apart test dependencies and runtime dependencies

things to consider:

Travis runs pip install -r requirements.txt. this means we may need to add a test_requirements.txt file and make it also install that

the requirements.txt right now doesn't do anything in particular, just lets setup.py pick up dependencies. i was under the impression that this is better practice for libraries unless specific versions are required.

Tox is run to do testing locally, and tox.ini defines dependencies too. Right now it only declares nose as a dependency because it needs to run the nosetests binary. It works on the assumption that the sbin build that is already pip installed into the individual virtualenv has all the other dependencies that this library needs.

clean up method signature for create_session

According to style guidelines, we should use Keyword Arguments with default values when there are a set of optional arguments for a function. The arbitrary keyword argument dictionary is not a great idea if we want to do some synchronous error checking on the options being passed in (which is a good idea for catching bugs earlier). The default value for the location is better left as None since we won't want to include it in the request at all.

Before:

def create_session(self, location='', properties={}, **kwargs)

After:

def create_session(self, location=None, p2p=False)

Implement X-OPENTOK-AUTH authentication

X-TB-PARTNER-AUTH and X-TB-TOKEN-AUTH will soon be deprecated. They will be replaced by a new authentication scheme using JWTs in the HTTP header with the name X-OPENTOK-AUTH. The specification of these tokens was completed during an internal API Review.

Python 3 support

Hello,

My employer uses OpenTok API and I've developed some code in Python 2.7 using this SDK.

We are considering move from Python 2.7 to Python 3.3 and we need this SDK ported on Python 3.

Do you have any plans on Python 3 support?

If no I can do a port by myself but before doing anything would like to double check that you are accepting pull requests.

In general I was thinking about following plan:

  1. Setup Travis-CI project and ensure that all tests are passing for Python 2.7
  2. Switch SDK into well-known requests library which solves all edge cases related to HTTP communication and has support for both Python 2 and 3.
  3. Port all code by adding simple compat.py module (as an option six package could be used)

Please let me know your thoughts on this topic.

Failing tests: dev dep "sure" dropped support for Python 2.6, 3.2

2.6:
Some tests use the expect function from the sure module. Sure no longer supports Python 2.6 (sometime since our last build and now) and currently tests fail trying to run tox in Python 2.6.

ERROR: Failure: ImportError (cannot import name OrderedDict)
File "Opentok-Python-SDK/tests/test_archive_api.py", line 4,
File "Opentok-Python-SDK/tests/test_archive.py", line 4,
File "Opentok-Python-SDK/tests/test_session_creation.py", line 5

OrderedDict is from Python 2.7.

3.2:
$ pip install -r test_requirements.txt fails with:
sure does explicitly not support the following python versions due to big incompatibilities: ((3, 0), (3, 1), (3, 2))

move sessionId decoding routine to a new method/function

right now session decoding is implemented inside the generate_token function. it looks like this is a debug feature and probably not something you want in production (it indicates programmer error but is predictable) because it adds time cost.

as a first step, we can separate this into another routine so that its reusable and later see if we should add some "debug mode" or "log level" type of features.

add JSON Schema validations

In the PHP SDK, we are using JSON Schema to validate what comes back from the server. This would be a nice catch for a Response Error where the version of the SDK is outdated against the API.

Use create-session REST API that returns JSON data

There is a new version of the create-session REST API that returns JSON data when you include an "Accept: application/json" header in the request. If this is used the XML library dependency can be eliminated.

Update README.md to follow the standard outline

  • Install:
  • Install using pip
  • Download manually (using GitHub releases)
  • Usage:
  • Initializing
  • Creating Sessions
  • Generating Tokens
  • Working with Archives
  • Documentation
  • Requirements
  • Changes / Release Notes
  • Contributing / Testing

Changing Port Number

I have implemented the python web server on a ubuntu 14.04 LTS desktop and it works fine on localhost:5000. But when I want to connect to it from another computer I can't access it and the port is not open. Is there any way to open up the port so that I can access the server from outside ?

change RoleConstants into an enum

instead of RoleConstants being a kind of meaningless class, use Python's enum package to represent the idea of Roles better.

we can use this library: https://pypi.python.org/pypi/enum34, enum is implemented in python 3.4 but this is the backport for it back to 2.4.

class Role(Enum)
  publisher = "publisher"
  subscriber = "subscriber"
  moderator = "moderator"

Feature: integration testing

sometimes just checking against canned responses (fixtures) is not good enough.

the main use case for integration testing is running the suite against the internal nightly build environment to detect problems (incompatible API changes, bad handling in the SDKs, etc) early.

one of the challenges in running integration tests is that many of the operations being tested require a specific state on the server. for example: starting an archive successfully requires that at least one client connection to the specific OpenTok session exists, deleting an archive requires an archive to exist, stopping an archive requires a started archive, etc.

one approach is to repurpose the unit tests to run in a different mode where they can hit live servers.

another approach could be scenario-driven, where a scripted set of operations are carried out sequentially. this could be better in address the challenge with server side state.

another technique that could be employed to address the server side state challenge is using a specific build of the client side opentok.js library that can run in node. the integration tests could "shell out" to a CLI that can conduct client side operations that will assist in setting up the proper state (like a client connection before starting an archive).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.