REST¶
oTreeには、外部プログラム(他のWebサイトなど)がoTreeと通信できるようにする REST API があります。
REST APIは、プログラムからアクセスできるように設計されたサーバー上の単なるURLです。
REST APIを頻繁に使用するプロジェクトの1つは、 oTree HR です。
セットアップ¶
注釈
「このコードはどこに配置すればいいですか」
このコードは、oTreeプロジェクトフォルダー内に配置する必要はありません。REST APIのポイントは、外部プログラムとサーバーがインターネットを介してoTreeと通信できるようにすることであるため、このコードを他のプログラムに配置する必要があります。これは、他のサーバーが使用する言語を使用しなければならないことも意味します。このページの例ではPythonを使用していますが、WebhookやcURLなどのツールの利用や他の言語によってHTTPリクエストを作成するのも簡単です。
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" エンドポイント¶
注釈
2021年3月現在の新しいベータ機能。
GET URL: /api/otree_version/
例:¶
data = call_api(GET, 'otree_version')
# returns: {'version': '5.0.0'}
"Session configs" エンドポイント¶
注釈
2021年3月現在の新しいベータ機能。
GET URL: /api/session_configs/
すべてのセッション構成のリストをすべてのプロパティを含む辞書型として返します。
例:¶
data = call_api(GET, 'session_configs')
pprint(data)
"Rooms" エンドポイント¶
注釈
2021年3月現在の新しいベータ機能。
GET URL: /api/rooms/
例:¶
data = call_api(GET, 'rooms')
pprint(data)
出力例(現在、roomにセッションがある場合、 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" エンドポイント¶
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" エンドポイント¶
注釈
2021年3月現在の新機能。十分なユーザーフィードバックが得られるまでベータ版です。
GET URL: /api/sessions/{code}
このAPIは、セッションとその参加者に関するデータを取得します。 participant_labels
を省略した場合、すべての参加者のデータを返します。
例:¶
data = call_api(GET, 'sessions', 'vfyqlw1q', participant_labels=['Alice'])
pprint(data)
"Session vars" エンドポイント¶
注釈
2021年4月の時点で、このエンドポイントでは、パスのパラメータとしてセッションコードを渡す必要があります。room内にセッションがある場合は、 rooms
エンドポイントでセッションコードを取得できます。
POST URL: /api/session_vars/{session_code}
このエンドポイントでは、 session.vars
を設定できます。1つの用途は実験者の入力です。例えば、実験の途中で抽選を行った場合、以下のようなスクリプトを実行して結果を入力することができます。
例:¶
call_api(POST, 'session_vars', 'vfyqlw1q', vars=dict(dice_roll=4))
"Participant vars" エンドポイント¶
POST URL: /api/participant_vars/{participant_code}
WebサービスやWebhookを介して、参加者に関する情報をoTreeに渡します。
例:¶
call_api(POST, 'participant_vars', 'vfyqlw1q', vars=dict(birth_year='1995', gender='F'))
"Participant vars for room" エンドポイント¶
POST URL: /api/participant_vars/
他の "participant vars" エンドポイントと同様ですが、参加者のコードがない場合にも使用できます。参加者のコードの代わりに、room名と参加者ラベルで参加者を識別します。
例:¶
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_file
から取得する必要はありませんが、参加者に participant_label
とともにリンクを与える必要があります。
認証¶
認証レベルをDEMOまたはSTUDYに設定している場合は、REST APIリクエストを認証する必要があります。
サーバー上に環境変数(つまり、Heroku config var) OTREE_REST_KEY
を作成してください。値を秘密の値として設定して下さい。
リクエストを行うときは、そのキーを otree-rest-key
と呼ばれるHTTPヘッダーとして追加してください。上記の 設定例 に従う場合は、 REST_KEY
変数を設定します。
デモとテスト¶
開発を快適にするために、偽の変数を生成し、実際のセッションでREST APIから取得されるデータをシミュレートできます。
セッション構成で、パラメーター mock_exogenous_data=True
を追加してください。(oTreeの外部で発生するため、「exogenous」データと呼んでいます。)
次に、プロジェクトの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
ここで参加者ラベルを設定することもできます。
デモモードまたはボットを使用してセッションを実行すると、 mock_exogenous_data()
は creating_session
の後、自動的に実行されます。ただし、セッションがroomで作成されている場合は実行されません。
異なるexogenousデータを必要とする複数のセッション構成がある場合は、次のように分岐できます。
def mock_exogenous_data(session):
if session.config['name'] == 'whatever':
...
if 'xyz' in session.config['app_sequence']:
...