如何通过REST API在Jupyter Notebook终端执行nbgrader评卷命令
实现通过Jupyter Notebook API执行nbgrader自动评阅命令的方案
核心实现思路
Jupyter Server的REST API没有直接执行终端命令的端点,但可以通过终端WebSocket接口完成命令执行,具体步骤如下:
1. 创建终端实例
先调用API创建一个终端,获取终端ID:
import requests token = "你的Jupyter用户token" base_url = "http://xx.xxx.xxx.xx/user/kevin" # 创建终端 create_terminal_url = f"{base_url}/api/terminals" headers = {"Authorization": f"token {token}"} response = requests.post(create_terminal_url, headers=headers) response.raise_for_status() terminal_id = response.json()["name"]
2. 通过WebSocket连接终端并发送命令
Jupyter终端用WebSocket进行实时交互,建立连接后发送命令(需加换行符模拟回车):
import websocket import json import time # 转换为WebSocket地址(http替换为ws) ws_url = f"ws://xx.xxx.xxx.xx/user/kevin/terminals/websocket/{terminal_id}" ws = websocket.WebSocket() ws.connect(ws_url, header={"Authorization": f"token {token}"}) # 发送nbgrader自动评阅命令 command = 'nbgrader autograde "Assignment1"\n' ws.send(json.dumps(["stdin", command])) # 接收命令输出(可根据实际需求调整接收逻辑,比如检测命令完成标识) output = [] try: while True: result = ws.recv() data = json.loads(result) if data[0] in ["stdout", "stderr"]: output.append(data[1]) # 示例:等待30秒后停止接收,实际可根据命令执行时长调整 time.sleep(30) break finally: ws.close() # 输出并返回结果 print("".join(output))
3. 清理终端资源(可选)
执行完命令后删除终端,避免资源占用:
delete_terminal_url = f"{base_url}/api/terminals/{terminal_id}" requests.delete(delete_terminal_url, headers=headers)
替代方案:自定义Jupyter Server扩展
如果WebSocket交互过于繁琐,可以开发轻量扩展:
- 注册新API路由(如
/api/nbgrader/autograde) - 在路由处理函数中用
subprocess执行nbgrader autograde命令 - 直接返回命令输出和状态码给LMS后端,无需处理WebSocket逻辑
注意事项
- 确保教师用户拥有执行nbgrader命令的权限,且Jupyter环境中nbgrader配置正确
- 处理命令执行的超时和异常,避免请求挂起
- 保障token传输和存储的安全性,防止泄露
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

