Skip to content

Instantly share code, notes, and snippets.

@deargle
Created November 7, 2017 23:31
Show Gist options
  • Save deargle/b15272fe2a883ec7bbf68f9b131edc64 to your computer and use it in GitHub Desktop.
Save deargle/b15272fe2a883ec7bbf68f9b131edc64 to your computer and use it in GitHub Desktop.
from sqlalchemy import create_engine, MetaData, Table, text
import json
import pandas as pd
from boto.mturk.connection import MTurkConnection
import random
import sys
from psiturk.models import Participant
from psiturk.db import db_session, init_db
from psiturk.amt_services import MTurkServices
from psiturk.psiturk_config import PsiturkConfig
sandbox = False
if sandbox:
host = 'mechanicalturk.sandbox.amazonaws.com'
else:
host = 'mechanicalturk.amazonaws.com'
mtc = MTurkConnection(host=host)
db_url = "<redacted>" # or get it from psiturk config file...
table_name = 'turkdemo'
data_column_name = 'datastring'
# boilerplace sqlalchemy setup
engine = create_engine(db_url)
metadata = MetaData()
metadata.bind = engine
table = Table(table_name, metadata, autoload=True)
# instantiate psiturk stuff
config = PsiturkConfig()
config.load_config()
amt_services = MTurkServices(
config.get('AWS Access', 'aws_access_key_id'), \
config.get('AWS Access', 'aws_secret_access_key'),
sandbox
)
init_db()
#bonus reason
reason = "Thank you!"
# get all workers with status 'submitted'
workers = amt_services.get_workers(assignment_status='Submitted')
uniqueIds = [ worker['workerId'] + ':' + worker['assignmentId'] for worker in workers ]
# make a query and loop through
s = table.select()
#status codes of subjects who have pending mturk submissions
statuses = [3,4]
s = s.where(table.c.status.in_(statuses))
s = s.where(table.c.uniqueid.in_(uniqueIds))
# if you have workers you wish to exclude, add them here
exclude = []
if exclude:
s = s.where(~table.c.uniqueid.in_(exclude))
hits_to_consider = []
if hits_to_consider:
s = s.where(table.c.hitid.in_(hits_to_consider))
rows = s.execute()
data = []
for row in rows:
data.append(row[data_column_name])
# Now we have all participant datastrings in a list.
# Let's make it a bit easier to work with:
# parse each participant's datastring as json object
# and take the 'data' sub-object
passed_assignment_ids = []
for part_json in data:
part = json.loads(part_json)
worker_id = part['workerId']
assignment_id = part['assignmentId']
accuracy_string = part['questiondata']['accuracy']
accuracy = float(accuracy_string.rstrip('%')) / 100
#accuracy = random.random() #hahahahahah that was almost really bad
if accuracy < 0.5:
# rejected!
print "Rejecting {} because accuracy was {:.0%}".format(assignment_id, accuracy)
feedback = "Sorry, your accuracy was below the threshold, suggesting that you \
were not paying attention during the task."
#mtc.reject_assignment(assignment_id, feedback=feedback)
else:
print "Passing {} with accuracy of {:.0%}".format(assignment_id, accuracy)
success = amt_services.approve_worker(assignment_id)
if success:
print 'approved', assignment_id
try:
part_db = Participant.query.\
filter(Participant.assignmentid == assignment_id).\
filter(Participant.endhit != None).\
one()
amount = part_db.bonus
status = part_db.status
if status in [5,7]:
raise "this participant shouldn't have reached this point, they've already been credited or bonused...", assignment_id
part_db.status = 5
if amount <= 0:
print "bonus amount <=$0, no bonus given to", assignment_id
elif status == 7:
print "bonus already awarded to ", assignment_id
else:
success = amt_services.bonus_worker(assignment_id,
amount, reason)
if success:
print "gave bonus of $" + str(amount) + " to " + \
assignment_id
part_db.status = 7
else:
print "*** failed to bonus", assignment_id
db_session.add(part_db)
db_session.commit()
except Exception as e:
print e
print "*** failed to bonus", assignment_id
else:
print '*** failed to approve', assignment_id
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment