Managing your MTurk Workers with Python

Amazon's Mechanical Turk (mTurk) is a crowdsourced marketplace that has become a valuable source of social scientific data. By using MTurk's API and Python, I'm going to overview a few programmatic solutions to common tasks facing researchers. 1

This tutorial will show you how to use Python to:

  1. get the IDs of all workers who completed a HIT
  2. assign a qualification to these workers
  3. bonus these workers
  4. send a message to these workers

Although you can easily accept your workers' submissions, there is no convenient method for assigning qualifications, sending bonuses, or sending messages to multiple workers simultaneously using MTurk's UI (its website). By using Python and the Boto module, we can overcome these inconveniences.

Before you begin, you'll need Python (I'm using version 2.7), Boto, and an AWS account.

Once you have your AWS account, you'll need to create your 'Access Key ID' and 'Secret Access Key'. Instructions for achieving this can be found here. Once everything has been set up, you can use the code below to get your mTurk account's current balance. (Importing the Price module is unimportant but will be necessary later, when we pay out bonuses.)

 #display account balance

 from boto.mturk.connection import MTurkConnection
 from boto.mturk.price import Price

 ACCESS_ID = your access id
 SECRET_KEY = your secret key
 HOST = 'mechanicalturk.amazonaws.com'

 mturk = MTurkConnection(aws_access_key_id=ACCESS_ID,
       aws_secret_access_key=SECRET_KEY,
       host=HOST)

 print mturk.get_account_balance()

With the object labeled mturk you will be able to execute commands and extract information from you MTurk account, and here we are extracting the account balance. If your balance shows up without generating any errors, you're ready to continue.

1) Get Worker IDs

The HIT: five MTurk workers were paid 20 cents each to tell me their favorite joke, with the understanding that the best joke would be paid a bonus of $1.

The winner:

Two mushrooms are in a bar having a drink when one looks at the other and says "I don't get why girls don't like me, I mean, hey, I'm a Fungi!"

This joke was so original that it came up twice. Perhaps originality costs more than 20 cents?

I accepted everyone's work through MTurk's UI. Next, I wanted to know who we would be qualifying, sending bonuses, and messaging.

 #display worker ids

 hit = '3PR3LXCWSF67WOX6Y5S8??????????'
 assignments = mturk.get_assignments(hit)

 for a in assignments:
  print a.WorkerId

Each HIT has its own ID. Using the HIT's ID, the hit variable, we can get the assignment IDs. These are the IDs associated with each worker's submission — in this case, each joke. From the assignment IDs, we can get the worker ID associated with each assignment and print the IDs of our five workers.

2) Assign a Qualification

This qualification was first created using MTurk's UI. By knowing the ID associated with this qualification, we can assign it to our workers.

 #assign qualifications

 qualification = "3JNQJJEQXNSX7K3S6OQG?????????"

 for a in assignments:
  mturk.assign_qualification(qualification,a.WorkerId,
         send_notification=False)

This qualification could be useful for excluding these workers from future research. It might be a good idea to do this because this study contained a deception that may increase suspicion.

3) Bonus Workers

The deception: rather than reserving the bonus for only our funniest worker, we're going to bonus everyone.

 #pay bonuses

 payment = Price(1.00)
 message = "[message that accompanies your bonus payment]"

 for a in assignments:
  mturk.grant_bonus(a.WorkerId,a.AssignmentId,
       payment,message)

To give a bonus, you must create a Price object while including an argument equal to the amount you intend to give each worker (and MTurk's fee will be added on top of this). Just like when you grant a bonus using MTurk's UI, you need to supply both the worker's ID and the ID of the worker's assignment — in this case, the worker's joke. Both of these IDs are conveniently located within each assignment object.

4) Message Workers

Lastly, our five workers were messaged to let them know that everyone received a bonus for their participation. The code below sent this information directly to our workers' email addresses. I asked our workers to reply to this message and indicate if they received their bonus, and I received messages from four workers that their bonuses came through without any problems. I assume the fifth worker was just too busy to reply, or uninterested.

 #message workers

 subject = "[message subject]"
 message = "[main message]"

 for a in assignments:
  mturk.notify_workers(a.WorkerId, subject, message)

This step could have been skipped by including this message directly with the bonus payment, however messaging workers separately was simple enough to not be an inconvenience.

Conclusion

Boto has far more features than are covered here, but these seemed to be the most useful for conducting research — especially if, like me, you send your workers to an external website to collect your data rather than rely on MTurk.

I have yet to try out this code on a large scale. When I have the chance, I'll be sure to write a new post if I encounter anything interesting.


  1. I have written an update to this guide that is important if you want to use this code to manage more than ten workers per HIT. It is available here