Skip to main content

Rustcha

rustcha recognizes CAPTCHA text from encoded images. The Python API uses a Rust extension and bundled ONNX models, so inference does not require a network connection.

Install

uv add rustcha

The package supports CPython 3.11 through 3.15. Building from source requires Rust 1.88 or newer.

Recognize text

Pass encoded image bytes, a path string, or a pathlib.Path:

from rustcha import Rustcha

recognizer = Rustcha()
result = recognizer.recognize(image_bytes)

print(result.text)
print(result.confidence)

allowed_characters constrains decoding to a known alphabet:

digits = recognizer.recognize(image_bytes, allowed_characters="0123456789")

Confidence is the geometric mean of the selected character probabilities. It is None when the model returns no characters.

Detect character regions

The detection model loads on first use. Set preload_detection=True if you prefer to pay that cost when constructing the recognizer.

recognizer = Rustcha(preload_detection=True)
result = recognizer.detect(image_bytes)

for box in result.boxes:
    print(box.x_min, box.y_min, box.x_max, box.y_max, box.confidence)

include_positions=True pairs recognized characters with detections from left to right:

result = recognizer.recognize(image_bytes, include_positions=True)

for item in result.character_positions:
    print(item.character, item.box)

OCR and detection are separate model passes. Their result counts can differ; an unmatched character has box=None. Call detect() when you need every detection.

Batches and asyncio

One recognizer reuses one OCR session. batch_size limits how many encoded images enter one native call; the model still evaluates images one at a time.

results = recognizer.batch_recognize(images, batch_size=10)

AsyncRustcha moves work to a worker thread. Calls on the same instance are serialized so they can reuse the same native sessions.

from rustcha import AsyncRustcha

recognizer = AsyncRustcha()
result = await recognizer.recognize(image_bytes)

Input limits

Encoded input is limited to 32 MiB. Decoded width and height are each limited to 8,192 pixels, and image decoders receive a 128 MiB allocation budget. These limits keep malformed or unexpectedly large inputs from consuming unbounded memory. They are not a substitute for request-size limits and timeouts in a service that accepts public uploads.

Models and license

The Python API, Rust implementation, packaging, tests, and automation in this repository are original work by Henrique Moreira and are distributed under the project's MIT license. rustcha was inspired by sml2h3/ddddocr, but has its own implementation and public API.

The bundled OCR and detection ONNX models come from ddddocr and are distributed under its MIT license. The OCR character map is derived from that project's CHARSET_BETA, so it is attributed with the models. Exact source details and checksums are recorded in THIRD_PARTY_NOTICES.md, and the upstream license is included in licenses/ddddocr-LICENSE.

OCR output is probabilistic. Do not use it as an authentication or authorization decision without independent validation.

Development

uv sync --all-groups
uv run maturin develop
just check

just check runs Python lint and type checks, Rust formatting and Clippy, Rust unit tests, lockfile checks, and Python integration tests.

Every push to prod checks the versions in pyproject.toml, Cargo.toml, and uv.lock. When they match and are newer than the latest v* tag, GitHub Actions builds CPython 3.11–3.15 ABI3 wheels for Linux, macOS ARM64, and Windows, publishes them to PyPI with uv, then creates the tag and GitHub release. Release notes list the commits since the previous tag in Keep a Changelog-style Added, Changed, Fixed, and Removed sections.

The repository must contain a PYPI_API_TOKEN Actions secret. A failed release can be resumed with the Publish Release workflow's manual trigger; identical files already present on PyPI are checked before upload.

Metadata

Release files for rustcha 0.1.0

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

Source distribution (sdist)

Source distribution for rustcha 0.1.0
File Size Uploaded
rustcha-0.1.0.tar.gz 69.1 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for rustcha 0.1.0
File
rustcha-0.1.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
rustcha-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl CPython 3.11 abi3 Linux glibc 2.28+ x86-64 Details
rustcha-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl CPython 3.11 abi3 Linux glibc 2.28+ ARM64 Details
rustcha-0.1.0-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details

Total release size: 379.2 MB

Release files / rustcha-0.1.0.tar.gz

Download URL rustcha-0.1.0.tar.gz
Size 69.1 MB
Tags Source
SHA-256 checksum
How to use checksums
f1628331d037fc906a480560c34667078839cb77ae6d86f73984de05929c4633
BLAKE2b-256 checksum
How to use checksums
9c24f054248df8e2d247d167cfe4f8c2bd7eb0d1ebf5544c5311842f9a4d237c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / rustcha-0.1.0-cp311-abi3-win_amd64.whl

Download URL rustcha-0.1.0-cp311-abi3-win_amd64.whl
Size 76.6 MB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
8f309fd1cb42cad96ba0b6a9af17e5ec932cbb3c7779c122c911e423757249ae
BLAKE2b-256 checksum
How to use checksums
5f4a87dbff6466e2a3479e4d033a52887f721e535a4cc49e05df5999dbe669c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / rustcha-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl

Download URL rustcha-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl
Size 78.1 MB
Tags CPython 3.11 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
5268e06f353c0c6d00af91209280e34e069ea80eb6ca905dda7f3bbebc99cb2d
BLAKE2b-256 checksum
How to use checksums
bff8339334387858a18a25429611674e3f197c94b36070cf3deac210382501c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / rustcha-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl

Download URL rustcha-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl
Size 78.8 MB
Tags CPython 3.11 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
51a3f9c7b48a5e7f1e501a0b92d04d44bc29c7f947a8e7f92d67ea5fe4c0389f
BLAKE2b-256 checksum
How to use checksums
659a7675a56dfd77bc8f261718233d921344bf88ed7ccae0d4c6674f41c6c3a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / rustcha-0.1.0-cp311-abi3-macosx_11_0_arm64.whl

Download URL rustcha-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
Size 76.6 MB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c6d82f989fd74acf366fd564a6eba493410e05878cd91b74511e707534abd24d
BLAKE2b-256 checksum
How to use checksums
eb21c3aba8576be4ad6ac4eab5154cd182cf2dff92e3f7e40fac4077c56af6d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.0 This release

5 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