Skip to content

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

  1. Evidence Map — what was inspected and confidence levels
  2. Product & System Overview — what it does and how pieces fit
  3. Backend Deep Dive — API, Celery tasks, OCR providers
  4. Frontend Deep Dive — dashboard, polling, preview
  5. Data Model & Storage — Redis hashes and job filesystem
  6. Infra & Local Ops — Docker, Makefile, env
  7. Security & Safety — auth gaps and file handling
  8. Testing & Quality — pytest coverage
  9. Unique Engineering Highlights — interview-worthy work
  10. Interview Prep — scripts and Q&A
  11. Risks & Next Steps — unknowns and hardening

Note: Chapter 02-agentic-ai-architecture is 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

  1. Async job API: submit → poll → download (md / html / zip).
  2. Default path is layout detection then per-block VLM, not classic Tesseract-style OCR.
  3. VLM_MODEL blank or Paddle-named → Paddle VL; otherwise LiteLLM routes any vision model.
  4. nvidia and sarvam are standalone extractors, not layout+block pipelines.
  5. No SQL database — Redis TTL (24h) + local jobs/ directories.
  6. Models are process singletons with optional prewarm on API and worker startup.
  7. Frontend is a single-page Vite app with 2s polling (no WebSockets, no router).
  8. No authentication on the API; CORS defaults to *.
  9. Docker full stack forces linux/amd64 because Paddle lacks official Linux ARM64 wheels.
  10. 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.