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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rustcha-0.1.0.tar.gz (69.1 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rustcha-0.1.0-cp311-abi3-win_amd64.whl (76.6 MB view details)

Uploaded CPython 3.11+Windows x86-64

rustcha-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl (78.1 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ x86-64

rustcha-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl (78.8 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ ARM64

rustcha-0.1.0-cp311-abi3-macosx_11_0_arm64.whl (76.6 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

File details

Details for the file rustcha-0.1.0.tar.gz.

File metadata

  • Download URL: rustcha-0.1.0.tar.gz
  • Upload date:
  • Size: 69.1 MB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for rustcha-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f1628331d037fc906a480560c34667078839cb77ae6d86f73984de05929c4633
MD5 a962081c26e7a11790b10ee2d6dc0b33
BLAKE2b-256 9c24f054248df8e2d247d167cfe4f8c2bd7eb0d1ebf5544c5311842f9a4d237c

See more details on using hashes here.

File details

Details for the file rustcha-0.1.0-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: rustcha-0.1.0-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 76.6 MB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using 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}

File hashes

Hashes for rustcha-0.1.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 8f309fd1cb42cad96ba0b6a9af17e5ec932cbb3c7779c122c911e423757249ae
MD5 90224b19c653d8e3626149fed480d473
BLAKE2b-256 5f4a87dbff6466e2a3479e4d033a52887f721e535a4cc49e05df5999dbe669c0

See more details on using hashes here.

File details

Details for the file rustcha-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl.

File metadata

  • Download URL: rustcha-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 78.1 MB
  • Tags: CPython 3.11+, manylinux: glibc 2.28+ x86-64
  • Uploaded using 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}

File hashes

Hashes for rustcha-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5268e06f353c0c6d00af91209280e34e069ea80eb6ca905dda7f3bbebc99cb2d
MD5 a74a63d9dc6c930a5b85a4e5cac7197c
BLAKE2b-256 bff8339334387858a18a25429611674e3f197c94b36070cf3deac210382501c9

See more details on using hashes here.

File details

Details for the file rustcha-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl.

File metadata

  • Download URL: rustcha-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl
  • Upload date:
  • Size: 78.8 MB
  • Tags: CPython 3.11+, manylinux: glibc 2.28+ ARM64
  • Uploaded using 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}

File hashes

Hashes for rustcha-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 51a3f9c7b48a5e7f1e501a0b92d04d44bc29c7f947a8e7f92d67ea5fe4c0389f
MD5 fe9661358d67e5ad6f3b7ba4fef78355
BLAKE2b-256 659a7675a56dfd77bc8f261718233d921344bf88ed7ccae0d4c6674f41c6c3a7

See more details on using hashes here.

File details

Details for the file rustcha-0.1.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

  • Download URL: rustcha-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 76.6 MB
  • Tags: CPython 3.11+, macOS 11.0+ ARM64
  • Uploaded using 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}

File hashes

Hashes for rustcha-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c6d82f989fd74acf366fd564a6eba493410e05878cd91b74511e707534abd24d
MD5 261c9f81e0d3a44559c1824a1f7df9e9
BLAKE2b-256 eb21c3aba8576be4ad6ac4eab5154cd182cf2dff92e3f7e40fac4077c56af6d5

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

5 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page