Skip to main content

PaddleOCR Implementation

This guide shows how to build and deploy an OCR API using FastAPI and PaddleOCR. The final system lets a user upload an image, sends it to a Python API, runs PaddleOCR, and returns extracted text through a secure HTTPS endpoint.

Final Architecture​

AI Document Intelligence PipelineWorkflow from document upload through FastAPI, PaddleOCR, LLM processing, and structured output.AI Document Intelligence PipelineFastAPI + PaddleOCR + LLM Cleanup using DeepSeek or ChatGPT1. Input Sources⬆ Upload FileπŸ–Ό ImagesπŸ“• PDF DocumentsπŸ“„ Scanned Forms2. FastAPI Backend⚑ FastAPIUpload Endpoint: /ocrPaddleOCRAI OCR Engineβœ“ Text Detectionβœ“ Text Recognitionβœ“ Table / Layout Structure3. Extracted DataπŸ“ƒ Text Contentβ–¦ Tables / RowsπŸ”‘ Key-Value Pairsβ–£ Bounding Boxes{ raw_text, boxes, confidence }4. LLM ProcessingSend OCR Data + PromptPrompt example:β€œClean OCR text, extract fields,detect anomalies, return JSON.”DeepSeekORChatGPT5. AI OutputClean SummaryJSON FieldsInsightsAlerts{ total: 1250, anomaly: none, confidence: 98%}6. Storage OptionalπŸ“ Save FilesπŸ›’ Database7. Frontend / ClientπŸ’» DashboardπŸ“Š Reportsβœ… ReviewKey Benefitsβœ“ High accuracy OCRβœ“ Structured JSONβœ“ LLM cleanupβœ“ FastAPI readySimple Flow1. Upload image/PDF2. FastAPI receives file3. PaddleOCR extracts text4. LLM cleans data5. Clean JSON/result to user

AI document intelligence workflow from upload through OCR, extraction, validation, review, and final output.

User
|
v
Next.js frontend
|
v
FastAPI backend on VPS
|
v
PaddleOCR engine
|
v
Text result

The production flow is:

https://api.yoursite.com/ocr
|
v
Nginx reverse proxy
|
v
FastAPI running on 127.0.0.1:8000
|
v
PaddleOCR

What You Need​

  • A Python backend project.
  • A VPS running Ubuntu 22.04 or newer.
  • A domain from Namecheap, GoDaddy, or another registrar.
  • SSH access to the VPS.
  • Basic GitHub repository access.

Use at least 2 GB RAM for a small PaddleOCR server. For high-volume OCR or large PDFs, use a larger VPS or a GPU-backed worker.

Build The Backend​

Create the project:

mkdir ocr-project
cd ocr-project
mkdir backend
cd backend

Create and activate a virtual environment:

python3 -m venv venv
source venv/bin/activate

Install the backend packages:

pip install fastapi uvicorn paddleocr paddlepaddle python-multipart

Create main.py:

from fastapi import FastAPI, UploadFile, File
from paddleocr import PaddleOCR
import os
import shutil
import uuid

app = FastAPI()
ocr = PaddleOCR(use_angle_cls=True, lang="en")


@app.get("/health")
def health():
return {"ok": True}


@app.post("/ocr")
async def run_ocr(file: UploadFile = File(...)):
os.makedirs("uploads", exist_ok=True)
temp_file = f"uploads/{uuid.uuid4()}.jpg"

with open(temp_file, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)

result = ocr.ocr(temp_file)

text = ""
for page in result:
for line in page:
text += line[1][0] + "\n"

os.remove(temp_file)

return {"text": text}

Run locally:

uvicorn main:app --reload

Open:

http://127.0.0.1:8000/health
http://127.0.0.1:8000/docs

Use /docs to upload an image and test /ocr.

Run An Existing Project​

If the project already exists and has an app/ folder, run it from the project root, not from inside app.

cd path/to/idsp-py
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Then try the most common FastAPI import path:

uvicorn app.main:app --reload

If that fails, inspect the app folder:

ls app

Other common run commands are:

uvicorn app.api:app --reload
uvicorn app.server:app --reload

Open the API docs:

http://127.0.0.1:8000/docs

For a live VPS server, run:

uvicorn app.main:app --host 0.0.0.0 --port 8000

Fix PaddlePaddle Install Errors​

If installation fails with:

ERROR: No matching distribution found for paddlepaddle==3.2.0

the pinned version in requirements.txt is not available for your Python and operating system combination.

Change:

paddlepaddle==3.2.0

to:

paddlepaddle

or use a newer supported version:

paddlepaddle==3.3.1

Then reinstall:

pip install --upgrade pip setuptools wheel
pip install -r requirements.txt

If it still fails, install PaddlePaddle and PaddleOCR manually first:

pip install paddlepaddle
pip install paddleocr
pip install -r requirements.txt

Check your Python version:

python3 --version

Use Python 3.10 or 3.11 when possible. PaddlePaddle wheels depend on Python version, CPU architecture, and operating system.

Buy And Prepare A VPS​

Create a VPS from a provider such as DigitalOcean or Hetzner.

Recommended starting setup:

  • Ubuntu 22.04.
  • 2 GB RAM minimum.
  • SSH access enabled.

Connect to the server:

ssh root@YOUR_SERVER_IP

Install server packages:

apt update
apt install python3 python3-pip python3-venv nginx git -y

Upload Code To VPS​

Push the backend to GitHub from your computer:

git init
git add .
git commit -m "first commit"
git remote add origin https://github.com/yourname/ocr-project.git
git push -u origin main

Clone it on the VPS:

git clone https://github.com/yourname/ocr-project.git
cd ocr-project/backend

Install the backend:

python3 -m venv venv
source venv/bin/activate
pip install fastapi uvicorn paddleocr paddlepaddle python-multipart

Run it:

uvicorn main:app --host 0.0.0.0 --port 8000

Test:

http://YOUR_SERVER_IP:8000/health

Keep The App Running With Supervisor​

Do not rely on a terminal session to keep the API alive. Use Supervisor.

Install Supervisor:

apt install supervisor -y

Create the config:

nano /etc/supervisor/conf.d/ocr.conf

Paste:

[program:ocr]
directory=/root/ocr-project/backend
command=/root/ocr-project/backend/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000
autostart=true
autorestart=true

Start the program:

supervisorctl reread
supervisorctl update
supervisorctl start ocr

The API now runs locally on the VPS at:

http://127.0.0.1:8000

Nginx will expose it publicly.

Connect A Domain​

In your domain provider, open DNS or Advanced DNS settings.

Add an A record:

Type: A Record
Host: api
Value: YOUR_SERVER_IP
TTL: Automatic

This maps:

api.yoursite.com -> YOUR_SERVER_IP

DNS propagation usually takes 5 to 30 minutes, but it can take longer.

Test:

ping api.yoursite.com

Configure Nginx​

Create a site config:

nano /etc/nginx/sites-available/ocr

Paste:

server {
listen 80;
server_name api.yoursite.com;

location / {
proxy_pass http://127.0.0.1:8000;
}
}

Enable it:

ln -s /etc/nginx/sites-available/ocr /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx

Test:

http://api.yoursite.com/health

Add HTTPS With Certbot​

Install Certbot:

apt install certbot python3-certbot-nginx -y

Generate SSL:

certbot --nginx -d api.yoursite.com

Follow the prompts:

  • Enter your email.
  • Agree to the terms.
  • Choose HTTP to HTTPS redirect.

Test:

https://api.yoursite.com/health

Certbot automatically renews Let's Encrypt certificates before they expire.

Update The App​

On your computer:

git add .
git commit -m "update"
git push

On the VPS:

cd /root/ocr-project/backend
git pull
source venv/bin/activate
supervisorctl restart ocr

Optional Docker Deployment​

Docker keeps deployment consistent across machines and avoids many dependency issues.

Install Docker:

apt update
apt install docker.io -y
systemctl start docker
systemctl enable docker

Create Dockerfile inside the backend folder:

FROM python:3.10

WORKDIR /app

COPY . .

RUN pip install --no-cache-dir fastapi uvicorn paddleocr paddlepaddle python-multipart

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Build the image:

docker build -t ocr-api .

Run the container:

docker run -d -p 8000:8000 ocr-api

Test:

http://YOUR_SERVER_IP:8000/health

With Docker, the production path is:

Domain -> Nginx -> Docker container -> FastAPI -> PaddleOCR

To update:

git pull
docker build -t ocr-api .
docker stop $(docker ps -q)
docker run -d -p 8000:8000 ocr-api

For multiple containers, use Docker Compose instead of stopping every running container.

Production Checklist​

  • Use /health for uptime checks.
  • Keep uploaded files in a temporary folder and delete them after OCR.
  • Store original documents only when the product requires it.
  • Put FastAPI behind Nginx instead of exposing Uvicorn directly.
  • Use HTTPS for all public endpoints.
  • Use Supervisor, systemd, or Docker to keep the process running.
  • Log OCR failures and slow requests.
  • Add file size limits before accepting uploads.
  • Validate extracted text before using it for business decisions.

Final Understanding​

  • VPS is your online server.
  • GitHub stores and transfers your code.
  • FastAPI exposes the OCR API.
  • PaddleOCR reads text from images and documents.
  • Supervisor keeps the Python API running.
  • Nginx routes public traffic to the local API.
  • SSL makes the API secure with HTTPS.
  • Docker makes deployment easier and repeatable.

Frontend platforms like Vercel auto-deploy from GitHub, but backend APIs on a VPS require manual setup. You connect through SSH, pull the code, run the app, route traffic with Nginx, secure it with SSL, and optionally use Docker for simplified deployment.