表題の通り、LRSとしてLearning Lockerを使うことになったので、まずはPythonでのデータ(ステートメント)の登録方法など。一般的には、MoodleなどのLMSからLRSに送るので、コードでガリガリということはあまりないと思いますが・・・。
留意点としては(Learning Lockerを前提にしていますが)、
- エンドポイントのportは8081
- usernameとかpasswordは、Learning Lockerにある管理画面のKey, Secretなどが該当
- headerには"X-Experience-API-Version"が必須
というところですね。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import json | |
from datetime import datetime, timezone | |
from base64 import b64encode | |
# Learning Locker LRS のエンドポイント情報 | |
LRS_ENDPOINT = "http://localhost:8081/data/xAPI/statements" | |
LRS_USERNAME = "xxxxxxx" | |
LRS_PASSWORD = "xxxxxx" | |
# Basic認証ヘッダーの作成 | |
def get_auth_header(): | |
auth_string = f"{LRS_USERNAME}:{LRS_PASSWORD}" | |
auth_encoded = b64encode(auth_string.encode()).decode() | |
return {"Authorization": f"Basic {auth_encoded}"} | |
# xAPI ステートメントの作成 | |
def create_xapi_statement(): | |
statement = { | |
"actor": { | |
"mbox": "mailto:example@example.com", | |
"name": "John Doe", | |
"objectType": "Agent" | |
}, | |
"verb": { | |
"id": "http://adlnet.gov/expapi/verbs/completed", | |
"display": {"en-US": "completed"} | |
}, | |
"object": { | |
"id": "http://example.com/activities/lesson1", | |
"definition": { | |
"name": {"en-US": "Lesson 1"}, | |
"description": {"en-US": "The first lesson"} | |
}, | |
"objectType": "Activity" | |
}, | |
"timestamp": datetime.now(timezone.utc).isoformat() | |
} | |
return statement | |
# xAPI ステートメントの送信 | |
def send_xapi_statement(): | |
headers = { | |
"Content-Type": "application/json", | |
"X-Experience-API-Version": "1.0.3", #これが必要です | |
**get_auth_header() | |
} | |
statement = create_xapi_statement() | |
response = requests.post(LRS_ENDPOINT, headers=headers, json=statement) | |
if response.status_code == 200 or response.status_code == 204: | |
print("xAPI ステートメントが正常に送信されました。") | |
else: | |
print(f"エラー: {response.status_code}, {response.text}") | |
if __name__ == "__main__": | |
send_xapi_statement() |