# OpenOCR Markdown Service 一个精简版图片/PDF 转 Markdown 服务,核心依赖 `openocr-python==0.1.5`,保留文档解析能力,去掉训练、评测和实验脚本。 **工作流**:Windows 本地编写代码 → Git 推送 → Ubuntu 服务器 Docker 运行。 ## 功能 - `POST /api/recognize`:上传图片或 PDF,生成 Markdown 和 JSON - `GET /api/history`:查看已解析文件列表 - `GET /output/...`:访问生成的 Markdown、JSON 和原始文件 - `GET /health`:健康检查 - `GET /docs`:Swagger API 文档 - `GET /v1/models`:OpenAI 兼容模型列表 - `POST /v1/chat/completions`:OpenAI 兼容文档转 Markdown 接口 --- ## 服务器首次初始化(Ubuntu) ### 1. 克隆代码与创建目录 ```bash cd ~ git clone <你的仓库地址> OpenOCR cd OpenOCR mkdir -p data/output data/uploads ``` ### 2. 生成并配置环境变量 ```bash cp .env.example .env ``` 纯 Docker 部署时,重点确认以下配置: ```env OPENOCR_AUTO_DOWNLOAD=true # 首次运行让容器自动下载模型 OPENOCR_USE_GPU=false # 未配置 NVIDIA Docker 插件前保持 false OPENOCR_CORS_ORIGINS=* ``` 完整配置项见 `.env.example`。 ### 3. 一键编译并启动容器 ```bash docker compose up -d --build ``` ### 4. 跟踪模型下载进度 模型体积较大,容器启动后会在后台自动下载。**此时不要急着调用接口**,先查看日志: ```bash docker compose logs -f ``` 首次下载可能需要 **5~30 分钟**(取决于网络)。当日志出现 `Application startup complete.` 且无报错时,说明模型加载完成,按 `Ctrl + C` 退出日志跟踪。 --- ## 健康检查与验证 ### 服务器本地 ```bash curl http://127.0.0.1:8000/health # 期望返回: {"status":"ok"} ``` ### Windows 本地浏览器 将 `服务器IP` 替换为实际地址: - API 文档:`http://服务器IP:8000/docs` - 健康检查:`http://服务器IP:8000/health` 若无法访问,请在云服务器安全组中放行 **8000** 端口。 ### API 调用示例 ```bash # 上传图片/PDF 进行解析 curl -F "file=@/path/to/page.png" http://127.0.0.1:8000/api/recognize # 查看历史记录 curl http://127.0.0.1:8000/api/history # 强制重新识别(同名文件默认复用已有结果) curl -F "file=@/path/to/page.png" -F "force=true" http://127.0.0.1:8000/api/recognize ``` 成功响应示例: ```json { "id": "page", "status": "success", "message": "Parsed successfully in 12.34s.", "markdown_url": "/output/page/page.md", "json_url": "/output/page/page.json" } ``` Markdown 访问地址:`http://服务器IP:8000/output/<文档名>/<文档名>.md` ### OpenAI 兼容接口 适用于已有 OpenAI SDK / LangChain / 各类 Agent 框架的调用方式。 若配置了 `OPENOCR_ROOT_PATH=/openocr`,则路径前缀为 `/openocr/v1/...`。 **列出模型** ```bash curl https://jsuse.com/openocr/v1/models ``` **文档转 Markdown(chat/completions)** ```bash curl https://jsuse.com/openocr/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "opendoc-0.1b", "messages": [ { "role": "user", "content": [ {"type": "text", "text": "Convert this document to markdown"}, { "type": "image_url", "image_url": {"url": "https://example.com/page.png"} } ] } ] }' ``` 也支持 `data:image/png;base64,...` 形式的图片 URL。 响应中的 `choices[0].message.content` 即为 Markdown 文本。 若设置了 `OPENOCR_API_KEY`,需附加请求头: ```bash -H "Authorization: Bearer your-api-key" ``` Python 示例(OpenAI SDK): ```python from openai import OpenAI client = OpenAI( base_url="https://jsuse.com/openocr/v1", api_key="your-api-key-or-empty", ) response = client.chat.completions.create( model="opendoc-0.1b", messages=[ { "role": "user", "content": [ {"type": "text", "text": "Convert to markdown"}, { "type": "image_url", "image_url": {"url": "https://example.com/page.png"}, }, ], } ], ) print(response.choices[0].message.content) ``` --- ## 日常开发与更新 ### Windows 本地 改完代码后推送到远程仓库: ```powershell # 若已配置 git 快捷别名 gpush "feat: 优化 OCR 的 Markdown 布局解析器" # 或标准命令 git add . git commit -m "feat: 优化 OCR 的 Markdown 布局解析器" git push ``` ### Ubuntu 服务器 **只改了 Python 代码**(最常见): ```bash cd ~/OpenOCR git pull && docker compose up -d --build ``` 优化后 Dockerfile 会分层缓存:`pyproject.toml` 不变时不会重装 `openocr-python` 等大依赖,通常 **10~30 秒** 即可完成。 **只改了 `.env` 配置**(无需重新 build): ```bash docker compose up -d ``` **依赖变更**(改了 `pyproject.toml`)才需要完整重建: ```bash docker compose build --no-cache docker compose up -d ``` 模型缓存在 Docker 卷 `openocr-model-cache` 中,重建容器后**不会重复下载模型**。解析结果在 `./data/` 中,同样不会丢失。 --- ## 启动速度优化说明 每次 `docker compose up -d --build` 很慢,通常有两类原因: | 原因 | 现象 | 已做优化 | |------|------|----------| | pip 重复下载依赖 | build 阶段耗时数分钟 | Dockerfile 分层 + BuildKit pip 缓存 | | 模型重复下载 | 启动后日志里又在下载 | 模型目录挂载到 `openocr-model-cache` 卷 | **首次部署**仍需下载模型(5~30 分钟,一次性)。之后日常更新应明显变快。 若 BuildKit 缓存未生效,可确认 Docker 版本 ≥ 20.10,compose 会自动使用 BuildKit。 --- ## 日常排错与手动测试 ### 查看日志 ```bash docker compose logs -f openocr-markdown ``` ### 命令行手动解析(不经过 API) ```bash docker compose exec openocr-markdown openocr-md /app/data/uploads/test.pdf --output-dir /app/data/output ``` ### 常用运维命令 ```bash docker compose ps # 查看容器状态 docker compose down # 停止服务 docker compose up -d --build # 重新构建并启动 ``` --- ## 关键配置 通过 `.env` 或环境变量配置: | 变量 | 默认值 | 说明 | |------|--------|------| | `OPENOCR_ROOT_PATH` | *(空)* | 反向代理子路径,如 `/openocr` | | `OPENOCR_OUTPUT_DIR` | `data/output` | 解析结果输出目录 | | `OPENOCR_UPLOAD_DIR` | `data/uploads` | 上传文件临时目录 | | `OPENOCR_USE_GPU` | `false` | 是否使用 GPU | | `OPENOCR_AUTO_DOWNLOAD` | `true` | 首次运行自动下载模型 | | `OPENOCR_LAYOUT_THRESHOLD` | `0.4` | 版面分析阈值 | | `OPENOCR_MAX_LENGTH` | `2048` | 识别最大长度 | | `OPENOCR_CORS_ORIGINS` | `*` | 跨域来源,多个用逗号分隔 | | `OPENOCR_API_KEY` | *(空)* | OpenAI 兼容接口 Bearer Token,留空则不校验 | | `OPENOCR_OPENAI_MODEL` | `opendoc-0.1b` | OpenAI 兼容接口使用的模型 ID | | `OPENOCR_LOG_LEVEL` | `info` | 日志级别 | --- ## 项目结构 ```text . ├── src/openocr_markdown/ │ ├── api.py # FastAPI 服务 │ ├── cli.py # 命令行入口 │ ├── config.py # 环境变量配置 │ ├── engine.py # OpenOCR 模型加载和解析封装 │ └── schemas.py # API 响应模型 ├── tests/ ├── Dockerfile ├── docker-compose.yml ├── pyproject.toml └── .env.example ``` ## 反向代理(Nginx 子路径) 若通过 `https://jsuse.com/openocr/` 这类**子路径**访问(而非直接 `:8000`),必须在 `.env` 中设置: ```env OPENOCR_ROOT_PATH=/openocr ``` 否则 `/health` 可能正常,但 `/docs` 会报 **Failed to load API definition**——因为 Swagger 会去根路径请求 `/openapi.json`,而不是 `/openocr/openapi.json`。 Nginx 参考配置: ```nginx location /openocr/ { proxy_pass http://127.0.0.1:8000/; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } ``` 修改后重启容器: ```bash docker compose up -d --build ``` --- ## 注意事项 - `.env`、`data/`、模型缓存目录已在 `.gitignore` 中排除,不会进入 Git - 首次启动耗时较长属于正常现象,等待模型下载完成后再调用接口 - 生产环境建议在 Docker 前加 Nginx 反向代理并配置 HTTPS