Boto Mturk Tutorial: Create hits

This tutorial will be the first of many about mturk and Boto, a python interface to Amazon Web Services.
When I started to develop python tasks for automate some process by using amazon mturk was a little bit difficult found enough information about the usage of Boto and about mturk, for this reason I want to make those things easy for others developers that, like me some time ago, are starting to deal with Amazon Mturk.
Let’s start from the origins what you need is:

Boto library (2.0b4): you can install it with easy_install or download the package from the github page.
Amazon Web Services keys: create an account or login if you already have one on, after that go to you account admin panel and than security settings.
In the page scroll to the section Access credentials and keep note of the Access Key ID and Secret Access Key.

We are almost ready for use this keys with Boto but before that we have to login with the aws account on for create the Mturk Sandbox account.

Ok, now we can start to write some code for test if our keys work and if we can connect to the Mturk engine.
Below there is the code for connect to the mturk api and get the account balance.

from boto.mturk.connection import MTurkConnection

ACCESS_ID ='your access key'
SECRET_KEY = 'your secret key'
HOST = ''

mtc = MTurkConnection(aws_access_key_id=ACCESS_ID,

print mtc.get_account_balance()

The expected result is a list with one value, normally $10,000.00 (I never see numbers like this on my bank account 🙁 )

If everything works fine we can start to create an mturk HIT.
Basically an HIT is a question, or a collection of questions. I strongly suggest you to read the HIT Data Structure before continue with this tutorial.

Let’s start to create our first HIT with 2 questions:
1 mandatory with choices and another one not mandatory with a free text answer.

from boto.mturk.connection import MTurkConnection
from boto.mturk.question import QuestionContent,Question,QuestionForm,

ACCESS_ID ='your acces key'
SECRET_KEY = 'your secret key'
HOST = ''

mtc = MTurkConnection(aws_access_key_id=ACCESS_ID,

title = 'Give your opinion about a website'
description = ('Visit a website and give us your opinion about'
               ' the design and also some personal comments')
keywords = 'website, rating, opinions'

ratings =[('Very Bad','-2'),
         ('Not bad','0'),
         ('Very Good','1')]

#---------------  BUILD OVERVIEW -------------------

overview = Overview()
overview.append_field('Title', 'Give your opinion on this website')
overview.append(FormattedContent('<a target="_blank"'
                                 ' href="">'
                                 ' Mauro Rocco Personal Forge</a>'))

#---------------  BUILD QUESTION 1 -------------------

qc1 = QuestionContent()
qc1.append_field('Title','How looks the design ?')

fta1 = SelectionAnswer(min=1, max=1,style='dropdown',

q1 = Question(identifier='design',

#---------------  BUILD QUESTION 2 -------------------

qc2 = QuestionContent()
qc2.append_field('Title','Your personal comments')

fta2 = FreeTextAnswer()

q2 = Question(identifier="comments",

#--------------- BUILD THE QUESTION FORM -------------------

question_form = QuestionForm()

#--------------- CREATE THE HIT -------------------

               duration = 60*5,

If you don’t see any output everything worked well, for be sure navigate to and see if your hit is in the list (can take some time to appear, you can also check on the requester sandbox admin panel).
The code is very clear and self explained but I will give you anyway some description with links to the Boto DOCS.

Overview: The overview is a free content of the question form, this means that can be everything (binary content, an html content, ex.), remember that it isn’t a “question object” is just an arbitrary content, in my example is a link to the website.

Question: The question is mainly made by the AnswerSpecification object, that specify which kind of answer have to be rendered for the question and by the QuestionContent object. The content can be, like for the Overview, a text, a binary content, an html content, ex.

QuestionForm: This is the container for all your questions and overviews, basically is an extension of a python standard list.

create_hit method: This is the method for create an hits, for see which parameters it accepts take a look to the docs.
A little suggestion, the question and questions parameters are different, the first one accept a Question object if you want to create a hit with just a question, the second one accept a QuestionForm.

Well, now you should be able to create an hit, you can also do your hits on the worker sandbox for see how they works and for have some results to fetch.
In the next tutorial I will speak about fetching result from your hits and accept or refuse payments to the workers.
See you soon 😉

  • Thanks for a great tutorial Mauro.

    One small mystery – when running your script above that creates a hit, why isn’t the hit shown under “Batches in progress” in the requester sandbox?

    I see it OK when I “Manage Hits Individually” and in the Worker sandbox, just not in batches.

  • Mauro Rocco

    Yep, is a still a mystery, just look at this thread

    Seem that only the hits created trough the website are showed on batches.

  • Ah well. Thanks for the tip!

  • One further question – how to get a submit button at the bottom of the form ( like this – from one of the sample templates )?

    Your example uses the default “Submit Hit” button – – and looking at the botoa API, there doesn’t seem to be an easy way to change this.

    Many thanks.

  • Mauro Rocco

    Yep, seems that there is no way, otherwise you can do what you want with external question, I really like it becouse are just iframe that point to an url on you server.

  • Pingback: Boto Mturk Tutorial: Fetch results and pay workers | Mauro Rocco()

  • Joseph Turian

    How long does it typically take for your HIT to appear in the list?

  • Mauro Rocco

    Between 5 and 30 seconds in the SandBox system, normally the production one is faster.

  • Pingback: » Python+EC2 update p2 Optimal Energetics – My PhD()

  • Gopal

    Hi, do you know how to get the RequesterAnnotation attribute from the hit? doing hit.RequesterAnnotation doesn’t work.

  • Mauro Rocco

    @Gopal when I can’t find an attribute normally I use python dir() function this should help you to understand if the parameter is there.
    Remember that RequesterAnnotation is visible only to the user that created the hit.

  • Thomas

    Question: I get this back – how can I use https connection with boto?

    NonSecureRequestThis request must be made over a secure channel. You must use ‘https’ rather than ‘http’….

  • Mauro Rocco

    @Thomas, which version of boto are you using ?
    By default the last version of BOTO uses https

  • Amir

    HITLayoutId can be passed to allow using a form designed on the mturk site. has: “You can use either the HITLayoutId or the Question parameter when calling CreateHIT, but not both.”

    But the boto’s MTurkConnection.create_hit does not seem to support it adding HITLayoutId.
    So I am trying to fit the existing forms we got and pass through a structure with Questions / QuestionForm etc as your sample has.
    Extending MTurkConnection.create_hit and adding code to code to support HITLayoutId is also a way I am considering.
    Any solution which works would be excellent. Let me know if you got a way to solve this. I can post back here when it’s solved.

  • Mauro Rocco

    Hi @Amir
    By looking here (2.0.6 dev)
    looks like that the create method accept a parameter HitLayout that by defaults is none.
    This parameter is in fact the HitLayoutId as you can see from the source code here:

    So I think that this is what you need.

    Let me know


  • Amir

    Hey Mauro,

    I can’t pass the HitLayoutId with the current 2.5.2 boto code.
    It is lacking the support you got on latest.
    Following code in create_hit() is missing:
    “if hit_layout is None:”
    “params[‘HITLayoutId’] = hit_layout”

    I could not used the latest (2.6.0?) code it didn’t work at all, so had to use 2.5.2. (something with security if I recall, saw a few posts on that online, one said that previous version works)

    Either way, thanks for pointing this solution, I will try the 2.5.2 code and have my updated version of create_hit match your 2.6 code and see if it works.

  • Mauro Rocco

    @Amir Keep me posted on this please. Thank you

  • Michael Chapman

    Hi Mauro, do you know if there is a way to add images to a question using boto? For example, if I wanted a worker to choose their favorite image out of 3 images, would there be a way to do that?

  • Hi Michael,

    For more advanced question like your use case I would recommend to use the ExternalQuestion( It’s basically an I frame pointing to a page that you host on your side, it’s enough you post the right data to mturk like written in the docs.

  • Michael Chapman

    What if I only wanted to add one image to a question? Is it still possible to do with boto, or would I need to use the ExternalQuestion? (I’d rather stick with Python and boto if possible)

  • To clarify. Mturk api doesn’t allow you to load images or rich html directly via api. If you want an alternative to iframe than you can go for an HitLayout, but this needs to be created first via mturk web interface.

    It’s useful when you don’t want to host anything on your side.

  • dg

    Thanks a lot for the example Mauro – this is really helpful! I have one question here.
    First, how do I modify the content of the function “overview.append(FormattedContent(…))”? For example, I need to enter my task description and couple of examples to describe my task. I can create a content like “content.html” but not sure how to include the “html” file in the overview.append function.

  • Hi dg,

    The most easy way is to just use python, read you html content from a file and put it in a string. After you just need to pass the string to the function FormattedContent.
    Off course first check which xhtml tags are allowed

  • dg

    Thanks a lot for the pointer!

  • Gitesh Chopra

    Hello Mauro Sir ,
    As a part of my final year project , I built an application using the BOTO Api. I am fetching the instance details such as ID , Public IP , DNS name , 5 security groups to which it is attached and then putting them in MYSQL Database. Similar thing , I am doing for Security groups and Routing tables. Fetch the route table / security group ID , put the rules corresponding to them , such as protocol , from port / to port in a MYSQL table.
    Then from the table I am fetching , these details and displaying on the screen. I am also working on a functionality , from which I could restore a deleted rule of security group or route table from the database . Its a kind of BACKUP & RESTORE application . I worked quite hard to learn python , AWS and Boto API from scratch but still I faced a lot of criticism .
    The coordinators at my college said , ” You are only fetching , you are not BUILDING SOMETHING “.

    “everything is already provided in BOTO , what HAVE YOU DONE ? ” .
    “this is nothing more than a small program for me “.
    “This is too small for a project for me “.

    Sir , I think you being a maestro in AWS , Boto could show me the way out . I still have about 10 days for my final presentation , before 1st December.
    . If it is possible, could you give me suggestions as to what functionality should I add , so that I can pan those critics (lecturers) , this tension of getting insulted goes away. I am hoping this project becomes ‘big’ , doesn’t merely remain a ‘small program’ , and I don’t keep fetching , I ‘build’ something and I can answer that I have done something .

    Really looking forward for your help sir.

  • Hi,
    Honestly I don’t know what you are expecting for me. You didn’t ask anything specific about BOTO that I could answer.
    If you ask me something specific I will happy to answer.


  • Gitesh Chopra

    Sir ,
    I am asking for your valuable suggestions / input as to what functionality I can add using BOTO , given the fact I have already fetched the instance , route table , security groups details and put them into the database. I now plan to put them on a web page using Django. I am not asking for any specific problem / troubleshooting.
    I just want your opinion / idea / input as to what functionality using BOTO is possible for me to add in my project , so that it gets approved .(Given the fact that , it was criticized for being TOO SMALL for a project , and was asked to be modified and add some stuff into it ).

  • Well BOTO is a Python API to the Amazon Web Services, so just browse the Amazon AWS catalog and see which services you could use in your project.
    Honestly I think you should ask all this question to your teacher and not to someone on an online blog, I’m sure he is the one in the best position to help you.

  • Andres

    thank you for this post !
    I had spent more than 10 hours figuring out my way in mturk API (java C# php etc)
    But this is the most (only) effective way I have found so far.
    Thanks a lot!

  • AB

    Hi , Post is really very informative.I want to create a categorization job in MTurk where people will read posts from a CSV and categorize the post into 3 categories Can you help me out in uploading the CSV in MTurk and creating HIT for each row of the csv.

  • Hi, I think that write a post for free to help others was already enough. I can’t help you build your project.

  • jtnimoy

    i get the same thing. google app engine.

  • Nicole Kostosky

    Hello Mauro,

    When designing an experiment on MTurk, I want to use radio buttons and images. I want to present an image then radio buttons with various options. I know how to hide and display images, but I do not know how to hide and display radio buttons. Is that possible?


  • Hi Nicole,
    If you are using standard html question than it’s all about using html and JavaScript. Radio button have also the css property display that you can set to none.
    Hopefully I answered your question.


  • Nicole Kostosky

    Thank you so much!

  • peter

    Currently, I want to assign qualification to workers on Mturk, but I cannot access to “qualification_type_id”. AMT documents shows that A Qualification type is given a Qualification type ID when you call the CreateQualificationType operation operation, and it retains that ID forever.

    I tested with code :

    qualification = Qualifications()

    qual = mtc.create_qualification_type(name = ‘q’, description=’qualification’, status = ‘Active’)

    print dir(qual)

    But I cannot find “qualification_type_id” attributes by call print dir(qual). And I need the “qualification_type_id”.

  • Hi Peter,
    Have you tried print dir(qual[0]) ?

  • peter

    aha, it works by using qual[0]. Thanks a lot.

  • This is something about BOTO that people often forget, every call returns a list :-|.
    Not a fan of it but it is kind of logic when you deeply understand the lib.

  • Xiao Ma

    This is awesome and very helpful! Thanks.

  • Weilong Wu

    I am running into the same issue with the tutorial code

    on Mac 10.12
    python version: 2.7
    boto: 2.46.1

    any help would be appreciated !

  • Muhammad Huzaifa Qamer

    Hi everyone, is there any similar tutorial written for boto3?