Skip to main content

🖋️ HandScribe OCR

Production-grade multilingual handwritten OCR for student notes

HandScribe Logo

CI Publish Docs License: GPL-3.0 Python 3.9+ Docker


What is HandScribe?

HandScribe extracts text from handwritten student notes in 80+ languages. It wraps three OCR engines — EasyOCR, PaddleOCR, and TrOCR — behind a single interface with advanced image preprocessing, a CLI, a REST API, and one-command Docker deployment.

Built for Tanzanian students. Designed for everyone.


Quick Start

Method Command
Docker (zero setup) docker run -p 8000:8000 ronaldgosso/handscribe
pip install pip install handscribe
From source git clone https://github.com/ronaldgosso/handscribe.git && cd handscribe && pip install -e .

Usage

CLI

handscribe extract notes.jpg -b easyocr -l en,sw     # extract text
handscribe extract notes.jpg --json                   # output as JSON
handscribe extract notes.jpg -o output.txt -c 0.6     # save to file
handscribe batch ./images/ -o ./results/               # batch process
handscribe compare notes.jpg -l en,sw                  # compare all backends

REST API

uvicorn ocr_engine.api:api --port 8000
# Interactive docs → http://localhost:8000/docs

curl -X POST http://localhost:8000/ocr \
  -F "file=@notes.jpg" -F "backend=easyocr" -F "languages=en,sw"

Python

from ocr_engine import OCREngine, OCRBackend

engine = OCREngine(backend=OCRBackend.EASYOCR, languages=["en", "sw"])
text = engine.extract_text("student_notes.jpg")

OCR Backends

Backend Best For Languages Speed Accuracy
EasyOCR Quick setup, mixed scripts 80+ ⚡⚡⚡ ⭐⭐⭐⭐
PaddleOCR Fast processing, documents 80+ ⚡⚡⚡⚡ ⭐⭐⭐⭐
TrOCR Handwriting accuracy English* ⚡⚡ ⭐⭐⭐⭐⭐

*TrOCR can be fine-tuned for other languages.

Language Codes

Language EasyOCR PaddleOCR
English en en
Swahili sw en (Latin script)
Arabic ar arabic
Hindi hi hi
French fr french

CI/CD Pipeline

HandScribe uses two separate GitHub Actions workflows:

Workflow File Triggers What It Does
CI ci.yml Push, PR Lint → Test → Build & push Docker image
Publish publish.yml Tag push (v*), Release, Manual Build & publish to PyPI
Pages pages.yml Push to main (docs/) Deploy landing page to GitHub Pages

How It Works

push / PR
   │
   ├── lint ─── ruff ─ black ─ mypy
   │
   └── test ─── pytest (41 tests, 60% coverage)
         │
         └── on main ── build & push Docker image to Docker Hub


push tag v0.1.0
   │
   └── publish ─── build ─── twine check ─── upload to PyPI

Status Badges

Badge Status
CI Build CI
PyPI Publish Publish

Publishing a Release

# 1. Bump version in pyproject.toml
# 2. Tag and push
git tag v0.1.0
git push origin v0.1.0

# → GitHub Actions auto-publishes to PyPI

Docker

docker run -p 8000:8000 ronaldgosso/handscribe        # run
docker build -t handscribe .                           # build
docker compose up -d                                   # compose

Full instructions in CONTRIBUTING.md.


Architecture

handscribe/
├── ocr_engine/
│   ├── engine.py            # Core OCR engine (3 backends)
│   ├── preprocessing.py     # Denoise, CLAHE, binarize, deskew
│   ├── cli.py               # CLI (Typer) — extract, batch, compare, info
│   └── api.py               # REST API (FastAPI) — /ocr, /ocr/text, /ocr/batch
├── tests/
│   └── test_engine.py       # 41 tests
├── .github/workflows/
│   ├── ci.yml               # Lint → Test → Docker
│   └── publish.yml          # Build → PyPI
├── Dockerfile               # Optimized single-stage build
├── docker-compose.yml
└── pyproject.toml

🔧 Add Other OCR Backends

EasyOCR is included by default. Add PaddleOCR or TrOCR as optional extras:

pip install handscribe[paddle]    # PaddleOCR — faster, document-style
pip install handscribe[trocr]     # TrOCR — highest handwriting accuracy
pip install handscribe[all]       # Both PaddleOCR + TrOCR
from ocr_engine import OCREngine, OCRBackend

# Switch backend at runtime
engine = OCREngine(backend=OCRBackend.PADDLE, languages=["en"])
engine = OCREngine(backend=OCRBackend.TROCR)

🧪 Development

git clone https://github.com/ronaldgosso/handscribe.git
cd handscribe
python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[all,dev]"
pytest tests/ -v

Full guide → CONTRIBUTING.md


Acknowledgments

  • EasyOCR — Jaided AI
  • PaddleOCR — PaddlePaddle
  • TrOCR — Microsoft
  • Tanzanian Students — the inspiration

Ronald Gosso — ronaldgosso@gmail.com · GitHub

Made with ❤️ for students everywhere

Metadata

Release files for handscribe 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for handscribe 0.1.2
File Size Uploaded
handscribe-0.1.2.tar.gz 29.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for handscribe 0.1.2
File Interpreter ABI Platform
handscribe-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 57.1 kB

Release files / handscribe-0.1.2.tar.gz

Download URL handscribe-0.1.2.tar.gz
Size 29.3 kB
Tags Source
SHA-256 checksum
How to use checksums
81a355d302e843141ccf8a161c820525a5d214263a0015229d565531a3d3bcd9
BLAKE2b-256 checksum
How to use checksums
bca6c50cad774c19f0d3b466c2bf793d67b86db1099d4d3b716fcbe911bc0599
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 9, 2026.

Transparency log

Release files / handscribe-0.1.2-py3-none-any.whl

Download URL handscribe-0.1.2-py3-none-any.whl
Size 27.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e729609a58297a994198c31973e1067a90c3b751b11e0fd29a33f12c917630b9
BLAKE2b-256 checksum
How to use checksums
16704f4e4283dd8d2a06220fe8946079f5f598c538e8266ecf18cfb883b8d185
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page