V1 HTTP API
自部署 V1 API 与 Python SDK、WebUI 使用同一套接口。本页说明一次完整请求周期——创建上传、上传字节、提交解析任务、轮询到终态、下载产物——并指向一个经过测试的示例脚本。Python 客户端见 Python SDK。
先启动本地服务,或将示例指向任意 V1 部署(包括官方云服务):
mineru-kit api-server --host 127.0.0.1 --port 8000 --tier standard
一次请求解析与异步 tasks
API server 和 Router 都提供 /v1/tasks、/v1/file_parse,与现有 Job 共用后台解析和任务 ID:
curl -sS 'http://127.0.0.1:8000/v1/file_parse?tier=flash&ocr_mode=txt' \
-F 'files=@document.pdf' -o result.json
curl -sS 'http://127.0.0.1:8000/v1/file_parse?tier=flash&response_format=zip' \
-F 'files=@document.pdf' -o result.zip
MINERU_API_URL=http://127.0.0.1:8002 MODE=async RESPONSE_FORMAT=zip \
bash scripts/http_task_example.sh document.pdf
同步等待默认 300 秒,wait_timeout 支持 1–3600 秒;超时返回 202 和 task_id/status_url/result_url,任务继续执行。
异步提交使用 POST /v1/tasks,通过返回的 V1 地址查询状态和结果。JSON 内联 files[].content,同时保留逐文件错误和产物引用。
异步 ZIP 必须提交时请求 output_formats=zip;同步 ZIP 自动请求。部分成功返回 200 和 partial,批量 ZIP 含分目录产物及 manifest。
上传可以是 multipart 或原始字节,也可使用与 V1 Job 相同的 JSON 来源。上传解析参数放查询串,JSON 参数放主体。
每文件最多 200 MiB,每任务最多 100 文件;批量上传共用页范围,逐文件配置使用 JSON。原始字节需提供 filename 和 Content-Length。
上述脚本自动计算 SHA-256 并使用 Expect: 100-continue;命中缓存且及时响应时,可跳过主体传输。
代理缓冲和客户端等待预算会影响省流量效果;直接复用 file_id 或现有 uploads 预检仍可可靠避免重复上传。
Router 的 V1 上传和便捷上传共享按调用方隔离的源字节缓存。上传按负载分配、同负载轮询;任务在上游网络等待前预占名额。
文件归属仅在最低负载候选中享有优先权,哈希命中也不能把任务固定到繁忙 worker。
一个批量任务仍整体交给一台 API,需要多 worker 并行时提交多个独立任务。
外置 worker 当前按容量 1 计权;本地 worker 容量来自 --worker-concurrency。这些路由属于当前自部署服务,云端支持情况以具体部署为准。
经过测试的示例脚本
包含超时、响应校验、有界轮询、退出码和凭据隔离的完整闭环,以仓库中单一经过测试的脚本维护:
export MINERU_API_URL=http://127.0.0.1:8000
export MINERU_API_KEY=secret-key # 匿名本地访问时省略
./scripts/http_api_example.sh document.pdf
脚本行为由 tests/unittest/test_http_api_example_script.py 在真实 Flash 服务和脚本化 mock 服务上验证,无需下载模型。退出码面向自动化保持稳定:
| 码 | 含义 |
|---|---|
0 |
任务 completed,全部请求产物已保存 |
1 |
脚本、传输、协议、下载或本地写入失败 |
2 |
任务 partial:已先保存成功文件的产物 |
3 |
任务 failed |
4 |
任务 canceled |
124 |
轮询预算耗尽;打印 job_id,可继续轮询 |
鉴权与字节上传
服务以 --api-key 启动时,/v1/* 请求携带 Authorization: Bearer $MINERU_API_KEY;匿名本地访问可省略该头。
字节上传原样使用 POST /v1/uploads 返回的方法、URL 和请求头:
- 自部署服务返回同源 URL(如
/v1/uploads/{id}/content)。同源指 scheme + host + 有效端口,由客户端判断而非假设;同源上传在服务要求鉴权时必须携带 API 鉴权。 - 官方 API 返回自带授权的预签名对象存储 URL。不要向不同源的 URL 附加 MinerU API Key——那会泄露凭据。服务返回的上传头(
upload_headers)始终原样保留。
示例脚本实现了与 Python SDK(api_client._same_origin_upload_headers)相同的规则:相对 URL 先按 API 基地址解析,再比较 scheme + host + 有效端口,仅对同源上传附加 MinerU Key。相对 URL 解析后即同源;同一主机的不同端口按不同源处理。
下载走 GET /v1/files/{file_id}/content,可能返回 302 重定向。示例跟随重定向但不使用 --location-trusted,凭据不会被重新发送到不同源(包括同主机不同端口;要求 curl >= 7.83.0)。
脚本刻意覆盖的请求周期细节
- 上传生命周期。 创建上传时传
sha256sum可启用完整性校验和秒传;命中已存在文件时响应直接为completed并内嵌file对象,跳过字节上传和完成两步。 - HTTP 200 不等于合法响应。 脚本在每一步校验 JSON 结构:ID 必须是非空字符串、状态必须属于支持集合;否则立即失败,而不是带着 null ID 进入轮询。
- 有界轮询。
MAX_POLLS限制轮询请求次数(每次还包括请求超时和轮询间隔);预算耗尽时脚本退出124并打印job_id——任务未被取消,可直接继续轮询。 - 终态。
completed、partial、failed、canceled都是终态。partial表示部分文件成功:脚本先保存成功文件的产物、打印含错误的逐文件结果,然后才退出2;failed退出3,canceled退出4。 - 原子下载。 产物先写
*.part,成功后才移到最终文件名;completed任务若有产物下载失败或缺失,不会退出0。 - 产物。 所有产物都是
purpose:"parse_output"的文件;内容一律通过GET /v1/files/{file_id}/content、用files[].output_files下的 id 获取。以GET /v1/health(features.sources、features.output_formats)为当前部署实际能力的依据;渲染器支持的格式不代表 API 暴露。
生产部署注意事项
- 谨慎绑定
--host。默认127.0.0.1只监听回环;使用0.0.0.0暴露到网络时,应配合--api-key或带鉴权的反向代理。 - 存储与重启边界:文件字节保存在
--upload-dir下(未配置时为临时目录,正常关闭即删除),但上传/文件/任务的资源索引是进程内状态。即使保留了目录,服务重启后旧的upload_id/file_id/任务 ID 也不保证可用。该 API 不是可恢复的持久化任务服务;持久化阅读、索引和缓存需求使用文档库——但文档库不是这套上传/任务接口的透明持久化替代品。 --concurrency限制并发解析任务数;超出后表现为queued时间变长,而不是失败。GET /v1/usage报告用量。用/v1/health和/docs(启用时)的 OpenAPI 文档区分服务端故障与客户端错误;重试failed任务前先查看服务端日志。
便捷解析使用 /v1/file_parse、/v1/tasks;根路径旧接口不提供,旧客户端迁移见迁移指南。