Skip to content

Commit 93fbff1

Browse files
committed
Merge branch 'modernization' of github.com:aoberoi/Opentok-Python-SDK into v2.2-docs
2 parents 56701eb + 2ca9765 commit 93fbff1

File tree

16 files changed

+575
-6
lines changed

16 files changed

+575
-6
lines changed

opentok/archives.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from datetime import datetime, date
2-
from six import iteritems, PY2, PY3
2+
from six import iteritems, PY2, PY3, u
33
import json
44
import pytz
55
if PY3:
@@ -75,7 +75,7 @@ def __init__(self, sdk, values):
7575
def stop(self):
7676
"""
7777
Stops an OpenTok archive that is being recorded.
78-
78+
7979
Archives automatically stop recording after 90 minutes or when all clients have disconnected
8080
from the session being archived.
8181
"""
@@ -86,7 +86,7 @@ def stop(self):
8686
def delete(self):
8787
"""
8888
Deletes an OpenTok archive.
89-
89+
9090
You can only delete an archive which has a status of "available" or "uploaded". Deleting an
9191
archive removes its record from the list of archives. For an "available" archive, it also
9292
removes the archive file, making it unavailable for download.
@@ -108,9 +108,9 @@ def json(self):
108108

109109
class ArchiveList(object):
110110

111-
def __init__(self, values):
111+
def __init__(self, sdk, values):
112112
self.count = values.get('count')
113-
self.items = map(lambda x: Archive(self, x), values.get('items', []))
113+
self.items = list(map(lambda x: Archive(sdk, x), values.get('items', [])))
114114

115115
def __iter__(self):
116116
for x in self.items:
@@ -125,4 +125,11 @@ def attrs(self):
125125
def json(self):
126126
return json.dumps(self.attrs(), default=dthandler, indent=4)
127127

128+
def __getitem__(self, key):
129+
return self.items.get(key)
130+
131+
def __setitem__(self, key, item):
132+
raise ArchiveError(u('Cannot set item {0} for key {1} in Archive object').format(item, key))
128133

134+
def __len__(self):
135+
return len(self.items)

opentok/opentok.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ def get_archives(self, offset=None, count=None):
386386
response = requests.get(self.archive_url() + "?" + urlencode(params), headers=self.archive_headers())
387387

388388
if response.status_code < 300:
389-
return ArchiveList(response.json())
389+
return ArchiveList(self, response.json())
390390
elif response.status_code == 403:
391391
raise AuthError()
392392
elif response.status_code == 404:

sample/Archiving/README.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# OpenTok Hello World Python
2+
3+
This is a simple demo app that shows how you can use the OpenTok-Python-SDK to create Sessions,
4+
generate Tokens with those Sessions, and then pass these values to a JavaScript client that can
5+
connect and conduct a group chat.
6+
7+
## Running the App
8+
9+
First, we highly recommend setting up a [virtualenv](http://www.virtualenv.org/en/latest/).
10+
11+
```
12+
$ virtualenv venv
13+
$ source venv/bin/activate
14+
```
15+
16+
Next, download the dependencies using [Pip](http://www.pip-installer.org/en/latest/), from the
17+
current directory:
18+
19+
```
20+
(venv)$ pip install -r requirements.txt
21+
```
22+
23+
Then add your own API Key and API Secret to the environment variables. There are a few ways to do
24+
this but the simplest would be to do it right in your shell.
25+
26+
```
27+
(venv)$ export API_KEY=0000000
28+
(venv)$ export API_SECRET=abcdef1234567890abcdef01234567890abcdef
29+
```
30+
31+
Finally, start the server.
32+
33+
```
34+
(venv)$ python helloworld.py
35+
```
36+
37+
Visit <http://127.0.0.1:5000/> in your browser. Open it again in a second window. Smile! You've just
38+
set up a group chat.
39+
40+
## Walkthrough
41+
42+
This demo application uses the [Flask web microframework](http://flask.pocoo.org/). It is similar to
43+
many other popular web frameworks. We are only covering the very basics of the framework, but you can
44+
learn more by following the links above.
45+
46+
### Main Application (helloworld.py)
47+
48+
The first thing done in this file is to import the dependencies we will be using. In this case that
49+
is the Flask web framework, the os module, and most importantly the OpenTok SDK.
50+
51+
```python
52+
from flask import Flask, render_template
53+
from opentok import OpenTok
54+
import os
55+
```
56+
57+
Next this file performs some basic checks on the environment. If it cannot find the `API_KEY`and
58+
`API_SECRET` environment variables, there is no point in continuing.
59+
60+
The object `app` is our application and its initialized by instantiating an object from Flask.
61+
Then we initialize an instance of OpenTok as `opentok`. If this file is run as the main file,
62+
we should start running the app.
63+
64+
```python
65+
app = Flask(__name__)
66+
opentok = OpenTok(api_key, api_secret)
67+
68+
# ...
69+
70+
if __name__ == "__main__":
71+
app.run()
72+
```
73+
74+
Now, lets discuss the Hello World application's functionality. We want to set up a group chat so
75+
that any client that visits a page will connect to the same OpenTok Session. Once they are connected
76+
they can Publish a Stream and Subscribe to all the other streams in that Session. So we just need
77+
one Session object, and it needs to be accessible every time a request is made. On the next line we
78+
simply call the `OpenTok` instance's `create_session` method to get a Session and store it in the
79+
`session` variable. Alternatively, `session_id`s are commonly stored in databses for applications
80+
that have many of them.
81+
82+
```python
83+
session = opentok.create_session()
84+
```
85+
86+
We only need one page, so we create one route handler for any HTTP GET requests to trigger.
87+
88+
```python
89+
@app.route("/")
90+
def hello():
91+
# ...
92+
```
93+
94+
Now all we have to do is serve a page with the three values the client will need to connect to the
95+
session: `api_key`, `session_id`, and `token`. The `api_key` is available in the outer scope so we
96+
can just assign it. The `session_id` is available as the `session.session_id` attribute. The `token`
97+
is generated freshly on this request by calling the `generate_token` method of the `opentok`
98+
instance, and passing in the `session_id`. This is because a Token is a piece of information that
99+
carries a specific client's permissions in a certain Session. Ideally, as we've done here, you
100+
generate a unique token for each client that will connect.
101+
102+
```python
103+
key = api_key
104+
session_id = session.session_id
105+
token = opentok.generate_token(session_id)
106+
```
107+
108+
Now all we have to do is serve a page with those three values. Lets call our `render_template`
109+
helper that will pick up a template called `index.html` from the `templates/` directory in our
110+
application and pass in the variables for it to include on the page.
111+
112+
```python
113+
return render_template('index.html', api_key=key, session_id=session_id, token=token)
114+
```
115+
116+
### Main Template (templates/index.html)
117+
118+
This file simply sets up the HTML page for the JavaScript application to run, imports the
119+
JavaScript library, and passes the values created by the server into the JavaScript application
120+
inside `public/js/helloworld.js`
121+
122+
### JavaScript Applicaton (static/js/helloworld.js)
123+
124+
The group chat is mostly implemented in this file. At a high level, we connect to the given
125+
Session, publish a stream from our webcam, and listen for new streams from other clients to
126+
subscribe to.
127+
128+
For more details, read the comments in the file or go to the
129+
[JavaScript Client Library](http://tokbox.com/opentok/libraries/client/js/) for a full reference.

sample/Archiving/archiving.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from flask import Flask, render_template, request, redirect, url_for
2+
from opentok import OpenTok
3+
from email.utils import formatdate
4+
import os, time
5+
6+
try:
7+
api_key = os.environ['API_KEY']
8+
api_secret = os.environ['API_SECRET']
9+
except Exception:
10+
raise Exception('You must define API_KEY and API_SECRET environment variables')
11+
12+
app = Flask(__name__)
13+
opentok = OpenTok(api_key, api_secret)
14+
session = opentok.create_session()
15+
16+
@app.template_filter('datefmt')
17+
def datefmt(dt):
18+
return formatdate(time.mktime(dt.timetuple()))
19+
20+
@app.route("/")
21+
def index():
22+
return render_template('index.html')
23+
24+
@app.route("/host")
25+
def host():
26+
key = api_key
27+
session_id = session.session_id
28+
token = opentok.generate_token(session_id)
29+
return render_template('host.html', api_key=key, session_id=session_id, token=token)
30+
31+
@app.route("/participant")
32+
def participant():
33+
key = api_key
34+
session_id = session.session_id
35+
token = opentok.generate_token(session_id)
36+
return render_template('participant.html', api_key=key, session_id=session_id, token=token)
37+
38+
@app.route("/history")
39+
def history():
40+
page = int(request.args.get('page', '1'))
41+
offset = (page - 1) * 5
42+
archives = opentok.get_archives(offset=offset, count=5)
43+
44+
show_previous = '/history?page=' + str(page-1) if page > 1 else None
45+
show_next = '/history?page=' + str(page+1) if archives.count > (offset + 5) else None
46+
47+
return render_template('history.html', archives=archives, show_previous=show_previous,
48+
show_next=show_next)
49+
50+
@app.route("/download/<archive_id>")
51+
def download(archive_id):
52+
archive = opentok.get_archive(archive_id)
53+
return redirect(archive.url)
54+
55+
@app.route("/start")
56+
def start():
57+
archive = opentok.start_archive(session.session_id, name="Python Archiving Sample App")
58+
return archive.json()
59+
60+
@app.route("/stop/<archive_id>")
61+
def stop(archive_id):
62+
archive = opentok.stop_archive(archive_id)
63+
return archive.json()
64+
65+
@app.route("/delete/<archive_id>")
66+
def delete(archive_id):
67+
opentok.delete_archive(archive_id)
68+
return redirect(url_for('history'))
69+
70+
71+
if __name__ == "__main__":
72+
app.debug = True
73+
app.run()

sample/Archiving/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Flask
2+
-e ./../..
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* Move down content because we have a fixed navbar that is 50px tall */
2+
body {
3+
padding-top: 50px;
4+
padding-bottom: 20px;
5+
background-color: #F2F2F2;
6+
}
7+
8+
/* Responsive: Portrait tablets and up */
9+
@media screen and (min-width: 768px) {
10+
/* Remove padding from wrapping element since we kick in the grid classes here */
11+
.body-content {
12+
padding: 0;
13+
}
14+
}
15+
16+
#subscribers div {
17+
float: left;
18+
}
19+
20+
.bump-me {
21+
padding-top: 40px;
22+
}
20.6 KB
Loading
21.3 KB
Loading
20.6 KB
Loading

sample/Archiving/static/js/host.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
var session = OT.initSession(sessionId),
2+
publisher = OT.initPublisher("publisher"),
3+
archiveID = null;
4+
5+
session.connect(apiKey, token, function(err, info) {
6+
if(err) {
7+
alert(err.message || err);
8+
}
9+
session.publish(publisher);
10+
});
11+
12+
session.on('streamCreated', function(event) {
13+
session.subscribe(event.stream, "subscribers", { insertMode: "append" });
14+
});
15+
16+
session.on('archiveStarted', function(event) {
17+
archiveID = event.id;
18+
console.log("ARCHIVE STARTED");
19+
$(".start").hide();
20+
$(".stop").show();
21+
});
22+
23+
session.on('archiveStopped', function(event) {
24+
archiveID = null;
25+
console.log("ARCHIVE STOPPED");
26+
$(".start").show();
27+
$(".stop").hide();
28+
});
29+
30+
$(document).ready(function() {
31+
$(".start").click(function(event){
32+
$.get("start");
33+
}).show();
34+
$(".stop").click(function(event){
35+
$.get("stop/" + archiveID);
36+
}).hide();
37+
});

0 commit comments

Comments
 (0)