如何通过UI按钮触发后端运行Jupyter Notebook?(拟用Flask)
实现Flask后端触发Jupyter Notebook执行的方案
一、基础Flask后端搭建
先创建核心Flask应用,处理前端按钮的POST请求:
from flask import Flask, request, jsonify import subprocess import os app = Flask(__name__) # 指定允许执行的笔记本路径(硬编码或配置文件,避免路径遍历风险) ALLOWED_NOTEBOOK = os.path.abspath("./target_notebook.ipynb") @app.route('/run-notebook', methods=['POST']) def run_notebook(): try: # 用nbconvert直接执行笔记本并捕获输出 result = subprocess.run( ["jupyter", "nbconvert", "--to", "script", "--execute", ALLOWED_NOTEBOOK, "--stdout"], capture_output=True, text=True, check=True # 执行出错时主动抛出异常 ) return jsonify({ "status": "success", "output": result.stdout }) except subprocess.CalledProcessError as e: return jsonify({ "status": "error", "message": e.stderr }), 500 except Exception as e: return jsonify({ "status": "error", "message": str(e) }), 500 if __name__ == '__main__': app.run(debug=True) # 生产环境务必关闭debug模式
二、前端按钮绑定请求
在你的HTML中给目标按钮添加点击事件,用Fetch API发送请求:
<button id="runNotebookBtn">运行Jupyter Notebook</button> <div id="executionResult"></div> <script> document.getElementById('runNotebookBtn').addEventListener('click', async () => { const btn = event.target; btn.disabled = true; btn.textContent = "运行中..."; try { const response = await fetch('/run-notebook', { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const data = await response.json(); const resultDiv = document.getElementById('executionResult'); if (data.status === 'success') { resultDiv.innerHTML = `<pre>${data.output}</pre>`; } else { resultDiv.innerHTML = `<p style="color: red;">执行失败:${data.message}</p>`; } } catch (err) { document.getElementById('executionResult').innerHTML = `<p style="color: red;">请求出错:${err.message}</p>`; } finally { btn.disabled = false; btn.textContent = "运行Jupyter Notebook"; } }); </script>
三、依赖安装
确保环境安装了必要的包:
pip install flask jupyter nbconvert
四、安全与优化建议
- 路径安全:绝对不要让前端传递笔记本路径,用硬编码或白名单机制,防止攻击者遍历服务器文件系统。
- 权限控制:运行Flask的用户权限要最小化,禁用root账号启动服务,降低恶意代码执行的风险。
- 异步处理:如果笔记本运行时间较长,建议用Celery等异步任务队列,避免阻塞Flask主线程,前端可通过轮询或WebSocket获取执行状态。
- CSRF防护:生产环境启用Flask的CSRF保护(比如借助
flask-wtf),防止跨站请求伪造。 - 输出截断:若笔记本输出过大,不要直接返回全部内容,可只返回执行状态和关键日志,或把输出写入文件后提供下载链接。
内容的提问来源于stack exchange,提问作者Coding Geeek
相关产品推荐
相关产品推荐

