REST¶
oTree有一个REST API使得外部程序(如其他网站)可与oTree通信。
REST API是一个在你的服务器上被设计用来被其他程序使用的URL,而不是用于在浏览器中手动打开的。
一个使用了很多REST API的项目是 oTree HR。
开始¶
注解
“这些代码应当放在哪里”
这些代码无需包含在你的oTree项目文件夹中。由于REST API的关键就在于使得外部程序和服务器可以与oTree通过网络通信,你应当将这些代码放在其他程序中。这意味着你可以使用在其他服务器上适用的任何语言来编写程序。本页面上的例子使用的是Python,但是使用其他编程语言进行HTTP请求也很简单,如webhooks工具或者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¶
注解
在2021年3月新引入的beta特性。
GET URL: /api/otree_version/
例子¶
data = call_api(GET, 'otree_version')
# returns: {'version': '5.0.0'}
“Session configs” endpoint¶
注解
在2021年3月新引入的beta特性。
GET URL: /api/session_configs/
返回所有session config组成的列表,使用字典存储它们的所有属性。
例子¶
data = call_api(GET, 'session_configs')
pprint(data)
“Rooms” endpoint¶
注解
在2021年3月新引入的beta特性。
GET URL: /api/rooms/
例子¶
data = call_api(GET, 'rooms')
pprint(data)
示例输出(注意它包含了 session_code
,如果房间中当前存在一个会话的话):
[{'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'}]
“Create sessions” endpoint¶
POST URL: /api/sessions/
下面是一些”create sessions”路径应当如何使用的例子:
- 其他网站可自动创建oTree会话
- 你可以自己创造一个更好看的oTree 配置会话 界面(例如加上侧边栏和控件)
- 在某些固定时刻创建oTree会话的进程
- 创建自定义会话的命令行脚本(如果
otree create_session
不够用的话)
例子¶
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)
“Get session data” endpoint¶
注解
2021年3月引入的新特性。将处于测试阶段直到获取足够的用户反馈。
GET URL: /api/sessions/{code}
此API将取回关于会话及其参与人的数据。如果略去 participant_labels
,那么将返回所有参与人的数据。
例子¶
data = call_api(GET, 'sessions', 'vfyqlw1q', participant_labels=['Alice'])
pprint(data)
“Session vars” endpoint¶
注解
在2021年4月,这一路径要求你传入会话代码作为路径参数。如果会话在房间中的话,你可以通过 rooms
路径获得会话代码。
POST URL: /api/session_vars/{session_code}
这一路径使你可以设置 session.vars
。一种用途是实验输入。举例来说,如果实验中有一次抽奖,就可以通过运行下面的脚本来输入结果。
例子¶
call_api(POST, 'session_vars', 'vfyqlw1q', vars=dict(dice_roll=4))
“Participant vars” endpoint¶
POST URL: /api/participant_vars/{participant_code}
通过 web services / webhooks 将参与人的信息传递给oTree。
例子¶
call_api(POST, 'participant_vars', 'vfyqlw1q', vars=dict(birth_year='1995', gender='F'))
“Participant vars for room” endpoint¶
POST URL: /api/participant_vars/
类似于”participant vars”路径,但这一API可在你不知道参与人代码时使用。你可以通过房间的名字以及参与人标签来指定参与人。
例子¶
call_api(
POST,
'participant_vars',
room_name='qualtrics_study',
participant_label='albert_e',
vars=dict(age=25, is_male=True, x=[3, 6, 9]),
)
参数¶
room_name
(必要)participant_label
(必要)vars
(必要): 用于加入participant vars的字典, 其中值必须是可被JSON序列化的数据类型, 甚至可以是嵌套的字典/列表。
你需要给参与人一个带 participant_label
的链接,尽管它不必包含在 participant_label_file
中。
认证¶
如果你将你的验证等级从DEMO改为STUDY,你必须验证你的REST API请求。
在服务器上创建一个环境变量(即 Heroku config var) OTREE_REST_KEY
。将其设置为某个秘密值。
在发送请求时,在HTTP header里将其添加为 otree-rest-key
。如果按照上面的 例子 ,你应当设置 REST_KEY
变量。
演示 & 测试¶
为在开发时更便利,你可以在一个真实的会话中生成假的vars来模拟从REST API获得的数据。
在你的session config中,添加参数 mock_exogenous_data=True
(称其为 exogenous(外源性) 数据是因为其是在oTree外部生成的。)
然后在你的项目的shared_out.py中(如果你使用的是文本编辑器,你可能需要创建此文件)定义一个同名函数(mock_exogenous_data
)。
下面是一个例子:
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
你也可以在此处设置参与人标签。
当你的会话运行在demo模式下,或者使用bot, mock_exogenous_data()
会在 creating_session
之后自动运行。然而,如果是在房间里创建的会话则不会运行。
如果你有多个session config需要不同的外源性数据,你可以像下面这样区分它们:
def mock_exogenous_data(session):
if session.config['name'] == 'whatever':
...
if 'xyz' in session.config['app_sequence']:
...