REST¶
oTree has a small REST API that enables external programs (such as other websites) to communicate with oTree, in particular:
- Create sessions
- Add participant vars
- Add session vars
A REST API is just a URL on your server that is designed to be accessed by programs, rather than being opened manually in a web browser.
Simply make a request to one of the below URLs.
“Create sessions” REST endpoint¶
POST URL: /api/sessions/
Here are some examples of how the “create sessions” endpoint can be used:
- Other websites can create oTree sessions automatically
- You can make a fancier alternative to oTree’s Configure sessions interface (e.g. with sliders and visual widgets)
- Process that will create new oTree sessions on some fixed schedule
- Command line script to create customized sessions
(if
otree create_session
is not sufficient)
Example¶
import requests # pip3 install requests
def create_session(**payload):
resp = requests.post(SERVER_URL + '/api/sessions/', json=payload)
resp.raise_for_status() # ensure it succeeded
return resp
resp = create_session(session_config_name='trust', room_name='econ101', num_participants=4, modified_session_config_fields=dict(num_apples=10, abc=[1, 2, 3]))
print(resp.text) # returns the session code
Note
“Where should I put this code?”
This code does not need to go inside your oTree project folder. Since the point of the REST API is to allow external programs and servers to communicate with oTree across the internet, you should put this code in that other program. That also means you should use whatever language that other server uses. The examples on this page use Python, but it’s simple to make HTTP requests using any programming language, or tools like webhooks or cURL.
Parameters¶
session_config_name
(required)num_participants
(required)modified_session_config_fields
: an optional dict of session config parameters, as discussed in Configure sessions.room_name
if you want to create the session in a room.
“Participant vars” REST endpoint¶
POST URL: /api/participant_vars/
This endpoint lets you set participant.vars
.
The main purpose is to allow other sites/apps to pass information about a participant to oTree,
via web services / webhooks.
For example, if the user does a survey on Qualtrics that then links to oTree,
you can pass their survey data (like gender, age, etc) into oTree as participant vars.
(Qualtrics allows making POST requests through their web service
feature.)
Example¶
import requests
def set_participant_vars(**payload):
resp = requests.post(SERVER_URL + '/api/participant_vars/', json=payload)
return resp
resp = set_participant_vars(room_name='qualtrics_study', participant_label='albert_e', vars=dict(age=25, is_male=True, x=[3,6,9]))
print(resp.text)
Parameters¶
room_name
(required)participant_label
(required)vars
(required): a dict of participant vars to add. Values can be any JSON-serializable data type, even nested dicts/lists.
This feature requires you to use a Room.
Participants are uniquely identified with the combination of room name & participant label.
So you will need to give participants a link with a participant_label
,
although this does not need to come from a participant_label_file
.
“Session vars” REST endpoint¶
POST URL: /api/session_vars/
This endpoint lets you set session.vars
.
One use is experimenter input.
For example, if the experimenter does a lottery drawing in the middle of the experiment,
they can input the result by running a script like the one below.
Example¶
def set_session_vars(**payload):
return requests.post(SERVER_URL + "/api/session_vars/", json=payload)
resp = set_session_vars(
room_name="my_room",
vars=dict(dice_roll=4),
)
Parameters¶
room_name
(required)vars
(required): a dict of session vars to add.
This feature requires you to use a Room.
Note¶
If you are using this for experimenter input during an experiment, you may also want to use error_message:
def error_message(player, values):
session = player.session
if 'dice_roll' not in session.vars:
return 'You must wait until the dice roll before proceeding'
Authentication¶
If you have set your auth level to DEMO or STUDY, you must authenticate your REST API requests.
Create an env var (i.e. Heroku config var) OTREE_REST_KEY
on the server. Set it to some secret value.
When you make a request, add that key as an HTTP header called otree-rest-key
.
For example:
import requests
REST_KEY = 'your_key'
def create_session(**payload):
resp = requests.post(SERVER_URL + '/api/sessions/', json=payload,
headers={'otree-rest-key': REST_KEY}
)
return resp
resp = create_session(session_config_name='trust', room_name='econ101', num_participants=4, modified_session_config_fields=dict(num_apples=10, abc=[1, 2, 3]))
print(resp.text) # returns the session code
Demo & testing¶
For convenience during development, you can generate fake vars to simulate data that, in a real session, will come from the REST API.
In your session config, add the parameter mock_exogenous_data=True
(We call it exogenous data because it originates outside oTree.)
Then define a function with the same name (mock_exogenous_data
)
in your project’s shared_out.py (if you are using a text editor,
you may need to create that file).
Here’s an example:
def mock_exogenous_data(session):
participants = session.get_participants()
for pp in participants:
pp.vars.update(age=20, is_male=True) # or make it random
You can also set participant labels here.
When you run a session in demo mode, or using bots, mock_exogenous_data()
will automatically be run after creating_session
. However, it will not be run
if the session is created in a room.
If you have multiple session configs that require different exogenous data, you can branch like this:
def mock_exogenous_data(session):
if session.config['name'] == 'whatever':
...
if 'xyz' in session.config['app_sequence']:
...