PaddleOCR TypeScript SDK 实战:从安装认证到任务提交、轮询结果与错误处理的完整指南
【免费下载链接】PaddleOCRTurn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100+ languages.项目地址: https://gitcode.com/GitHub_Trending/pa/PaddleOCR
本篇技术指南基于 PaddleOCR 仓库中的 api_sdk/typescript/README.md 及其配套源码展开,系统讲解官方 npm 包@paddleocr/api-sdk的安装方式、认证配置、OCR 与文档解析任务提交、模型选择、轮询机制、结果结构以及完整错误处理体系。读完本文,你可以直接在 Node.js 项目中调用 PaddleOCR 托管 API,完成从 PDF/图片到结构化文本的解析,并能通过submit/wait拆分接口、AbortSignal与批量任务(batchId)实现并发控制。需要特别说明的是:该 SDK 是 PaddleOCR 官方 API 的 TypeScript 客户端,负责提交任务并获取结果,本身不执行本地 OCR 推理。
定位、安装与本地构建
TypeScript SDK 以公共作用域 npm 包@paddleocr/api-sdk发布,遵循 SemVer 版本管理。从 package.json 可以看到几个关键约束:
- 运行时要求
node >= 18(engines字段),基于 Node 18+ 内置的全局fetch实现网络层; - 采用 ESM 为主、CJS 兼容的双格式产物(
"type": "module",main指向dist/index.cjs,module指向dist/index.js),构建工具为tsup; - 许可证为 Apache-2.0。
生产环境直接安装发布版本:
npm install @paddleocr/api-sdk在仓库内做本地开发时,SDK 源码位于 api_sdk/typescript/ 目录,可执行:
npm install npm run build其中build脚本即tsup(见 tsup.config.ts 与 tsconfig.json),产出dist/下的 ESM、CJS 与类型声明文件。
认证与客户端初始化
SDK 通过 Bearer Token 认证。二选一方式提供令牌:
- 设置环境变量
PADDLEOCR_ACCESS_TOKEN; - 或通过构造函数的
token选项显式传入。
export PADDLEOCR_ACCESS_TOKEN="your-access-token"import { PaddleOCRClient } from "@paddleocr/api-sdk"; const client = new PaddleOCRClient({ token: process.env.PADDLEOCR_ACCESS_TOKEN, });从 客户端入口源码 可以看到初始化逻辑的细节:token解析顺序为「显式参数 → 环境变量 → 空串」,若最终为空则立即抛出AuthError,即缺少令牌时客户端构造即失败,不会延迟到首次请求。
完整的客户端配置项定义在 ClientOptions 接口:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
token | string | 读PADDLEOCR_ACCESS_TOKEN | 访问令牌,必填(参数或环境变量二选一) |
baseUrl | string | https://paddleocr.aistudio-app.com(或PADDLEOCR_BASE_URL环境变量) | 官方 API 服务地址,可用于接入自建代理 |
requestTimeout | number | 300000(5 分钟) | 单次 HTTP 请求超时,覆盖提交任务、查询状态、下载资源 |
pollTimeout | number | 600000(10 分钟) | 等待任务完成的总时长上限 |
timeout | number | — | requestTimeout/pollTimeout的兼容简写 |
fetch | typeof fetch | 全局fetch | 注入自定义 fetch 实现,适配代理或自定义网络层 |
clientPlatform | string | 无 | 附加Client-Platform请求头标识调用方平台 |
自定义服务地址与 fetch 注入示例:
const client = new PaddleOCRClient({ baseUrl: "https://my-proxy.com/paddle", fetch: myCustomFetch, });快速开始:OCR 与文档解析
提交 OCR 任务
最小可用示例(与 README 一致):
import { Model, PaddleOCRClient } from "@paddleocr/api-sdk"; const client = new PaddleOCRClient(); const result = await client.ocr({ model: Model.PPOCRv5, fileUrl: "https://example.com/invoice.pdf", }); console.log(result.jobId, result.pages.length);client.ocr()是便捷方法:内部先调用submitOcr提交任务获得jobId,再自动轮询直到任务完成并解析结果(见 ocr 方法实现)。完整可运行的 URL 提交示例可参考 examples/ocr-url.ts。
文件来源二选一:
fileUrl:服务端直接抓取公开 URL 文件,走 JSON 提交;filePath:本地文件,SDK 通过 multipart/form-data 上传(内部以FormData附加file字段及model、optionalPayload、pageRanges、batchId,见 submitFile 实现),且要求文件真实存在,否则抛FileNotFoundError。
两者互斥:同时提供或都不提供会在提交前抛出InvalidRequestError(校验逻辑)。
其他通用请求字段:
pageRanges:只处理指定页码范围(如"1-2");batchId:把多个任务归入同一批次,可用getBatchStatus(batchId)统一查询进度;options:任务级算法参数,按任务类型分别对应OCROptions/DocParsingOptions(见后文参数表)。未设置的字段不会随请求发送,由服务端使用默认值。
提交文档解析任务
文档解析(结构化文档 → Markdown 等)默认使用PaddleOCR-VL-1.6模型:
const doc = await client.parseDocument({ filePath: "./report.pdf", options: { useChartRecognition: true, }, }); console.log(doc.jobId, doc.pages.length);指定Model.PPStructureV3即可改用 PP-StructureV3 解析管线。本地文件解析的完整示例(含提交后并发等待多个任务)见 examples/doc-parsing-file.ts:
// 手动模式:先批量提交,再并发等待 const job1 = await client.submitOcr({ fileUrl: "https://example.com/f1.pdf" }); const job2 = await client.submitDocumentParsing({ model: Model.PPStructureV3, filePath: "./sample.pdf", }); const [r1, r2] = await Promise.all([ client.waitOcrResult(job1.jobId), client.waitDocumentParsingResult(job2.jobId), ]);公共 API 方法一览
SDK 的方法分为两类:便捷方法(提交 + 等待一步完成)和拆分方法(提交、查询、等待分离,适合并发与断点续查)。完整导出清单见 src/index.ts:
| 方法 | 说明 |
|---|---|
ocr(req, { signal }) | 提交 OCR 任务、等待完成并返回OCRResult |
parseDocument(req, { signal }) | 提交文档解析任务、等待完成并返回DocParsingResult |
submitOcr(req) | 仅提交 OCR 任务,返回Job(含jobId、model、task、pageRanges、batchId) |
submitDocumentParsing(req) | 仅提交文档解析任务,返回Job |
waitOcrResult(job \| jobId) | 等待 OCR 任务完成并解析结果 |
waitDocumentParsingResult(job \| jobId) | 等待文档解析任务完成并解析结果 |
getStatus(jobId) | 非阻塞查询任务状态,返回JobStatus |
getBatchStatus(batchId) | 查询批次内全部任务状态 |
saveResource(url, dest, opts) | 保存单个结果资源 URL 到本地 |
saveOcrResultResources(result, dir, opts) | 批量保存 OCR 结果引用的资源(如ocrImageUrl) |
saveDocumentParsingResultResources(result, dir, opts) | 批量保存文档解析结果引用的资源(Markdown 图片、输出图等) |
所有提交/等待方法均支持传入AbortSignal以主动取消(轮询循环会在每轮检查信号,见 poller 实现)。
模型选择与任务校验
SDK 通过Model枚举提供官方 API 模型名的类型安全写法(models.ts),枚举值本身就是提交请求时使用的模型名字符串,也可以直接传字符串(如model: "PaddleOCR-VL-1.6"):
| 枚举 | 模型名 | 适用任务 |
|---|---|---|
Model.PPOCRv5 | PP-OCRv5 | OCR |
Model.PPOCRv5Latin | PP-OCRv5-latin | OCR(拉丁字符) |
Model.PPOCRv6 | PP-OCRv6 | OCR |
Model.PPStructureV3 | PP-StructureV3 | 文档解析 |
Model.PaddleOCRVL | PaddleOCR-VL | 文档解析 |
Model.PaddleOCRVL15 | PaddleOCR-VL-1.5 | 文档解析 |
Model.PaddleOCRVL16 | PaddleOCR-VL-1.6 | 文档解析 |
默认模型与任务-模型匹配规则在源码中硬性校验(validateModelForTask):
| 任务 | 默认模型 | 可选模型 | 参数类型 |
|---|---|---|---|
OCR(ocr/submitOcr/waitOcrResult) | Model.PPOCRv6 | PPOCRv5、PPOCRv5Latin、PPOCRv6 | OCROptions |
文档解析(parseDocument等) | Model.PaddleOCRVL16 | PPStructureV3、PaddleOCRVL、PaddleOCRVL15、PaddleOCRVL16 | PPStructureV3对应PPStructureV3Options;VL 系列对应PaddleOCRVLOptions |
例如对 OCR 任务传入文档解析模型会直接抛InvalidRequestError: Model ... is not an OCR model.,错误在本地即被拦截、不会浪费一次网络提交。
任务级算法参数
参数均为可选、camelCase 命名,与官方 API 字段一致。三类可选字段的定义见 models.ts 中的三个 Options 接口。常用字段如下:
OCROptions
| 字段 | 类型 | 说明 |
|---|---|---|
useDocOrientationClassify | boolean | 文档方向分类 |
useDocUnwarping | boolean | 文档扭曲矫正 |
useTextlineOrientation | boolean | 文本行方向分类 |
textDetLimitSideLen/textDetLimitType | number / string | 文本检测长边限制及限制方式 |
textDetThresh/textDetBoxThresh/textDetUnclipRatio | number | 检测置信度阈值、box 阈值与外扩比例 |
textRecScoreThresh | number | 识别置信度阈值 |
visualize | boolean | 是否返回可视化结果图 |
PPStructureV3Options
| 字段 | 类型 | 说明 |
|---|---|---|
useTableRecognition | boolean | 表格识别 |
useFormulaRecognition | boolean | 公式识别 |
useChartRecognition | boolean | 图表识别 |
useSealRecognition | boolean | 印章识别 |
useRegionDetection | boolean | 区域检测 |
layoutThreshold | number | Record | 版面检测置信度阈值(可按类别配置) |
markdownIgnoreLabels | string[] | Markdown 输出时忽略的版面类别 |
prettifyMarkdown | boolean | Markdown 美化 |
outputFormats | string[] | 输出格式 |
PaddleOCRVLOptions
| 字段 | 类型 | 说明 |
|---|---|---|
useLayoutDetection | boolean | 版面检测 |
useChartRecognition | boolean | 图表识别 |
promptLabel | "ocr" \| "formula" \| "table" \| "chart" \| "seal" \| "spotting" | VL 模型处理的区块类型 |
temperature/topP/repetitionPenalty | number | 生成采样参数 |
maxNewTokens/minPixels/maxPixels | number | 生成与图像缩放控制 |
prettifyMarkdown/mergeTables/relevelTitles/restructurePages | boolean | Markdown 后处理选项 |
showFormulaNumber | boolean | 公式编号 |
由于接口声明了[key: string]: unknown索引签名,SDK 允许透传未显式列出的官方 API 参数,实际可用参数集以后端 API 为准。
底层机制:提交、轮询与结果解析
理解调用链有助于排障与性能调优。从源码看,一次完整调用经历三个阶段:
1. 提交任务(POST)。HttpClient 固定请求官方 API 路径/api/v2/ocr/jobs:fileUrl走 JSON 请求体({ fileUrl, model, optionalPayload }+ 可选pageRanges/batchId),filePath走 multipart 上传;请求头携带Authorization: Bearer <token>。响应体约定为{ code, msg, data }结构,code非 0 即视为业务失败并抛APIError(fetchJson 实现),data.jobId缺失则抛ResponseFormatError。
2. 轮询状态(GET)。Poller 采用指数退避策略:初始间隔 3 秒,每轮乘以 1.5 倍,上限 15 秒,总时长受pollTimeout(默认 10 分钟)约束。任务状态机为pending → running → done | failed:
done:从状态响应中的resultUrl.jsonUrl拉取 JSONL 结果文件,按行解析为结构化对象;failed:抛JobFailedError(携带jobId与服务端errorMsg);- 超过
pollTimeout:抛PollTimeoutError。
3. 结果解析。OCR 结果要求每行包含result.ocrResults[].prunedResult,文档解析结果要求result.layoutParsingResults[].markdown.text,字段缺失时抛ResultParseError(parseOCRResult / parseDocParsingResult)。
结果对象结构
结果类型定义在 src/results.ts:
// OCR 结果 interface OCRResult { jobId: string; pages: Array<{ prunedResult: unknown; // 精简后的 OCR 文本/坐标结果 ocrImageUrl?: string; // OCR 结果图 URL docPreprocessingImageUrl?: string; // 预处理图 URL inputImageUrl?: string; // 输入图 URL }>; dataInfo?: Record<string, unknown>; } // 文档解析结果 interface DocParsingResult { jobId: string; pages: Array<{ markdownText: string; // 该页 Markdown 文本 markdownImages: Record<string, string>; // Markdown 中图片 → URL outputImages: Record<string, string>; // 输出图(如版面图)→ URL inputImageUrl?: string; exports?: Record<string, unknown>; markdown?: Record<string, unknown>; }>; dataInfo?: Record<string, unknown>; }任务状态对象JobStatus含state、progress(totalPages/extractedPages/起止时间)、resultUrl与errorMsg字段,可用于展示进度。
错误处理体系
SDK 的全部异常继承自PaddleOCRAPIError(src/errors.ts),可按name或instanceof精确分类处理:
| 异常类 | 触发场景 |
|---|---|
AuthError | 构造时缺少 token;HTTP 401/403 |
InvalidRequestError | fileUrl/filePath互斥校验失败、模型与任务不匹配、目标路径非法 |
APIError(含statusCode) | 业务code非 0 或其他非 2xx 响应 |
RateLimitError | HTTP 429,触发限流 |
ServiceUnavailableError | HTTP 503/504,服务不可用 |
JobFailedError(含jobId、errorMsg) | 服务端任务执行失败 |
RequestTimeoutError | 单次 HTTP 请求超过requestTimeout |
PollTimeoutError | 轮询总时长超过pollTimeout |
NetworkError | 连接失败等底层网络异常 |
FileNotFoundError | 本地filePath不存在 |
ResponseFormatError/ResultParseError | 响应体缺少data/jobId/state等约定字段、JSONL 结果解析失败 |
生产代码中一个稳健的捕获示例:
import { JobFailedError, PollTimeoutError, RateLimitError } from "@paddleocr/api-sdk"; try { await client.ocr({ fileUrl: url }); } catch (e) { if (e instanceof RateLimitError) { /* 退避重试 */ } else if (e instanceof PollTimeoutError) { /* 用 e.jobId 稍后 getStatus 续查 */ } else if (e instanceof JobFailedError) { console.error(e.errorMsg); } else { throw e; } }注意PollTimeoutError不代表任务失败——任务可能仍在服务端运行,可保存jobId之后通过getStatus/waitOcrResult续查。
保存结果资源到本地
OCR 与文档解析结果中引用的图片(ocrImageUrl、Markdown 插图等)以 URL 形式返回。SDK 提供三组方法将其落盘,destination可以是已存在的目录(自动按 URL basename 命名)或具体文件路径,options.overwrite控制是否覆盖已存在文件:
// 保存 OCR 每页的结果图 const saved = await client.saveOcrResultResources(ocrResult, "./output"); // 保存文档解析的 Markdown 图片与输出图 const saved2 = await client.saveDocumentParsingResultResources(docResult, "./output"); // 或单独保存某个 URL await client.saveResource(imageUrl, "./output/figure.png", { overwrite: true });实现上有明确的安全约束(saveResourceUrl 与校验逻辑):目标目录必须已存在;非overwrite模式下拒绝覆盖且检测同批次重复目标;资源映射键不允许包含路径分隔符或以.开头的危险文件名(safeMapKeyFilename),URL basename 也会被规范化防止路径逃逸。
构建、测试与质量门禁
SDK 目录内的工程化脚本(package.json scripts)与 README「Build And Test」一节对应:
npm run lint # tsc --noEmit,类型检查 npm run build # tsup 构建 ESM/CJS/类型声明 npm test # vitest run 单元测试 npm audit --audit-level=moderate # 依赖审计prepublishOnly钩子会串行执行 lint + build + test,保证发布前质量门禁。单元测试 tests/client.test.ts 通过注入 mockfetch验证了公共契约:token 构造期校验、submitOcr请求体格式(含pageRanges/batchId/optionalPayload)、状态轮询与 JSONL 结果解析、各类异常路径,可作为理解 SDK 行为边界的可靠依据。
延伸阅读
- 官方文档中文站对应章节:PaddleOCR 官方 API TypeScript SDK
- 英文版本:TypeScript SDK (English)
- SDK 中文 README:api_sdk/typescript/README_cn.md
- 同仓库其他语言客户端:api_sdk/go(Go SDK)与 paddleocr/_api_client(Python 侧实现),可对照阅读提交-轮询-解析的共性设计。
【免费下载链接】PaddleOCRTurn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100+ languages.项目地址: https://gitcode.com/GitHub_Trending/pa/PaddleOCR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考