如何实现Next.js应用上传PDF至Jupyter Notebook并展示LLM摘要?
解决方案:Next.js + PDF摘要后端服务搭建
一、Jupyter Notebook的改造与部署
直接运行Jupyter Notebook无法和前端高效通信,建议将Notebook的核心逻辑封装成HTTP API服务,两种主流方案如下:
1. 转成FastAPI/Flask服务(推荐)
把Notebook中处理PDF、调用LLM生成摘要的代码提取为独立Python函数,再用FastAPI封装成接口,灵活性和性能最优。
- 步骤:
- 从Notebook导出核心逻辑:编写
generate_pdf_summary(pdf_content)函数,负责读取PDF二进制数据、调用LLM生成摘要。 - 编写FastAPI接口:创建
main.py,实现接收PDF文件的POST接口,配置CORS解决跨域问题。 - 部署:用Docker打包服务,部署到云服务器(EC2、阿里云ECS)或者轻量平台(Render、Fly.io)。
- 从Notebook导出核心逻辑:编写
2. 使用Jupyter Kernel Gateway(快速迁移)
如果不想大幅修改Notebook代码,可以用该工具将Notebook直接转成REST API:
- 步骤:
- 安装依赖:
pip install jupyter_kernel_gateway - 在Notebook单元格开头用注释标记API端点,比如
# POST /summarize-pdf,然后编写处理请求的代码(读取PDF文件、生成摘要)。 - 启动服务:
jupyter kernelgateway --KernelGatewayApp.api='notebook' --KernelGatewayApp.notebook='your_notebook.ipynb'
- 安装依赖:
- 注意:适合快速原型,但长期维护性和性能不如FastAPI。
二、Next.js与后端的通信实现
前端通过FormData上传PDF文件,调用后端API获取摘要,核心代码示例如下:
前端(Next.js)示例
'use client' import { useState } from 'react' export default function PdfSummarizer() { const [selectedFile, setSelectedFile] = useState(null) const [summary, setSummary] = useState('') const [loading, setLoading] = useState(false) const handleFileChange = (e) => { setSelectedFile(e.target.files[0]) } const handleSubmit = async () => { if (!selectedFile) return setLoading(true) setSummary('') const formData = new FormData() formData.append('file', selectedFile) try { const res = await fetch('http://你的后端域名/api/summarize-pdf', { method: 'POST', body: formData, }) const data = await res.json() setSummary(data.summary) } catch (err) { console.error('摘要生成失败:', err) setSummary('生成失败,请检查文件或重试') } finally { setLoading(false) } } return ( <div className="max-w-md mx-auto p-6"> <h1 className="text-2xl font-bold mb-4">PDF摘要生成器</h1> <input type="file" accept=".pdf" onChange={handleFileChange} className="mb-4 block" /> <button onClick={handleSubmit} disabled={loading || !selectedFile} className="bg-blue-500 text-white px-4 py-2 rounded" > {loading ? '生成中...' : '生成摘要'} </button> {summary && ( <div className="mt-6 p-4 bg-gray-50 rounded"> <h2 className="font-semibold mb-2">摘要内容:</h2> <p>{summary}</p> </div> )} </div> ) }
后端(FastAPI)示例
from fastapi import FastAPI, File, UploadFile from fastapi.middleware.cors import CORSMiddleware # 导入你从Notebook中提取的摘要生成函数 from pdf_processor import generate_pdf_summary app = FastAPI() # 配置CORS,允许Next.js域名访问 app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:3000"], # 替换为你的Next.js生产域名 allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.post("/api/summarize-pdf") async def summarize_pdf(file: UploadFile = File(...)): # 读取上传的PDF二进制数据 pdf_bytes = await file.read() # 调用摘要生成函数 summary = generate_pdf_summary(pdf_bytes) return {"summary": summary}
三、部署与安全注意事项
后端部署:
- 用Docker打包FastAPI服务,示例Dockerfile:
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] - 部署到云平台后,开放对应端口(如8000),配置反向代理(如Nginx)实现HTTPS访问。
- 用Docker打包FastAPI服务,示例Dockerfile:
LLM资源配置:
- 本地运行LLM模型需确保服务器有足够GPU资源;调用第三方LLM API(如OpenAI)时,在后端配置API密钥,绝对不要暴露在前端代码中。
安全防护:
- 给后端API添加身份验证,比如检查请求头中的API密钥:
from fastapi import Header, HTTPException, Depends async def verify_api_key(api_key: str = Header(...)): if api_key != "你的密钥": raise HTTPException(status_code=403, detail="无效的API密钥") # 在接口中添加依赖 @app.post("/api/summarize-pdf", dependencies=[Depends(verify_api_key)])
- 给后端API添加身份验证,比如检查请求头中的API密钥:
内容的提问来源于stack exchange,提问作者Favour Onyido
相关产品推荐
相关产品推荐

