https://github.com/NYUCCL/psiTurk
Tip revision: cb281fe064fb55ce942e8e436169ed4403102069 authored by Todd Gureckis on 29 May 2014, 02:22:42 UTC
Merge remote-tracking branch 'origin/2.0.1_fixes'
Merge remote-tracking branch 'origin/2.0.1_fixes'
Tip revision: cb281fe
psiturk_org_services.py
import os, sys
import urllib2
import json
import datetime
import requests
from flask import jsonify
from version import version_number
import git
class PsiturkOrgServices:
"""
PsiturkOrgServices
this class provides an interface to the API provided
by the psiturk_org website. the two main features
of this API are registering secure ads
see: https://github.com/NYUCCL/api-psiturk-org
"""
def __init__(self, key, secret):
self.apiServer = 'https://api.psiturk.org' # 'https://api.psiturk.org' # by default for now
self.adServer = 'https://ad.psiturk.org'
self.sandboxAdServer = 'https://sandbox.ad.psiturk.org'
self.update_credentials(key,secret)
if not self.check_credentials():
print 'WARNING *****************************'
print 'Sorry, psiTurk Credentials invalid.\nYou will only be able to '\
+ 'test experiments locally until you enter\nvalid '\
+ 'credentials in the psiTurk Access section of ~/.psiturkconfig.\nGet your ' \
+ 'credentials at https://www.psiturk.org/login.\n'
def check_credentials(self):
r = requests.get(self.apiServer + '/api/ad', auth=(self.access_key,self.secret_key))
if r.status_code in [401, 403, 500]: # not sure 500 server error should be included here
return False
else:
return True
def update_credentials(self, key, secret):
self.access_key = key
self.secret_key = secret
def connect(self, server):
"""
connect:
"connects to server" since the is a fairly
basic API, just allows overriding of which Ad server
you are talking to
"""
self.apiServer = server
def get_system_status(self):
"""
get_system_status:
"""
try:
api_server_status_link = self.apiServer + '/status_msg?version=' + version_number
response=urllib2.urlopen(api_server_status_link,timeout=1)
status_msg = json.load(response)['status']
except:
status_msg = "Sorry, can't connect to psiturk.org, please check your internet connection.\nYou will not be able to create new hits, but testing locally should work.\n"
return status_msg
def get_my_ip(self):
"""
get_my_ip:
asks and external server what your ip appears to be
(useful is running from behind a NAT/wifi router).
Of course, incoming port to the router must be
forwarded correctly.
"""
if 'OPENSHIFT_SECRET_TOKEN' in os.environ:
ip = os.environ['OPENSHIFT_APP_DNS']
else:
ip = json.load(urllib2.urlopen('http://httpbin.org/ip'))['origin']
return ip
def create_record(self, name, content, username, password):
#headers = {'key': username, 'secret': password}
r = requests.post(self.apiServer + '/api/' + name, data=json.dumps(content), auth=(username,password))
return r
def update_record(self, name, recordid, content, username, password):
#headers = {'key': username, 'secret': password}
r = requests.put(self.apiServer + '/api/' + name + '/' + str(recordid), data=json.dumps(content), auth=(username,password))
return r
def delete_record(self, name, recordid, username, password):
#headers = {'key': username, 'secret': password}
r = requests.delete(self.apiServer + '/api/' + name + '/' + str(recordid), auth=(username,password))
return r
def query_records(self, name, username, password, query=''):
#headers = {'key': username, 'secret': password}
r = requests.get(self.apiServer + '/api/' + name + "/" + query, auth=(username,password))
return r
def get_ad_url(self, adId, sandbox):
"""
get_ad_url:
gets ad server thing
"""
if sandbox:
return self.sandboxAdServer + '/view/' + str(adId)
else:
return self.adServer + '/view/' + str(adId)
def set_ad_hitid(self, adId, hitId, sandbox):
"""
get_ad_hitid:
updates the ad with the corresponding hitid
"""
if sandbox:
r = self.update_record('sandboxad', adId, {'amt_hit_id':hitId}, self.access_key, self.secret_key)
else:
r = self.update_record('ad', adId, {'amt_hit_id':hitId}, self.access_key, self.secret_key)
if r.status_code == 201:
return True
else:
return False
def create_ad(self, ad_content):
"""
create_ad:
"""
if not 'is_sandbox' in ad_content:
return False
else:
if ad_content['is_sandbox']:
r = self.create_record('sandboxad', ad_content, self.access_key, self.secret_key)
else:
r = self.create_record('ad', ad_content, self.access_key, self.secret_key)
if r.status_code == 201:
return r.json()['ad_id']
else:
return False
def download_experiment(self, experiment_id):
"""
download_experiment:
"""
r = self.query_records('experiment', self.access_key, self.secret_key, query='download/'+experiment_id)
print r.text
return
class ExperimentExchangeServices:
"""
ExperimentExchangeServices
this class provides a non-authenticated interface to the API provided
by the psiturk_org website. the feature is
interfacing with the experiment exchange
see: https://github.com/NYUCCL/api-psiturk-org
"""
def __init__(self):
self.apiServer = 'https://api.psiturk.org' # 'https://api.psiturk.org' # by default for now
def query_records_no_auth(self, name, query=''):
#headers = {'key': username, 'secret': password}
r = requests.get(self.apiServer + '/api/' + name + "/" + query)
return r
def download_experiment(self, experiment_id):
"""
download_experiment:
"""
r = self.query_records_no_auth('experiment', query='download/'+experiment_id)
if r.status_code == 404:
print "Sorry, no experiment matching id # " + experiment_id
print "Please double check the code you obtained on the http://psiturk.org/ee"
else:
# check if folder with same name already exists.
expinfo = r.json()
gitr = requests.get(expinfo['git_url']).json()
if os.path.exists('./'+gitr['name']):
print "*"*20
print "Sorry, you already have a file or folder named "+gitr['name']+". Please rename or delete it before trying to download this experiment. You can do this by typing `rm -rf " + gitr['name'] + "`"
print "*"*20
return
if "clone_url" in gitr:
git.Git().clone(gitr["clone_url"])
print "="*20
print "Downloading..."
print "Name: " + expinfo['name']
print "Downloads: " + str(expinfo['downloads'])
print "Keywords: " + expinfo['keywords']
print "psiTurk Version: " + str(expinfo['psiturk_version_string'])
print "URL: http://psiturk.org/ee/"+experiment_id
print "\n"
print "Experiment downloaded into the `" + gitr['name'] + "` folder of the current directory"
print "Type 'cd " + gitr['name'] + "` then run the `psiturk` command."
print "="*20
else:
print "Sorry, experiment not located on github. You might contact the author of this experiment. Experiment NOT downloaded."
return