Skip to content

Commit 178a21d

Browse files
authored
Use own ad server (#226)
* documenting the tab-complete functions * adding functionality for gunicorn ssl and for specifying one's own ad_location (instead of using the psiturk location) * printing the ad url and the mturk url, for both psiturk and non-psiturk ad_locations * no need to ask them twice if they're using an external server... * functionizes generate_hit_config and also create_psiturk_ad to make hit_create less bulky * Adding some documentation for the new [server parameter] and [shell parameter] SSL- and ad-server-related experimental features. Also I'm removing most of the inline documentation from the default local config.txt file. It seemed like it might have been overwhelming to newcomers. I moved it into the docs instead. * added important note to docs emphasizing that if the psiturk server is ssl-enabled, a proxy server must be used in front of it in order to serve static content. * warn before reloading on submit page if it hasn't finished submitting to mturk yet.
1 parent fb4b1fc commit 178a21d

File tree

10 files changed

+413
-159
lines changed

10 files changed

+413
-159
lines changed

doc/config/server_parameters.rst

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@ command line. An example looks like this:
77

88
::
99

10-
[Server Parameters]
11-
host = 0.0.0.0
12-
port = 22362
13-
cutoff_time = 30
14-
logfile = server.log
15-
loglevel = 2
16-
debug = true
17-
login_username = examplename
18-
login_pw = examplepassword
19-
threads = auto
10+
[Server Parameters]
11+
host = 0.0.0.0
12+
port = 22362
13+
cutoff_time = 30
14+
logfile = server.log
15+
loglevel = 2
16+
debug = true
17+
login_username = examplename
18+
login_pw = examplepassword
19+
threads = auto
20+
#certfile = <path_to.crt>
21+
#keyfile = <path_to.key>
2022

2123
`host` [ string]
2224
--------------
@@ -91,3 +93,46 @@ the the psiturk webserver will run. This enables multiple
9193
simultanous connections from internet users. If you select
9294
`auto` it will set this based on the number of processor
9395
cores on your current computer.
96+
97+
`certfile` [ string ]
98+
----------------------
99+
.. warning::
100+
101+
SSL support for the psiturk server is an experimental feature.
102+
103+
`certfile` should be the /path/to/your/domain/SSL.crt
104+
105+
If both certfile and keyfile are set and the files readable, then
106+
the psiturk gunicorn server will run with ssl. You will need
107+
to execute the psiturk with privileges sufficient to read
108+
the keyfile (typically root). If you run `psiturk` with `sudo` and if you are using
109+
a virtual environment, make sure to execute the full path to the desired psiturk instance in your environment.
110+
See `launch-sudo-psiturk in this gist`_ for an example.
111+
112+
If you want to do this, you are responsible for obtaining
113+
your own cert and key. It is not necessary to run the
114+
psiturk server with `ssl` in order to use your own ad server.
115+
You can have a proxy server such as `nginx` in front of
116+
psiturk/gunicorn which handles ssl connections. See `this gist`_ for an example. **However, if you configure the psiturk server to run with SSL by setting the `certfile` and `keyfile` here, you must use a proxy server in front of psiturk to serve the content in your /static folder. An SSL-enabled psiturk/gunicorn server will not serve static content -- it will only serve dynamic content.**
117+
118+
See http://docs.gunicorn.org/en/stable/deploy.html for more information on setting up proxy servers with the psiturk (gunicorn) server.
119+
120+
.. seealso::
121+
122+
`use_psiturk_ad_server <shell_parameters.html#use-psiturk-ad-server-true-false>`__
123+
How to use your own ad_location. Does not require that the **psiTurk** server be SSL-enabled. (Although you will still need your own SSL certificate and key)
124+
125+
`keyfile` [ string ]
126+
----------------------
127+
.. warning::
128+
129+
SSL support for the psiturk server is an experimental feature.
130+
131+
`certfile` should be the /path/to/your/domain/private-SSL.key. Although .crts can contain .key files within them,
132+
psiturk currently requires that you point to separate .crt and .key files for this experimental feature to work.
133+
134+
See the documentation for `certfile` for more information.
135+
136+
.. _launch-sudo-psiturk in this gist: gist_
137+
.. _this gist: gist_
138+
.. _gist: https://gist.github.com/deargle/5d8c01660a77b8090a2cd24efcda2c59

doc/config/shell_parameters.rst

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,64 @@ to `true` to lessen the chance of accidentally posting a live HIT to mTurk.
2020

2121
`Overview of the command-line interface <../command_line_overview.html>`__
2222
The basic features of the **psiTurk** command line.
23+
24+
`use_psiturk_ad_server` [true | false]
25+
---------------------------------------
26+
27+
.. warning::
28+
29+
Non-use of the psiturk ad server is an experimental feature.
30+
31+
If set to `true`, then the **psiTurk** secure ad server functionality will be enabled,
32+
and your ad will be hosted on psiturk.org when creating hits on AMT.
33+
34+
If you want to host your own ad, then set this to `false`. You are responsible for obtaining
35+
your own cert and key and for configuring your own proxy server in front
36+
of psiturk/gunicorn. It is not necessary to also include the cert and key
37+
in the [Server Parameters] section -- you can have a proxy server
38+
such as nginx in front of psiturk/gunicorn which handles SSL connections.
39+
Although if you don't have your SSL certs in both places, then traffic between
40+
your proxy server and psiturk/gunicorn will not be encrypted. Perhaps that
41+
doesn't matter to you though if you configure your proxy server to pass traffic
42+
to your gunicorn/psiturk server via localhost.
43+
44+
If set to `false` then you must also specify your custom `ad_location` (see below).
45+
46+
.. seealso::
47+
48+
See the `[Server Parameters] certfile and keyfile configs <server_parameters.html>`__
49+
for ssl-enabling the psiturk server (although this is not required to use your
50+
own ad location).
51+
52+
.. seealso::
53+
54+
See `this gist`_ for an example nginx psiturk SSL configuration
55+
56+
57+
`ad_location` [false | string]
58+
------------------------------
59+
60+
.. warning::
61+
62+
Non-use of the psiturk ad server is an experimental feature.
63+
64+
`ad_location` is only used if `use_psiturk_ad_server` is `false`.
65+
Set to whatever you set up your proxy server to listen on. This will be sent directly
66+
to AMT when creating your HITs to tell AMT where to look for your ad.
67+
68+
Format is as follows::
69+
70+
https://<host>:<port>/ad
71+
72+
Some gotcha's:
73+
74+
* don't forget the `/ad` at the end. And don't append a trailing backslash.
75+
* you must use `https://` or AMT will explode.
76+
* the `<port>` should be the port your *proxy server* (such as nginx) is running on, *not* the **psiturk** port. See the `gist`_ for a full example.
77+
78+
.. seealso::
79+
80+
See the information for the `use_psiturk_ad_server` configuration above as well.
81+
82+
.. _this gist: gist_
83+
.. _gist: https://gist.github.com/deargle/5d8c01660a77b8090a2cd24efcda2c59

doc/configuration.rst

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -71,41 +71,47 @@ project:
7171

7272
::
7373

74-
[HIT Configuration]
75-
title = Stroop task
76-
description = Judge the color of a series of words.
77-
amt_keywords = Perception, Psychology
78-
lifetime = 24
79-
us_only = true
80-
approve_requirement = 95
81-
contact_email_on_error = [email protected]
82-
ad_group = My research project
83-
psiturk_keywords = stroop
84-
organization_name = New Great University
85-
browser_exclude_rule = MSIE, mobile, tablet
86-
87-
[Database Parameters]
88-
database_url = sqlite:///participants.db
89-
table_name = turkdemo
90-
91-
[Server Parameters]
92-
host = 0.0.0.0
93-
port = 22362
94-
cutoff_time = 30
95-
logfile = server.log
96-
loglevel = 2
97-
debug = true
98-
login_username = examplename
99-
login_pw = examplepassword
100-
threads = auto
101-
102-
[Task Parameters]
103-
experiment_code_version = 1.0
104-
num_conds = 1
105-
num_counters = 1
106-
107-
[Shell Parameters]
108-
launch_in_sandbox_mode = true
74+
[HIT Configuration]
75+
title = Stroop task
76+
description = Judge the color of a series of words.
77+
amt_keywords = Perception, Psychology
78+
lifetime = 24
79+
us_only = true
80+
approve_requirement = 95
81+
contact_email_on_error = [email protected]
82+
ad_group = Default psiTurk Stroop Example
83+
psiturk_keywords = stroop
84+
organization_name = New Great University
85+
browser_exclude_rule = MSIE, mobile, tablet
86+
87+
[Database Parameters]
88+
database_url = sqlite:///participants.db
89+
table_name = turkdemo
90+
91+
[Server Parameters]
92+
host = localhost
93+
port = 22362
94+
cutoff_time = 30
95+
logfile = server.log
96+
loglevel = 2
97+
debug = true
98+
login_username = examplename
99+
login_pw = examplepassword
100+
threads = auto
101+
secret_key = 'this is my secret key which is hard to guess, i should change this'
102+
#certfile = <path_to.crt>
103+
#keyfile = <path_to.key>
104+
105+
[Task Parameters]
106+
experiment_code_version = 1.0
107+
num_conds = 1
108+
num_counters = 1
109+
110+
[Shell Parameters]
111+
launch_in_sandbox_mode = true
112+
use_psiturk_ad_server = true
113+
ad_location = false
114+
109115

110116
This file is divided into a few sections which are
111117
described in detail. Each field is described by

psiturk/amt_services.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,8 +627,8 @@ def dispose_hit(self, hitid):
627627
try:
628628
self.mtc.dispose_hit(hitid)
629629
except Exception, e:
630-
print 'Failed to dispose of HIT %s. Make sure there are no "\
631-
"assignments remaining to be reviewed' % hitid
630+
print "Failed to dispose of HIT %s. Make sure there are no "\
631+
"assignments remaining to be reviewed." % hitid
632632

633633
def extend_hit(self, hitid, assignments_increment=None,
634634
expiration_increment=None):

psiturk/default_configs/local_config_defaults.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ login_username = examplename
2626
login_pw = examplepassword
2727
threads = auto
2828
secret_key = 'this is my secret key which is hard to guess, i should change this'
29+
#certfile = <path_to.crt>
30+
#keyfile = <path_to.key>
2931

3032
[Task Parameters]
3133
experiment_code_version = 1.0
@@ -34,3 +36,10 @@ num_counters = 1
3436

3537
[Shell Parameters]
3638
launch_in_sandbox_mode = true
39+
40+
# If you are not using the psiturk ad server, set `use_psiturk_ad_server` to `false` and point `ad_location` to your proxy server <host> and <port>. Format the ad_location like this:
41+
#
42+
# https://<host>:<port>/ad
43+
44+
use_psiturk_ad_server = true
45+
ad_location = false
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>Returning to Mechanical Turk</title>
5+
<script>
6+
window.opener.location.reload(true);
7+
window.close();
8+
</script>
9+
</head>
10+
<body>
11+
<h1>Returning to HIT window.</h1>
12+
<p>You are being redirected back to the HIT window, which should refresh.
13+
If you do not see the HIT submission form when you return, try refreshing
14+
the page.</p>
15+
</body>
16+
</html>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<html><head>
2+
<title>Psychology Experiment - Thanks</title>
3+
<link rel="stylesheet" href="/static/css/bootstrap.min.css" type="text/css">
4+
<link rel="stylesheet" href="/static/css/style.css" type="text/css">
5+
<script src="/static/lib/jquery-min.js" type="text/javascript"> </script>
6+
<script>
7+
function complete_amt_task() {
8+
$(window).on('beforeunload', function(){
9+
return 'Your submission is in progress. If you leave now, your assignment data will be corrupted.';
10+
});
11+
$.ajax({
12+
dataType: "json",
13+
type: "GET",
14+
url: "/worker_submitted?uniqueId={{ workerid }}:{{ assignmentid }}",
15+
success: function (data) {
16+
$( "#mturk_form" ).submit();
17+
$(window).off('beforeunload');
18+
}
19+
});
20+
};
21+
</script>
22+
</head>
23+
<body>
24+
<div id="container-ad">
25+
<div class="well">
26+
<h1>Thanks for your participation</h1>
27+
<hr>
28+
29+
<p>To complete the HIT, simply press the button below.</p>
30+
31+
{% if using_sandbox %}
32+
<form style="width: auto;" id="mturk_form" action="https://workersandbox.mturk.com/mturk/externalSubmit" method="post">
33+
{% else %}
34+
<form style="width: auto;" id="mturk_form" action="https://www.mturk.com/mturk/externalSubmit" method="post">
35+
{% endif %}
36+
<input type="hidden" id="assignmentId" name="assignmentId" value="{{ assignmentid }}">
37+
<input type="hidden" id="hitId" name="hitId" value="{{ hitid }}">
38+
<input type="hidden" id="workerId" name="workerId" value="{{ workerid }}">
39+
</form>
40+
41+
<button class="btn btn-success btn-lg" onclick="complete_amt_task();">
42+
Complete HIT
43+
</button>
44+
45+
</div>
46+
47+
</div></body></html>

psiturk/experiment.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -268,16 +268,21 @@ def advertisement():
268268
# them to start the task again.
269269
raise ExperimentError('already_started_exp_mturk')
270270
elif status == COMPLETED:
271-
# They've done the debriefing but perhaps haven't submitted the HIT
272-
# yet.. Turn asignmentId into original assignment id before sending it
273-
# back to AMT
274-
return render_template(
275-
'thanks.html',
276-
is_sandbox=(mode == "sandbox"),
277-
hitid=hit_id,
278-
assignmentid=assignment_id,
279-
workerid=worker_id
280-
)
271+
use_psiturk_ad_server = CONFIG.getboolean('Shell Parameters', 'use_psiturk_ad_server')
272+
if not use_psiturk_ad_server:
273+
# They've finished the experiment but haven't submitted the HIT
274+
# yet.. Turn asignmentId into original assignment id before sending it
275+
# back to AMT
276+
return render_template(
277+
'thanks-mturksubmit.html',
278+
using_sandbox=(mode == "sandbox"),
279+
hitid=hit_id,
280+
assignmentid=assignment_id,
281+
workerid=worker_id
282+
)
283+
else:
284+
# Show them a thanks message and tell them to go away.
285+
return render_template( 'thanks.html' )
281286
elif already_in_db and not debug_mode:
282287
raise ExperimentError('already_did_exp_hit')
283288
elif status == ALLOCATED or not status or debug_mode:
@@ -420,7 +425,8 @@ def start_exp():
420425
if other_assignment:
421426
raise ExperimentError('already_did_exp_hit')
422427

423-
if mode == 'sandbox' or mode == 'live':
428+
use_psiturk_ad_server = CONFIG.getboolean('Shell Parameters', 'use_psiturk_ad_server')
429+
if use_psiturk_ad_server and (mode == 'sandbox' or mode == 'live'):
424430
# If everything goes ok here relatively safe to assume we can lookup
425431
# the ad.
426432
ad_id = get_ad_via_hitid(hit_id)
@@ -566,6 +572,7 @@ def quitter():
566572
return jsonify(**resp)
567573

568574
# Note: This route should only used when debugging
575+
# or when not using the psiturk adserver
569576
@app.route('/complete', methods=['GET'])
570577
@nocache
571578
def debug_complete():
@@ -574,6 +581,10 @@ def debug_complete():
574581
raise ExperimentError('improper_inputs')
575582
else:
576583
unique_id = request.args['uniqueId']
584+
if unique_id[:5] == "debug":
585+
debug_mode = True
586+
else:
587+
debug_mode = False
577588
try:
578589
user = Participant.query.\
579590
filter(Participant.uniqueid == unique_id).one()
@@ -584,7 +595,10 @@ def debug_complete():
584595
except:
585596
raise ExperimentError('error_setting_worker_complete')
586597
else:
587-
return render_template('complete.html')
598+
if debug_mode:
599+
return render_template('complete.html')
600+
else: # send them back to mturk.
601+
return render_template('closepopup.html')
588602

589603
@app.route('/worker_complete', methods=['GET'])
590604
def worker_complete():

0 commit comments

Comments
 (0)