OCR Service — Codebase Interview Dossier¶
Repository: Hari31416/ocr-service (private)
Inspected checkout: repos/ocr-service (cloned 2026-07-09)
Package: paddle-ocr-service 0.1.0
Stack: Python 3.13 · FastAPI · Celery · Redis · PaddleOCR/PaddleX · LiteLLM · React 19 · Vite
Reading order¶
- Evidence Map — what was inspected and confidence levels
- Product & System Overview — what it does and how pieces fit
- Backend Deep Dive — API, Celery tasks, OCR providers
- Frontend Deep Dive — dashboard, polling, preview
- Data Model & Storage — Redis hashes and job filesystem
- Infra & Local Ops — Docker, Makefile, env
- Security & Safety — auth gaps and file handling
- Testing & Quality — pytest coverage
- Unique Engineering Highlights — interview-worthy work
- Interview Prep — scripts and Q&A
- Risks & Next Steps — unknowns and hardening
Note: Chapter
02-agentic-ai-architectureis omitted. This codebase is a deterministic OCR/VLM pipeline, not an agent loop with tools or planning.
Preview and export¶
From projects/ocr-service/:
make serve # MkDocs live preview
make build # Static site → site-dossier/
make consolidate # Single Markdown file
make pdf # PDF via md2pdf (requires install-md2pdf)
Executive summary¶
Universal OCR Service turns PDFs and images into structured Markdown and HTML. FastAPI accepts uploads and returns a job_id; Celery workers run layout detection (PP-DocLayoutV3) and/or vision-language transcription; Redis holds ephemeral job state; results land on the local filesystem under jobs/.
Four provider modes share one job API: layout (default hybrid), vlm (whole-page LiteLLM), nvidia (NeMo Retriever Parse NIM), and sarvam (Sarvam Vision API). A React dashboard uploads files, selects mode, polls every 2s, and previews HTML/Markdown.
The core engineering bet is layout-aware multimodal OCR with a pluggable VLM client, process-level model caching, and parallel per-block inference — without introducing a permanent document database.
System map¶
graph TD
classDef default fill:#1e293b,stroke:#38bdf8,stroke-width:2px,color:#f8fafc
classDef highlight fill:#065f46,stroke:#34d399,stroke-width:2px,color:#f0fdf4
classDef warning fill:#78350f,stroke:#fbbf24,stroke-width:2px,color:#fffbeb
UI["React Dashboard"]:::highlight
API["FastAPI /ocr"]
R0["Redis DB 0<br/>job hashes"]
R1["Redis DB 1<br/>Celery broker"]
W["Celery worker<br/>pool=solo"]
FS["jobs/{id}/ artifacts"]
LAY["PP-DocLayoutV3"]
VLM["VLMClient<br/>Paddle / LiteLLM"]
NIM["NVIDIA NIM"]
SAR["Sarvam API"]
UI --> API
API --> R0
API --> R1
API --> FS
W --> R0
W --> R1
W --> FS
W --> LAY
W --> VLM
W --> NIM
W --> SAR
linkStyle default stroke:#64748b,stroke-width:2px
The API is thin orchestration. Heavy work stays in the worker, which branches by vlm_mode and writes progress back to Redis for the UI to poll.
Diagram index¶
| Topic | Chapter |
|---|---|
| High-level architecture | 01 |
| Job lifecycle sequence | 01 |
| Provider mode branching | 03 |
| Job state machine | 05 |
| Local / Docker topology | 06 |
Top 10 things to know¶
- Async job API: submit → poll → download (
md/html/zip). - Default path is layout detection then per-block VLM, not classic Tesseract-style OCR.
VLM_MODELblank or Paddle-named → Paddle VL; otherwise LiteLLM routes any vision model.nvidiaandsarvamare standalone extractors, not layout+block pipelines.- No SQL database — Redis TTL (24h) + local
jobs/directories. - Models are process singletons with optional prewarm on API and worker startup.
- Frontend is a single-page Vite app with 2s polling (no WebSockets, no router).
- No authentication on the API; CORS defaults to
*. - Docker full stack forces
linux/amd64because Paddle lacks official Linux ARM64 wheels. - Project already ships rich MkDocs under
docs/in the source repo.
Most impressive engineering¶
- Hybrid layout + label-specific VLM prompts with figure embedding as base64
- Unified job surface over four very different providers
- LiteLLM as the escape hatch for any vision model without rewriting the pipeline
- NVIDIA path resilience (JPEG size backoff, partial page success, Gemma fallback)
Report coverage¶
| File | Focus |
|---|---|
| 00 | Evidence and confidence |
| 01 | Product and architecture |
| 03 | Backend and OCR pipeline |
| 04 | React dashboard |
| 05 | Redis + filesystem |
| 06 | Ops and Docker |
| 07 | Security posture |
| 08 | Tests |
| 09 | Highlights |
| 10 | Interview scripts |
| 11 | Gaps and risks |
Open questions (preview)¶
No client auth; upload size only claimed in UI; Redis TTL vs disk retention cleanup; compose password mismatch between local and full stacks; worker_prefetch_multiplier=4 vs “one task” comment. Details in 11.