From d43897c64c7a16f9cd83e827bc642cf90b6c354b Mon Sep 17 00:00:00 2001 From: yml Date: Tue, 19 May 2026 23:10:33 +0800 Subject: [PATCH] [Snow Team] ocr-python: auto-commit work --- .../subservices/ocr-worker/pyproject.toml | 2 ++ .../ocr-worker/src/ocr_worker/server.py | 34 +++++++++++++++++++ deploy/docker/ocr-worker.Dockerfile | 33 ++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 apps/backend/subservices/ocr-worker/src/ocr_worker/server.py create mode 100644 deploy/docker/ocr-worker.Dockerfile diff --git a/apps/backend/subservices/ocr-worker/pyproject.toml b/apps/backend/subservices/ocr-worker/pyproject.toml index f02808d0..a400a78d 100644 --- a/apps/backend/subservices/ocr-worker/pyproject.toml +++ b/apps/backend/subservices/ocr-worker/pyproject.toml @@ -5,6 +5,8 @@ readme = "README.md" requires-python = ">=3.11" dependencies = [ "ddddocr>=1.6.1", + "fastapi>=0.115.0", + "uvicorn>=0.34.0", ] [project.scripts] diff --git a/apps/backend/subservices/ocr-worker/src/ocr_worker/server.py b/apps/backend/subservices/ocr-worker/src/ocr_worker/server.py new file mode 100644 index 00000000..da06a129 --- /dev/null +++ b/apps/backend/subservices/ocr-worker/src/ocr_worker/server.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +import asyncio +from contextlib import asynccontextmanager + +from fastapi import FastAPI + +from .engine import get_ocr_engine +from .cli import recognize_payload, batch_recognize_payload + + +@asynccontextmanager +async def lifespan(app: FastAPI): + # Eagerly load model on startup + get_ocr_engine() + yield + + +app = FastAPI(lifespan=lifespan) + + +@app.get("/health") +async def health(): + return {"code": 0, "msg": "ok"} + + +@app.post("/ocr/recognize") +async def recognize(payload: dict): + return await asyncio.to_thread(recognize_payload, payload) + + +@app.post("/ocr/batch") +async def batch_recognize(payload: dict): + return await asyncio.to_thread(batch_recognize_payload, payload) diff --git a/deploy/docker/ocr-worker.Dockerfile b/deploy/docker/ocr-worker.Dockerfile new file mode 100644 index 00000000..cb7d446c --- /dev/null +++ b/deploy/docker/ocr-worker.Dockerfile @@ -0,0 +1,33 @@ +FROM python:3.11-slim-bookworm + +ARG DEBIAN_MIRROR=mirrors.cloud.tencent.com +ARG PIP_INDEX_URL=https://mirrors.cloud.tencent.com/pypi/simple + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Asia/Shanghai + +# NOTE: Use Debian official HTTP sources (not Tencent mirrors) because: +# slim image has no ca-certificates pre-installed, and Tencent mirrors +# redirect HTTP → HTTPS which fails without TLS certs (chicken-and-egg). +# Debian official HTTP sources work without TLS. Apt packages are GPG-signed. +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update \ + && apt-get install -y --no-install-recommends curl ca-certificates \ + && ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \ + && echo ${TZ} > /etc/timezone \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY apps/backend/subservices/ocr-worker/ ./ocr-worker/ +RUN --mount=type=cache,target=/root/cache/pip \ + pip install --no-cache-dir -i ${PIP_INDEX_URL} ./ocr-worker + +EXPOSE 8100 + +HEALTHCHECK --interval=5s --timeout=5s --retries=20 --start-period=15s \ + CMD curl -fsS http://127.0.0.1:8100/health || exit 1 + +CMD ["uvicorn", "ocr_worker.server:app", "--host", "0.0.0.0", "--port", "8100"]