REST

oTree tiene una API REST que permite a programas externos (como otros sitios web) comunicarse con oTree.

Una API REST es simplemente una URL en tu servidor que está diseñada para ser accedida por programas, en lugar de ser abierta manualmente en un navegador web.

One project that uses the REST API a lot is oTree HR.

Configuración

Nota

«¿Dónde debo poner este código?»

Este código no necesita estar dentro de tu carpeta del proyecto oTree. Dado que el objetivo de la API REST es permitir que programas y servidores externos se comuniquen con oTree a través de Internet, debes colocar este código en ese otro programa. Esto también significa que debes usar el lenguaje que utilice ese otro servidor. Los ejemplos en esta página utilizan Python, pero es sencillo realizar solicitudes HTTP utilizando cualquier lenguaje de programación, o herramientas como webhooks o cURL.

import requests  # pip3 install requests
from pprint import pprint


GET = requests.get
POST = requests.post

# if using Heroku, change this to https://YOURAPP.herokuapp.com
SERVER_URL = 'http://localhost:8000'
REST_KEY = ''  # fill this later

def call_api(method, *path_parts, **params) -> dict:
    path_parts = '/'.join(path_parts)
    url = f'{SERVER_URL}/api/{path_parts}/'
    resp = method(url, json=params, headers={'otree-rest-key': REST_KEY})
    if not resp.ok:
        msg = (
            f'Request to "{url}" failed '
            f'with status code {resp.status_code}: {resp.text}'
        )
        raise Exception(msg)
    return resp.json()

«oTree version» endpoint

GET URL: /api/otree_version/

Ejemplo

data = call_api(GET, 'otree_version')
# returns: {'version': '5.0.0'}

«Session configs» endpoint

GET URL: /api/session_configs/

Devuelve la lista de todas tus session configs, como diccionarios con todas sus propiedades.

Ejemplo

data = call_api(GET, 'session_configs')
pprint(data)

«Rooms» endpoint

GET URL: /api/rooms/

Ejemplo

data = call_api(GET, 'rooms')
pprint(data)

Ejemplo de salida (tenga en cuenta que incluye session_code si actualmente hay una sesión en la sala):

[{'name': 'my_room',
  'session_code': 'lq3cxfn2',
  'url': 'http://localhost:8000/room/my_room'},
 {'name': 'live_demo',
  'session_code': None,
  'url': 'http://localhost:8000/room/live_demo'}]

Endpoint de «Crear sesiones»

URL POST: /api/sessions/

Aquí hay algunos ejemplos de cómo se puede utilizar el endpoint de «crear sesiones»:

  • Otros sitios web pueden crear sesiones de oTree automáticamente

  • Puedes crear una alternativa más elaborada a la interfaz de Configurar sesiones de oTree (por ejemplo, con deslizadores y widgets visuales)

  • Proceso que creará nuevas sesiones de oTree en un horario fijo

  • Script de línea de comandos para crear sesiones personalizadas (si otree create_session no es suficiente)

Ejemplo

data = call_api(
    POST,
    'sessions',
    session_config_name='trust',
    room_name='econ101',
    num_participants=4,
    modified_session_config_fields=dict(num_apples=10, abc=[1, 2, 3]),
)
pprint(data)

Parámetros

  • session_config_name (requerido)

  • num_participants (requerido)

  • modified_session_config_fields: un diccionario opcional de parámetros de configuración de sesión, como se discutió en Configurar sesiones.

  • room_name si deseas crear la sesión en una sala.

endpoint de «Get session data»

GET URL: /api/sessions/{code}

Esta API recupera datos sobre una sesión y sus participantes. Si se omite participant_labels, devuelve datos para todos los participantes.

Ejemplo

data = call_api(GET, 'sessions', 'vfyqlw1q', participant_labels=['Alice'])
pprint(data)

«Session vars» endpoint

Nota

A partir de abril de 2021, este endpoint requiere que pases un código de sesión como parámetro de ruta. Si la sesión está en una sala, puedes obtener el código de sesión con el endpoint rooms.

POST URL: /api/session_vars/{session_code}

Este endpoint te permite establecer session.vars. Un uso es la entrada del experimentador. Por ejemplo, si el experimentador realiza un sorteo en medio del experimento, puede introducir el resultado ejecutando un script como el siguiente.

Ejemplo

call_api(POST, 'session_vars', 'vfyqlw1q', vars=dict(dice_roll=4))

«Participant vars» endpoint

POST URL: /api/participant_vars/{participant_code}

Pasa información sobre un participante a oTree, a través de servicios web / webhooks.

Ejemplo

call_api(POST, 'participant_vars', 'vfyqlw1q', vars=dict(birth_year='1995', gender='F'))

«Participant vars for room» endpoint

POST URL: /api/participant_vars/

Similar al otro endpoint de «participant vars», pero este se puede utilizar cuando no tienes el código del participante. En su lugar, identificas al participante por el nombre de la sala y su etiqueta de participante.

Ejemplo

call_api(
    POST,
    'participant_vars',
    room_name='qualtrics_study',
    participant_label='albert_e',
    vars=dict(age=25, is_male=True, x=[3, 6, 9]),
)

Parámetros

  • room_name (requerido)

  • participant_label (requerido)

  • vars (requerido): un diccionario de participant vars para agregar. Los valores pueden ser cualquier tipo de dato que se pueda serializar en JSON, incluso diccionarios/listas anidados.

Necesitarás proporcionar a los participantes un enlace con un participant_label, aunque no es necesario que provenga de un participant_label_file.

Autenticación

Si has configurado tu nivel de autenticación en DEMO o STUDY, debes autenticar tus solicitudes de la API REST.

Crea una variable de entorno (es decir, una variable de configuración de Heroku) OTREE_REST_KEY en el servidor. Establece un valor secreto.

Cuando realices una solicitud, añade esa clave como un encabezado HTTP llamado otree-rest-key. Si sigues el ejemplo de configuración anterior, deberías establecer la variable REST_KEY.

Demostración y pruebas

Para mayor comodidad durante el desarrollo, puedes generar vars falsas para simular datos que, en una sesión real, provendrán de la REST API.

En la configuración de tu sesión, añade el parámetro mock_exogenous_data=True (Lo llamamos datos exógenos porque provienen de fuera de oTree).

Luego define una función con el mismo nombre (mock_exogenous_data) en el archivo shared_out.py de tu proyecto (si estás utilizando un editor de texto, es posible que necesites crear ese archivo).

Aquí hay un ejemplo:

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

También puedes establecer etiquetas de participante aquí.

Cuando ejecutas una sesión en modo de demostración, o utilizando bots, mock_exogenous_data() se ejecutará automáticamente después de creating_session. Sin embargo, no se ejecutará si la sesión se crea en una sala.

Si tienes múltiples configuraciones de sesión que requieren diferentes datos exógenos, puedes ramificarte así:

def mock_exogenous_data(session):
    if session.config['name'] == 'whatever':
        ...
    if 'xyz' in session.config['app_sequence']:
        ...