# PPOcrv6 **Repository Path**: mfcom/ppocrv6 ## Basic Information - **Project Name**: PPOcrv6 - **Description**: PPOcrv6做的ocr识别项目 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-10 - **Last Updated**: 2026-07-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PP-OCRv6 OCR 服务 FastAPI + PaddleOCR 的可部署 OCR 服务。提供管理端、文件/Base64/URL 识别、统一结构化响应、受控并发队列和生产安全校验。 ## 当前架构 浏览器不会直接访问 rcomOcrAdmin,也不会保存上游 JWT 到 localStorage: ~~~text 浏览器 ──账号密码──> Python /admin/login │ └──> rcomOcrAdmin /api/User/login │ └── JWT 返回 Python 浏览器 <── HttpOnly 签名会话 ── Python ~~~ Python 不连接 MySQL,也不读取数据库连接字符串。登录、Token 校验和用户/订阅信息全部通过 rcomOcrAdmin 的 HTTP API 获取。 默认接口: - POST /api/User/login - GET /api/User/getuser - GET /api/User/validatetoken 可用 RCOM_LOGIN_PATH、RCOM_USER_PATH、RCOM_VALIDATE_TOKEN_PATH 修改。 ## 鉴权方式 OCR 接口支持四种调用方式: 1. 管理网页的 HttpOnly 登录会话。 2. rcomOcrAdmin JWT:Authorization: Bearer {token}。 3. 服务间固定密钥:X-Internal-API-Key。 4. 兼容旧客户端的 OCR_API_KEY(可选)。 推荐 rcomOcrAdmin 在同一台服务器上这样调用: ~~~powershell $headers = @{'X-Internal-API-Key'=$env:OCR_INTERNAL_API_KEY} $body = @{image_url='https://example.com/image.jpg'} | ConvertTo-Json Invoke-RestMethod -Method Post -Uri 'http://127.0.0.1:8000/api/v1/ocr' -Headers $headers -ContentType 'application/json' -Body $body ~~~ Docker 端口只映射到宿主机 127.0.0.1。即使如此仍推荐固定内部密钥,因为容器内看到的来源地址通常是 Docker 网关,不一定是 127.0.0.1。 OCR_ALLOW_LOOPBACK_WITHOUT_AUTH=true 可以允许直接回环来源免鉴权,默认关闭。不要在经过反向代理或公网绑定时启用。 ### rcomOcrAdmin API Key 当前 rcomOcrAdmin 的 ApiKeyService.ValidateAsync 没有独立 HTTP 验证接口,因此 Python 不能安全复用数据库中的客户 API Key。公网客户目前应使用 rcom JWT。 以后如增加只读验证接口,可配置: ~~~text RCOM_API_KEY_VALIDATE_PATH=/api/ApiKey/Validate ~~~ Python 会用 X-Api-Key 调用它;无需连接数据库或修改 Python 路由。 ## 并发与排队 针对 4 核 CPU、8 GiB 内存,默认配置: - OCR_MAX_CONCURRENT_REQUESTS=2:全局同时推理槽位数,可设置为任意大于等于 1 的整数;每个槽位会按需加载一个独立 PaddleOCR 实例。 - OCR_CPU_THREADS=2:每路最多使用两个计算线程。 - OCR_MAX_QUEUE_SIZE=20:最多二十个请求等待。 - OCR_QUEUE_TIMEOUT_SECONDS=120:等待超过两分钟返回 504。 - Uvicorn 仍使用一个 worker,避免每个 worker 重复加载整组模型。 ### 将服务器调整为 5 个并发槽位 仓库默认值仍是 2。测试中使用过的 5 是临时验证值,不会自动写入服务器配置。需要按以下步骤操作,运行中的服务才会真正使用 5 个并发槽位。 1. 修改服务器项目目录中的 `.env`: ~~~text OCR_MAX_CONCURRENT_REQUESTS=5 OCR_MAX_QUEUE_SIZE=20 UVICORN_LIMIT_CONCURRENCY=64 ~~~ `OCR_MAX_CONCURRENT_REQUESTS=5` 表示最多同时执行 5 个 OCR 推理,并按需创建最多 5 个独立 PaddleOCR 模型实例。5 个槽位加 20 个等待请求没有超过 64,因此这个场景无需继续提高 `UVICORN_LIMIT_CONCURRENCY`。 旧部署的 `.env` 如果还存在 `OCR_MODEL_INSTANCES_PER_PROFILE=2`,可以删除。应用已经不再读取这个旧配置,它不会再把模型容量限制为 2。 2. 重建并重新创建容器,使新的环境变量生效: ~~~powershell docker compose up -d --build --force-recreate ~~~ 只修改 `.env` 但不重新创建容器不会生效。 3. 检查容器中的实际配置和运行状态: ~~~powershell docker compose exec ppocr printenv OCR_MAX_CONCURRENT_REQUESTS docker compose ps Invoke-RestMethod http://127.0.0.1:8000/health ~~~ 第一条命令应输出 `5`,`docker compose ps` 应显示服务处于 healthy 状态。登录管理端后,运行状态中的并发上限也应显示为 5。 4. 开始压测并观察资源: ~~~powershell docker stats ppocr-api ~~~ 建议依次测试 2、3、4、5、6 等槽位,记录吞吐量、响应时间、CPU 和内存峰值。模型实例是按需加载的,首次达到新的并发档位时会有模型加载开销,预热后再记录正式结果。 持续压测超过每分钟 120 个请求时,可以临时设置 `OCR_RATE_LIMIT_PER_MINUTE=0` 并再次重新创建容器,避免应用层限流干扰结果;测试结束后应恢复生产限流值。若以后将槽位数和等待队列之和提高到 64 以上,还应同步调高 `UVICORN_LIMIT_CONCURRENCY`。 请求处理顺序: ~~~text 校验与下载 → 有界等待队列 → 独立模型实例 → 结构化结果 │ ├─ 有空位:立即推理 ├─ 无空位:等待 └─ 队列已满:503 + Retry-After ~~~ 默认只启用 small,medium 已彻底禁用。需要 tiny 时可设置 OCR_ENABLED_PROFILES=small,tiny,但每个 profile 都可能按并发槽位数加载实例,应先观察内存限额内的峰值。 ## 安装与本地运行 ~~~powershell python -m venv .venv .\.venv\Scripts\python.exe -m pip install -U pip .\.venv\Scripts\python.exe -m pip install paddlepaddle==3.2.0 -i https://www.paddlepaddle.org.cn/packages/stable/cpu/ .\.venv\Scripts\python.exe -m pip install -r requirements.txt ~~~ 至少设置: ~~~powershell $env:RCOM_ADMIN_BASE_URL='https://ocrapi.example.com' $env:ADMIN_SESSION_SECRET='随机生成的至少32字符会话密钥' $env:OCR_INTERNAL_API_KEY='随机生成的至少32字符内部密钥' $env:ADMIN_COOKIE_SECURE='false' .\.venv\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 1 ~~~ 本地 HTTP 测试时 ADMIN_COOKIE_SECURE=false;通过 HTTPS 部署时必须为 true。 打开: - 管理端:http://127.0.0.1:8000/ - Swagger:http://127.0.0.1:8000/docs - 健康检查:http://127.0.0.1:8000/health ## Docker 部署 ~~~powershell Copy-Item .env.example .env ~~~ 修改 .env 中以下占位值后再启动: - RCOM_ADMIN_BASE_URL - ADMIN_SESSION_SECRET - OCR_INTERNAL_API_KEY ~~~powershell docker compose up -d --build ~~~ Compose 默认分配 4 CPU、8 GiB 内存,并配置 host.docker.internal:host-gateway。Python 容器需要访问宿主机上的 rcomOcrAdmin 时,可以把地址设为: ~~~text RCOM_ADMIN_BASE_URL=http://host.docker.internal:端口 RCOM_VERIFY_TLS=false ~~~ 若使用公网 HTTPS 域名,保持 RCOM_VERIFY_TLS=true。 ## JSON OCR API POST /api/v1/ocr 必须且只能提供 image_base64 或 image_url。 ~~~json { "image_url": "https://example.com/image.jpg", "model_profile": "small", "include_raw": false, "auto_correct": false } ~~~ 成功响应: ~~~json { "success": true, "request_id": "request-id", "data": { "source": { "type": "url", "content_type": "image/jpeg", "size_bytes": 12345, "width": 1200, "height": 800, "frames": 1 }, "model_profile": "small", "text": "识别文本", "pages": [], "stats": { "pages": 1, "lines": 5, "text_chars": 32, "avg_score": 0.98 }, "queue_wait_ms": 14, "elapsed_ms": 286 } } ~~~ 错误响应统一包含 success=false、request_id 和 error.code/message/details。 ## 安全与资源限制 - URL 仅允许 HTTP/HTTPS、公网 IP、受控端口,并逐跳校验重定向。 - 校验请求体、图片字节数、真实格式、边长、总像素和帧数。 - 临时图片在请求结束后立即清理。 - 自动纠正、模型对比和 raw 结果默认关闭。 - 每个认证主体独立限流,默认每分钟 120 次。 - 登录默认每个来源每分钟最多 10 次。 - 管理端写操作要求 CSRF Token。 - 应用日志不记录密码、JWT、API Key、Base64 或识别文本。 - 日志按天轮转并保留 30 天;Docker stdout/stderr 另有大小限制。 公网部署必须使用 HTTPS 反向代理,并在代理层继续限制请求体、连接数和超时。 ## 验证 ~~~powershell .\.venv\Scripts\python.exe -m unittest discover -s tests -v ~~~ 测试使用模拟的 rcomOcrAdmin HTTP 服务,不访问 MySQL。