bro-ocr
- lightweight pydantic wrapper for quick OCR prototyping
- aims to speed up your work on OCR with an llm-agnostic approach
- constructing prompts, extracting information, validating result schemas — plug bro-ocr into your pipeline and it's handled
the problem
every OCR-with-LLM project ends up hand-rolling the same three things: crop the region you care about, describe what you want back as a schema, then validate whatever JSON the model hands back. bro-ocr turns that into two objects instead of a pile of copy-pasted glue code — and it never locks you into a specific LLM provider.
two objects you need to know
Template — serves as data model and configuration.
- an image has a size (
w,h) and a list ofpatches(regions of interest) - each
Patchis a bounding box (x,y,w,h) plus its ownschemasand an optionalinstruction - each
Schemais one field to extract — afieldname, adtype, and an optional per-fieldinstruction
it's just data. build it once, reuse it for every document of that layout.
SchemaConverter — integrates with Template to create a dynamic pydantic data model, usable as both a schema builder and a schema validator.
from_single— exactly one field (e.g.total_amount: float)from_object— a flat group of fields (e.g.year,month,day)from_list— a repeating group wrapped in a list (e.g. lineitems)
same model, two jobs: dump .model_json_schema() into your prompt so the LLM knows the shape you want back, then call .model_validate_json(...) on the response to make sure it actually came back that shape.
install
pre-1.0, not on PyPI yet. clone it and install editable:
uv pip install -e .
quickstart
define a patch and its schema:
from bro_ocr.core.template import Dtype, Patch, Schema, SchemaType, Template
total_amount = Patch(
name="total_amount",
x=455, y=564, w=86, h=25,
schema_type=SchemaType.SINGLE,
schemas=[Schema(field="total_amount", dtype=Dtype.FLOAT)],
instruction="amount is in float",
)
template = Template(name="invoice", w=578, h=750, patches=[total_amount])
turn it into a pydantic model, use it both ways:
from bro_ocr.utils.conversion import SchemaConverter as sc
model = sc.from_single(total_amount.name, total_amount.schemas)
# 1. shape your prompt
model.model_json_schema()
# 2. validate what the LLM sent back
model.model_validate_json('{"total_amount": 551.56}')
from_object (flat group of fields) and from_list (repeating rows) work the same way. See notebooks/dev.ipynb for a full invoice walkthrough covering all three SchemaTypes, cropping patches out of a real image with cv2, and a worked example calling a vision model over AWS Bedrock.
bring your own LLM
bro-ocr doesn't ship an LLM client and never will — that's the agnostic part. it preps the region, builds the schema, validates the response. wiring up OpenAI, Anthropic, Bedrock, a local VLM, whatever — that's on you, and it's about 20 lines (see the notebook for one way to do it).
status
early days — Template + SchemaConverter is the whole lite core for now. more pieces (prompt packing, provider adapters, etc.) land later as opt-in extras without touching this base.
license
Apache 2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bro_ocr-0.1.1.tar.gz.
File metadata
- Download URL: bro_ocr-0.1.1.tar.gz
- Upload date:
- Size: 124.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18dee43f2ef0ca0fb485f70879c5df9e3d1bbdda329cf2e94d501d3cca2f597d
|
|
| MD5 |
f0e2b648fcc4303b2a848ec754dc9dbb
|
|
| BLAKE2b-256 |
e08e4ee8b96313cbdf43bdd70ef8f64481e0a3bd96e495c1e816d5645eeb3a35
|
Provenance
The following attestation bundles were made for bro_ocr-0.1.1.tar.gz:
Publisher:
publish.yml on datanooblol/bro-ocr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bro_ocr-0.1.1.tar.gz -
Subject digest:
18dee43f2ef0ca0fb485f70879c5df9e3d1bbdda329cf2e94d501d3cca2f597d - Sigstore transparency entry: 2565479034
- Sigstore integration time:
-
Permalink:
datanooblol/bro-ocr@377270534609e20fe6658e8f3dd1788fdaedb750 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/datanooblol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@377270534609e20fe6658e8f3dd1788fdaedb750 -
Trigger Event:
push
-
Statement type:
File details
Details for the file bro_ocr-0.1.1-py3-none-any.whl.
File metadata
- Download URL: bro_ocr-0.1.1-py3-none-any.whl
- Upload date:
- Size: 8.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d73c533b8aa365dfe517b4e7b2077080ae8fa3d31bd9e33aebfce85430203173
|
|
| MD5 |
12fc61497df50fce20b5d2df608acba7
|
|
| BLAKE2b-256 |
4361b72f5333c66c5456c9dd3164fc13c73d8eea3ae7f70f970db181e2c369ca
|
Provenance
The following attestation bundles were made for bro_ocr-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on datanooblol/bro-ocr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bro_ocr-0.1.1-py3-none-any.whl -
Subject digest:
d73c533b8aa365dfe517b4e7b2077080ae8fa3d31bd9e33aebfce85430203173 - Sigstore transparency entry: 2565479466
- Sigstore integration time:
-
Permalink:
datanooblol/bro-ocr@377270534609e20fe6658e8f3dd1788fdaedb750 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/datanooblol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@377270534609e20fe6658e8f3dd1788fdaedb750 -
Trigger Event:
push
-
Statement type: