Here is a heavily modified version of one of the Khan API examples that does exactly what you are looking for (I needed the same information).
import cgi
import rauth
import SimpleHTTPServer
import SocketServer
import time
import webbrowser
import requests
students = ['student1@email.com','student2@email.com']
courses = ['programming','html-css','html-css-js','programming-games-visualizations']
# You can get a CONSUMER_KEY and CONSUMER_SECRET for your app here:
# http://www.khanacademy.org/api-apps/register
CONSUMER_KEY = 'abcdefghijklmnop'
CONSUMER_SECRET = 'qrstuvwxyz123456'
CALLBACK_BASE = '127.0.0.1'
SERVER_URL = 'http://www.khanacademy.org'
VERIFIER = None
# Create the callback server that's used to set the oauth verifier after the
# request token is authorized.
def create_callback_server():
class CallbackHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
global VERIFIER
params = cgi.parse_qs(self.path.split('?', 1)[1],
keep_blank_values=False)
VERIFIER = params['oauth_verifier'][0]
self.send_response(200)
self.send_header('Content-Type', 'text/plain')
self.end_headers()
self.wfile.write('OAuth request token fetched and authorized;' +
' you can close this window.')
def log_request(self, code='-', size='-'):
pass
server = SocketServer.TCPServer((CALLBACK_BASE, 0), CallbackHandler)
return server
# Make an authenticated API call using the given rauth session.
def get_api_resource(session):
start = time.time()
allProgress = []
for student in students:
print "Getting key for",student
url = SERVER_URL + '/api/v1/user?email=' + student
split_url = url.split('?', 1)
params = {}
# Separate out the URL's parameters, if applicable.
if len(split_url) == 2:
url = split_url[0]
params = cgi.parse_qs(split_url[1], keep_blank_values=False)
response = session.get(url, params=params)
studentKhanData = response.json()
try:
if student != studentKhanData['student_summary']['email']:
print "Mismatch. Khan probably returned my data instead."
print "This student probably needs to add me as a coach."
print "Skipping",student
continue
key = studentKhanData['student_summary']['key']
except TypeError as e:
print "Error:",e
print "Does this student have a Khan account?"
print "Skipping",student
continue
individualProgress = []
for course in courses:
print "Getting",course,"progress for",student
ts = int(time.time()*1000)
url = SERVER_URL + '/api/internal/user/topic-progress/' + course + '?casing=camel&userKey=' + key + '&lang=en&_=' + str(ts)
print url
split_url = url.split('?', 1)
params = {}
# Separate out the URL's parameters, if applicable.
if len(split_url) == 2:
url = split_url[0]
params = cgi.parse_qs(split_url[1], keep_blank_values=False)
response = session.get(url, params=params)
progressData = response.json()
progressArray = progressData['topicProgress']
challengeCount = 0
for activity in progressArray:
if activity['status'] == 'complete' and activity['type'] == 'challenge':
challengeCount += 1
individualProgress.append(challengeCount)
allProgress.append([student,individualProgress])
for x in allProgress:
print x
print "\n"
end = time.time()
print "\nTime: %ss\n" % (end - start)
def run_tests():
# Create an OAuth1Service using rauth.
service = rauth.OAuth1Service(
name='autoGrade',
consumer_key=CONSUMER_KEY,
consumer_secret=CONSUMER_SECRET,
request_token_url=SERVER_URL + '/api/auth2/request_token',
access_token_url=SERVER_URL + '/api/auth2/access_token',
authorize_url=SERVER_URL + '/api/auth2/authorize',
base_url=SERVER_URL + '/api/auth2')
callback_server = create_callback_server()
# 1. Get a request token.
request_token, secret_request_token = service.get_request_token(
params={'oauth_callback': 'http://%s:%d/' %
(CALLBACK_BASE, callback_server.server_address[1])})
# 2. Authorize your request token.
print "Get authorize URL"
authorize_url = service.get_authorize_url(request_token)
print authorize_url
webbrowser.open(authorize_url)
#It is possible to automate this part using selenium, but it appears to be against Khan Academy's Terms of Service
callback_server.handle_request()
callback_server.server_close()
# 3. Get an access token.
session = service.get_auth_session(request_token, secret_request_token,
params={'oauth_verifier': VERIFIER})
# Repeatedly prompt user for a resource and make authenticated API calls.
print
#while(True):
get_api_resource(session)
def main():
run_tests()
if __name__ == "__main__":
main()