Skip to content

Deploy to Mechanical Turk or Prolific

This guide provides instructions for deploying a Graph to Mechanical Turk or Prolific.

Prerequisites

  • A Graph.
  • The ability to upload then generate public URLs for files (e.g. via S3)
  • The ability to request ExternalQuestion HITs on Mechanical Turk (e.g. via boto3) and/or Studies on Prolific (e.g. via Prolific's API or website) .
  • An endpoint which accepts and stores JSON data posted from participant browsers located at any of the public URLs mentioned above (e.g. via AWS Lambda function which writes to an S3 bucket). If this endpoint is at a different origin than your file uploads, ensure that the endpoint accepts cross-origin browser POSTs.

1. Build a site from your Graph

Use the nk.build_site function to convert your Graph into a static website; i.e. a folder with an HTML file, the nodekit.js and nodekit.css files, and any assets used by the Graph, such as images and videos.

import nodekit as nk
...
graph = nk.Graph(...)  # put your Graph here
result = nk.build_site(graph=graph, savedir="my-site") 

Of special interest is the HTML file (the "entrypoint"), which the participant will load in their web browser to play the Graph. You may retrieve the relative location of this file in the folder by accessing the .entrypoint property of the result:

1
2
3
4
5
import nodekit as nk
...
graph = nk.Graph(...)  # put your Graph here
result = nk.build_site(graph=graph, savedir="my-site")
print("Entrypoint:", result.entrypoint)      # graphs/<hash>.html
Deploying multiple Graphs?

When building multiple Graphs into deployable sites, one can reduce the total number of files generated by supplying a single savedir when calling nk.build_site on each Graph.

Doing so will allow each Graph entrypoint to share files that they hold in common, such as nodekit.js, nodekit.css, and any Assets.

2. Upload the site to the internet

Sync the entire site_root to your host, preserving paths. If using S3, a typical command is:

aws s3 sync build/my-site s3://your-bucket/task --delete

Ensure you have the URL of the entrypoint HTML, and that it is publicly accessible. This is the link you will be using when requesting an MTurk HIT or Prolific Study in the next step.

3. Deploy to a recruitment platform

The site built by nk.build_site is compatible with Mechanical Turk and Prolific. The built site handles the expected integration logic for each platform, out-of-the-box (e.g. extracting query parameters, POSTing data, redirecting at the right moment, ...), so you do not have to set this up yourself.

However, some configuration might still be needed: the Graph site looks for a nodekitSubmitTo query parameter whose value points to your submission endpoint. This is how the Graph site knows where to POST the participants' Trace data to your server or bucket.

For example, if your entrypoint URL is https://site.com/graphs/568...7f6a.html, and you have an endpoint set up at https://my-endpoint.com, the final URL needs to contain a URL-encoded nodekitSubmitTo query parameter:

https://site.com/graphs/568...7f6a.html?nodekitSubmitTo=https%3A%2F%2Fmy-endpoint.com

You can assemble this URL yourself, but nk.prepare_site_url is the easier way to do it correctly:

import nodekit as nk

entrypoint_url = "https://site.com/graphs/568...7f6a.html"
submit_url = "https://my-endpoint.com"

prepared_url = nk.prepare_site_url(
    site_url=entrypoint_url,
    nodekit_submit_to=submit_url,
)

3a. Request a Mechanical Turk HIT

Mechanical Turk allows ExternalQuestion Assignments to post behavioral data to their backend, where you can later retrieve it. The Graph site automatically submits the Trace data to Mechanical Turk, even if nodekitSubmitTo is not provided. Thus, supplying the nodekitSubmitTo query parameter is optional, if you are using Mechanical Turk.

If you do want NodeKit to also POST the completed submission to your own endpoint, include nodekitSubmitTo in the HIT URL. You can use nk.prepare_site_url to add it:

hit_url = nk.prepare_site_url(
    site_url=entrypoint_url,
    platform="mturk",
    nodekit_submit_to=submit_url,
)

Either way, once you have finalized the URL you will be using, use your preferred method to request an ExternalQuestion HIT which points to the URL. One standard approach might be to use the mturk client provided in boto3.

Maximizing the size of the display on Mechanical Turk

ExternalQuestion HITs on Mechanical Turk are displayed in an iFrame element. It is recommended that you set the ExternalQuestion FrameHeight to 0, which maximizes the size of the iFrame on the participant's web browser.

Running the Graph outside the ExternalQuestion iFrame

If you'd like to have the participant run the Graph in its own page, you could set the ExternalQuestion link to a simple landing page which displays a link to the entrypoint URL of the Graph. If you do this, ensure your landing page attaches all the query parameters that Mechanical Turk adds to the new page, such as the assignmentId query parameter.

3b. Request a Prolific Study

If requesting a Prolific Study, the study URL must include:

  • nodekitSubmitTo. As Prolific does not store participant data, specify the endpoint where you can accept JSON POST messages originating from the participant web page.
  • prolificCompletionCode. Specify the completion code you will use / has been issued when creating the Prolific Draft Study (see link). NodeKit uses this code to construct and redirect to Prolific's completion URL, per Prolific's recommended redirect completion path. Note NodeKit only supports the use of a single Prolific completion code.
  • The three Prolific placeholder parameters: PROLIFIC_PID={{%PROLIFIC_PID%}}, STUDY_ID={{%STUDY_ID%}}, and SESSION_ID={{%SESSION_ID%}}.

Use nk.prepare_site_url to add these query parameters:

study_url = nk.prepare_site_url(
    site_url=entrypoint_url,
    platform="prolific",
    nodekit_submit_to=submit_url,
    prolific_completion_code="YOUR_COMPLETION_CODE",
)

This adds nodekitSubmitTo, prolificCompletionCode, and the Prolific placeholder parameters that Prolific substitutes at runtime for each participant session.

A full example URL for a Prolific Study should look like:

https://my-task.com?nodekitSubmitTo=https%3A%2F%2Fmy-endpoint.com&prolificCompletionCode=1&PROLIFIC_PID={{%PROLIFIC_PID%}}&STUDY_ID={{%STUDY_ID%}}&SESSION_ID={{%SESSION_ID%}}

4. Download the results

Depending on whether you supplied a nodekitSubmitTo endpoint in the previous step, you can expect a JSON document to have been POSTed whenever each participant completed the Graph:

If you did not supply a nodekitSubmitTo endpoint when using Mechanical Turk, you can retrieve the data using the GetAssignment operation and by inspecting the Answer data.

5. Validate results

Once you download the submission payload from the previous step, you can validate the submission data:

import nodekit as nk
from pathlib import Path
import json

data = json.loads(Path('the-data.json').read_text())
site_submission = nk.SiteSubmission.model_validate_json(data)
print(site_submission.platform_context)
print(site_submission.trace)