You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过点击HTML网页按钮在后端运行Jupyter Notebook?

通过前端按钮触发后端运行Jupyter Notebook的实现方案

方案1:基于Python Web框架(Flask/FastAPI)封装执行逻辑

这是最灵活的方案,适合需要自定义业务逻辑、处理执行结果的场景。

操作步骤:

  1. 安装依赖
    先安装所需的Python库:

    pip install flask nbclient nbformat flask-cors
    
    • flask:搭建Web后端接口
    • nbclient:以编程方式执行Jupyter Notebook
    • nbformat:解析和处理Notebook文件格式
    • flask-cors:解决前后端跨域问题(若前后端分离部署)
  2. 编写Flask后端代码
    创建app.py文件,实现接收前端请求、执行Notebook的接口:

    from flask import Flask, jsonify
    from flask_cors import CORS
    from nbformat import read, NO_CONVERT
    from nbclient import NotebookClient
    
    app = Flask(__name__)
    CORS(app)  # 允许跨域请求
    
    @app.route('/run-notebook', methods=['POST'])
    def run_notebook():
        try:
            # 读取目标Notebook文件
            with open('your_notebook.ipynb', 'r', encoding='utf-8') as f:
                nb = read(f, NO_CONVERT)
            
            # 配置并执行Notebook
            client = NotebookClient(nb, timeout=600, kernel_name='python3')
            client.execute()
    
            # 收集执行结果(可选,按需处理)
            outputs = []
            for cell in nb.cells:
                if hasattr(cell, 'outputs') and cell.outputs:
                    for output in cell.outputs:
                        if output.output_type == 'stream':
                            outputs.append(output.text)
                        elif output.output_type == 'execute_result':
                            outputs.append(str(output.data.get('text/plain', '')))
            
            return jsonify({'status': 'success', 'outputs': outputs}), 200
        except Exception as e:
            return jsonify({'status': 'error', 'message': str(e)}), 500
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000, debug=True)
    
  3. 编写前端页面
    创建index.html,添加按钮并绑定点击事件:

    <!DOCTYPE html>
    <html>
    <head>
        <title>运行Jupyter Notebook</title>
        <style>
            #runNotebookBtn {
                padding: 10px 20px;
                font-size: 16px;
                cursor: pointer;
                background-color: #4CAF50;
                color: white;
                border: none;
                border-radius: 4px;
            }
            #runNotebookBtn:hover {
                background-color: #45a049;
            }
            #result {
                margin-top: 20px;
                padding: 10px;
                border: 1px solid #ccc;
                border-radius: 4px;
                min-height: 50px;
            }
        </style>
    </head>
    <body>
        <button id="runNotebookBtn">运行Jupyter笔记本</button>
        <div id="result"></div>
    
        <script>
            const btn = document.getElementById('runNotebookBtn');
            const resultDiv = document.getElementById('result');
    
            btn.addEventListener('click', async () => {
                btn.disabled = true;
                btn.textContent = '运行中...';
                resultDiv.textContent = '';
    
                try {
                    const response = await fetch('http://localhost:5000/run-notebook', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        }
                    });
                    const data = await response.json();
    
                    if (data.status === 'success') {
                        resultDiv.textContent = '执行成功!输出结果:\n' + data.outputs.join('\n');
                    } else {
                        resultDiv.textContent = '执行失败:' + data.message;
                    }
                } catch (error) {
                    resultDiv.textContent = '请求出错:' + error.message;
                } finally {
                    btn.disabled = false;
                    btn.textContent = '运行Jupyter笔记本';
                }
            });
        </script>
    </body>
    </html>
    
  4. 运行测试

    • 启动Flask后端:python app.py
    • 打开index.html页面,点击按钮即可触发Notebook执行。

方案2:直接调用Jupyter Server的REST API

利用Jupyter自带的官方API,无需额外封装执行逻辑,适合快速搭建场景。

操作步骤:

  1. 启动带API访问的Jupyter Server
    测试环境启动命令(生产环境必须设置token/密码):

    jupyter notebook --port=8888 --NotebookApp.token='' --NotebookApp.password='' --allow-origin='*'
    
    • --allow-origin='*':允许跨域请求(生产环境建议指定具体域名)
  2. 前端调用API执行Notebook
    修改前端JS代码,通过Jupyter API完成执行流程:

    <script>
        const btn = document.getElementById('runNotebookBtn');
        const resultDiv = document.getElementById('result');
        const baseUrl = 'http://localhost:8888/api';
    
        btn.addEventListener('click', async () => {
            btn.disabled = true;
            btn.textContent = '运行中...';
            resultDiv.textContent = '';
    
            try {
                // 1. 创建Python内核
                const kernelResp = await fetch(`${baseUrl}/kernels`, {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({name: 'python3'})
                });
                const kernel = await kernelResp.json();
                const kernelId = kernel.id;
    
                // 2. 获取Notebook内容
                const nbResp = await fetch(`${baseUrl}/contents/your_notebook.ipynb`);
                const nbData = await nbResp.json();
                const cells = nbData.content.cells;
    
                // 3. 逐个执行单元格
                const outputs = [];
                for (const cell of cells) {
                    if (cell.cell_type === 'code') {
                        const execResp = await fetch(`${baseUrl}/kernels/${kernelId}/execute`, {
                            method: 'POST',
                            headers: {'Content-Type': 'application/json'},
                            body: JSON.stringify({code: cell.source})
                        });
                        const execResult = await execResp.json();
                        outputs.push(`单元格输出:${JSON.stringify(execResult.content)}`);
                    }
                }
    
                // 4. 关闭内核(可选)
                await fetch(`${baseUrl}/kernels/${kernelId}`, {method: 'DELETE'});
    
                resultDiv.textContent = '执行成功!输出结果:\n' + outputs.join('\n');
            } catch (error) {
                resultDiv.textContent = '请求出错:' + error.message;
            } finally {
                btn.disabled = false;
                btn.textContent = '运行Jupyter笔记本';
            }
        });
    </script>
    
  3. 注意事项

    • 生产环境必须配置Jupyter的认证机制(token或密码),避免未授权访问
    • Jupyter API的详细文档可通过启动后的http://localhost:8888/docs查看

方案3:通过nbconvert命令行工具批量执行

适合仅需运行Notebook并生成输出文件(如HTML、PDF),无需实时获取执行结果的场景。

操作步骤:

  1. 安装nbconvert

    pip install nbconvert
    
  2. 编写后端接口(以Flask为例)
    修改app.py中的接口,用subprocess调用nbconvert命令:

    from flask import Flask, jsonify
    from flask_cors import CORS
    import subprocess
    import os
    
    app = Flask(__name__)
    CORS(app)
    
    @app.route('/run-notebook', methods=['POST'])
    def run_notebook():
        try:
            notebook_path = 'your_notebook.ipynb'
            output_path = 'output.html'
    
            # 执行nbconvert命令,运行Notebook并生成HTML输出
            subprocess.run(
                ['jupyter', 'nbconvert', '--execute', '--to', 'html', notebook_path, '--output', output_path],
                check=True,
                capture_output=True,
                text=True
            )
    
            # 检查输出文件是否生成
            if os.path.exists(output_path):
                return jsonify({'status': 'success', 'output_file': output_path}), 200
            else:
                return jsonify({'status': 'error', 'message': '输出文件未生成'}), 500
        except subprocess.CalledProcessError as e:
            return jsonify({'status': 'error', 'message': f'命令执行失败:{e.stderr}'}), 500
        except Exception as e:
            return jsonify({'status': 'error', 'message': str(e)}), 500
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000, debug=True)
    
  3. 前端处理结果
    前端可以在请求成功后,通过链接下载生成的输出文件:

    // 在fetch成功的分支添加
    if (data.status === 'success') {
        const downloadLink = document.createElement('a');
        downloadLink.href = data.output_file;
        downloadLink.download = 'notebook_output.html';
        downloadLink.textContent = '点击下载执行结果';
        resultDiv.innerHTML = '执行成功!';
        resultDiv.appendChild(downloadLink);
    }
    

内容的提问来源于stack exchange,提问作者Coding Geeek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 20:57:06