基于FastAPI搭建PDF翻译微服务:从架构到部署(附完整代码)
前言最近在做一个企业内部文档中台项目需要把PDF翻译能力封装成微服务供前端、IM机器人、定时任务等多个消费者调用。调研了一圈发现市面上的方案要么太重直接部署商业软件要么太轻纯脚本无法水平扩展。最终选型是FastAPI PDFTranslator API Docker轻量、异步、易部署。本文分享完整的架构设计和代码实现读者可以直接复制使用。环境准备Python 3.10Docker Docker Compose可选用于部署依赖库pipinstallfastapi uvicorn httpx python-multipart aiofiles架构设计┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ 前端/客户端 │────→│ FastAPI微服务 │────→│ PDFTranslator │ │ /IM机器人 │ │ (翻译任务管理) │ │ 翻译API │ └─────────────┘ └──────────────────┘ └─────────────────┘ │ ↓ ┌──────────────────┐ │ Redis (可选) │ │ 任务队列/缓存 │ └──────────────────┘核心设计原则异步处理PDF翻译是IO密集型操作FastAPI的异步能力可以高效处理并发状态管理翻译任务异步执行客户端通过任务ID轮询进度容错设计网络异常时自动重试失败任务可重新触发实现步骤Step 1: 项目结构pdf-translate-service/ ├── main.py # FastAPI入口 ├── translator.py # 翻译核心逻辑 ├── models.py # Pydantic模型 ├── requirements.txt └── DockerfileStep 2: 数据模型定义# models.pyfrompydanticimportBaseModel,FieldfromtypingimportOptional,LiteralfromdatetimeimportdatetimefromenumimportEnumclassTaskStatus(str,Enum):PENDINGpendingPROCESSINGprocessingCOMPLETEDcompletedFAILEDfailedclassTranslateRequest(BaseModel):source_lang:strField(defaultauto,description源语言代码)target_lang:strField(...,description目标语言代码如 zh, en, de)webhook_url:Optional[str]Field(None,description完成后的回调URL)classTranslateTask(BaseModel):task_id:strstatus:TaskStatus source_lang:strtarget_lang:stroriginal_filename:strcreated_at:datetime completed_at:Optional[datetime]Nonedownload_url:Optional[str]Noneerror_message:Optional[str]NoneStep 3: 翻译核心逻辑# translator.pyimporthttpximportuuidimportasynciofrompathlibimportPathfromtypingimportOptional PDFTRANSLATOR_APIhttps://api.pdftranslator.org/v1/translateclassPDFTranslatorClient:PDFTranslator API 异步客户端def__init__(self,api_key:Optional[str]None):self.api_keyapi_key self.clienthttpx.AsyncClient(timeout300.0)asyncdeftranslate(self,file_path:Path,target_lang:str,source_lang:strauto)-dict: 异步翻译PDF文件 Args: file_path: PDF文件路径 target_lang: 目标语言代码 source_lang: 源语言代码auto表示自动检测 Returns: API响应字典包含翻译结果URL headers{}ifself.api_key:headers[Authorization]fBearer{self.api_key}data{source_lang:source_lang,target_lang:target_lang}withopen(file_path,rb)asf:files{file:(file_path.name,f,application/pdf)}responseawaitself.client.post(PDFTRANSLATOR_API,datadata,filesfiles,headersheaders)response.raise_for_status()returnresponse.json()asyncdefclose(self):awaitself.client.aclose()Step 4: FastAPI 主服务# main.pyimportuuidimportshutilfromdatetimeimportdatetimefrompathlibimportPathfromtypingimportDictfromfastapiimportFastAPI,File,UploadFile,HTTPException,BackgroundTasksfromfastapi.responsesimportFileResponsefrommodelsimportTranslateRequest,TranslateTask,TaskStatusfromtranslatorimportPDFTranslatorClient appFastAPI(titlePDF Translation Microservice)# 内存存储生产环境建议用Redis 持久化数据库tasks_db:Dict[str,TranslateTask]{}UPLOAD_DIRPath(./uploads)RESULT_DIRPath(./results)UPLOAD_DIR.mkdir(exist_okTrue)RESULT_DIR.mkdir(exist_okTrue)app.post(/translate,response_modelTranslateTask)asyncdefcreate_translate_task(background_tasks:BackgroundTasks,request:TranslateRequest,file:UploadFileFile(...)): 创建PDF翻译任务 - 接收PDF文件和翻译参数 - 返回任务ID客户端通过 /tasks/{task_id} 查询进度 ifnotfile.filename.endswith(.pdf):raiseHTTPException(400,detailOnly PDF files are supported)task_idstr(uuid.uuid4())upload_pathUPLOAD_DIR/f{task_id}_{file.filename}withopen(upload_path,wb)asf:contentawaitfile.read()f.write(content)taskTranslateTask(task_idtask_id,statusTaskStatus.PENDING,source_langrequest.source_lang,target_langrequest.target_lang,original_filenamefile.filename,created_atdatetime.now())tasks_db[task_id]task# 后台异步执行翻译background_tasks.add_task(process_translation,task_idtask_id,file_pathupload_path,target_langrequest.target_lang,source_langrequest.source_lang)returntaskasyncdefprocess_translation(task_id:str,file_path:Path,target_lang:str,source_lang:str):后台执行翻译任务tasktasks_db[task_id]clientPDFTranslatorClient()try:task.statusTaskStatus.PROCESSING# 调用翻译API带重试resultawaittranslate_with_retry(client,file_path,target_lang,source_lang)# 保存结果这里模拟下载翻译后的文件result_pathRESULT_DIR/f{task_id}_translated.pdfawaitdownload_result(result[download_url],result_path)task.statusTaskStatus.COMPLETED task.completed_atdatetime.now()task.download_urlf/download/{task_id}exceptExceptionase:task.statusTaskStatus.FAILED task.error_messagestr(e)finally:awaitclient.close()# 清理上传的原始文件iffile_path.exists():file_path.unlink()asyncdeftranslate_with_retry(client:PDFTranslatorClient,file_path:Path,target_lang:str,source_lang:str,max_retries:int3)-dict:带重试机制的翻译调用forattemptinrange(max_retries):try:returnawaitclient.translate(file_path,target_lang,source_lang)excepthttpx.HTTPStatusErrorase:ife.response.status_code500andattemptmax_retries-1:wait_time2**attempt# 指数退避awaitasyncio.sleep(wait_time)continueraiseraiseException(Max retries exceeded)asyncdefdownload_result(url:str,save_path:Path):下载翻译结果asyncwithhttpx.AsyncClient()asclient:responseawaitclient.get(url)response.raise_for_status()withopen(save_path,wb)asf:f.write(response.content)app.get(/tasks/{task_id},response_modelTranslateTask)asyncdefget_task_status(task_id:str):查询任务状态iftask_idnotintasks_db:raiseHTTPException(404,detailTask not found)returntasks_db[task_id]app.get(/download/{task_id})asyncdefdownload_translated_file(task_id:str):下载翻译后的PDFiftask_idnotintasks_db:raiseHTTPException(404,detailTask not found)tasktasks_db[task_id]iftask.status!TaskStatus.COMPLETED:raiseHTTPException(400,detailTask not completed yet)result_pathRESULT_DIR/f{task_id}_translated.pdfifnotresult_path.exists():raiseHTTPException(404,detailResult file not found)returnFileResponse(result_path,filenameftranslated_{task.original_filename},media_typeapplication/pdf)app.get(/health)asyncdefhealth_check():健康检查端点return{status:healthy,timestamp:datetime.now().isoformat()}if__name____main__:importuvicorn uvicorn.run(app,host0.0.0.0,port8000)Step 5: Docker 部署配置# Dockerfile FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . RUN mkdir -p uploads results EXPOSE 8000 CMD [uvicorn, main:app, --host, 0.0.0.0, --port, 8000]# docker-compose.ymlversion:3.8services:pdf-translate-api:build:.ports:-8000:8000volumes:-./uploads:/app/uploads-./results:/app/resultsenvironment:-PYTHONUNBUFFERED1restart:unless-stoppedhealthcheck:test:[CMD,curl,-f,http://localhost:8000/health]interval:30stimeout:10sretries:3运行效果启动服务docker-composeup-d提交翻译任务curl-XPOSThttp://localhost:8000/translate\-Ffiledocument.pdf\-Frequest{target_lang:zh}查询任务状态curlhttp://localhost:8000/tasks/{task_id}响应示例{task_id:550e8400-e29b-41d4-a716-446655440000,status:completed,source_lang:auto,target_lang:zh,original_filename:document.pdf,created_at:2026-07-28T10:30:00,completed_at:2026-07-28T10:32:15,download_url:/download/550e8400-e29b-41d4-a716-446655440000,error_message:null}生产环境建议持久化存储用PostgreSQL替代内存字典存储任务状态消息队列用Celery Redis处理大文件翻译避免阻塞API限流用FastAPI的依赖注入实现速率限制防止滥用监控集成Prometheus Grafana监控API健康度认证添加JWT或API Key认证保护翻译接口总结这套方案的核心价值在于轻量和可扩展单服务启动仅需几十MB内存异步架构天然支持高并发Docker化部署适配K8s等容器编排平台与PDFTranslator的免费API结合企业文档中台的翻译成本可以降到接近零完整代码已在上文给出直接复制即可运行。有问题欢迎在评论区讨论。标签PDF翻译、FastAPI、Python、微服务、Docker、AI翻译

相关新闻

pycharm连接mysql时报错

pycharm连接mysql时报错

#在URL后加上: ?serverTimezoneUTC&characterEncodingutf-8

2026/7/28 15:47:41 阅读更多 →
数据通信基础(一)

数据通信基础(一)

数据通信基础(一) 1.数据通信基本概念 2.数据通信计算 3.通信传输介质 4.数据调制与编码 1.数据通信基本概念 考点1: 信源:信号的产生物(发送端) 信道:通信的通道,是信号传输的媒介 信宿:信号的接收(接收端) 数字信号:是以某一瞬间的状态表示它们传送的消息,…

2026/7/28 15:47:41 阅读更多 →
2026年大模型选型指南:不聊跑分,只讲场景和落地无标题】

2026年大模型选型指南:不聊跑分,只讲场景和落地无标题】

今年的模型格外火,模型跑分各种评论一堆一堆,真要选的时候还是不知道怎么定。 换模型改代码这个事,干过的都懂——改地址、改参数、改返回解析,一折腾就是半天,还得重新测一遍。 这篇不是测评报告,也不是源…

2026/7/28 15:47:41 阅读更多 →

最新新闻

ncmdumpGUI:三分钟快速解锁网易云NCM加密音乐的终极指南

ncmdumpGUI:三分钟快速解锁网易云NCM加密音乐的终极指南

ncmdumpGUI:三分钟快速解锁网易云NCM加密音乐的终极指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 还在为网易云音乐下载的NCM格式文件无法在…

2026/7/28 15:54:44 阅读更多 →
如何高效获取官方电子教材:tchMaterial-parser 终极使用指南

如何高效获取官方电子教材:tchMaterial-parser 终极使用指南

如何高效获取官方电子教材:tchMaterial-parser 终极使用指南 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具,帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载,让您更方便地获取课本内容。 项…

2026/7/28 15:54:44 阅读更多 →
(超级全)Linux常用命令 ,看这一篇就够了,30分钟马上学会

(超级全)Linux常用命令 ,看这一篇就够了,30分钟马上学会

欢迎交流 QQ 2431173627 微信 ccc17862701790 本文将介绍工作学习面试中常用到的LInux基本命令 基本都会涵盖到本人将linux命令总结为一下几大块(如有错误,恳请指正)话不多说 下面将逐一介绍主要参考鸟哥的linux私房菜 同时结合其他地方的学习材料 以及个人平常的使用总结故在以…

2026/7/28 15:54:44 阅读更多 →
长鑫上市,造富了谁

长鑫上市,造富了谁

2026年7月27日,国产DRAM龙头长鑫科技正式登陆上交所科创板。开盘报49.50元/股,较发行价8.66元/股大涨471.59%,总市值一举突破3.31万亿元。截至当日收盘,市值定格在3.28万亿元,超越工商银行、建设银行、农业银行、中国移…

2026/7/28 15:54:44 阅读更多 →
Visual C++运行库终极修复指南:一键解决DLL缺失问题

Visual C++运行库终极修复指南:一键解决DLL缺失问题

Visual C运行库终极修复指南:一键解决DLL缺失问题 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的尴尬时刻?刚下载…

2026/7/28 15:54:44 阅读更多 →
Matlab学习 -- .m文件

Matlab学习 -- .m文件

.m文件分为脚本文件和函数,其中函数可以接收参数和输出,脚本不可以脚本中往往包含多个函数,是一系列命令行的集合创建脚本文件需要使用文本编辑器,使用edit(文件名.m)打开文本编辑器输入文件名即可运行脚本mkdir创建文件夹&#x…

2026/7/28 15:53:44 阅读更多 →

日新闻

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:43 阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:43 阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:43 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/28 8:29:16 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻