Spaces:
Sleeping
Sleeping
Claude
Replace retired zephyr default with a fallback chain of supported chat models
7ce911a unverified | title: Document Intelligence - OCR Data Extractor | |
| emoji: π | |
| colorFrom: blue | |
| colorTo: gray | |
| sdk: gradio | |
| sdk_version: 6.19.0 | |
| app_file: app.py | |
| pinned: false | |
| license: mit | |
| # Turn Documents Into Structured Business Data | |
| The real value isn't converting images into text β it's turning | |
| unstructured documents into reliable, actionable data. This tool takes | |
| scanned PDFs or images, runs them through OCR, and uses an AI-assisted | |
| extraction step (configured by describing what you need in plain | |
| language) to produce clean, audit-ready structured data. Built for: | |
| - **Construction / SAP data support** β change orders, delay notices, | |
| punch list items, RFIs, PO numbers, SAP document numbers, quantities. | |
| - **Compliance** β non-conformances, violations, expirations, corrective | |
| actions, certification codes (ISO, OSHA, ASTM, ANSI). | |
| - **Business finance** β past-due invoices, payment rejections, credit | |
| holds, invoice numbers, dollar amounts, due dates. | |
| ## Notifications vs. fields | |
| The tool treats two kinds of requests differently, rather than running | |
| one blanket extraction pass over every document: | |
| - **Notifications** β keyword/phrase hits that flag an event (a boolean | |
| "this happened on this page"), e.g. "past due", "non-compliant", | |
| "change order". Each category (construction/compliance/finance/general) | |
| has its own built-in phrase list; you can add your own custom | |
| notification keywords too. | |
| - **Fields** β labeled values extracted as data, not just flagged. | |
| Standard fields are *scoped to the categories you select* (see | |
| `CATEGORY_FIELD_MAP` in `extractors.py`) so a compliance document | |
| doesn't generate empty invoice-number columns: construction gets PO/SAP | |
| numbers, compliance gets certification codes, finance gets invoice | |
| numbers/percentages, and dates/amounts apply where relevant. On top of | |
| that, you can name your own **custom fields** β any label that appears | |
| in the document followed by a value (e.g. "reference number", "gross | |
| weight", "delivery date") β and the app finds the label and captures | |
| what follows it. | |
| ## How it works | |
| The app is a single guided flow: describe what you need, upload your | |
| documents, run and review. | |
| 1. **Step 1 - describe what you need** β in plain language (e.g. *"flag | |
| overdue invoices over $10k and non-compliance notices, and pull the | |
| reference number and gross weight"*), or tap one of the | |
| construction/compliance/finance starting-point buttons. A Hugging | |
| Face-hosted chat model turns that into extraction settings | |
| (categories, notification keywords, custom fields, export filter), | |
| shown live in the "Extraction plan" panel. You can also skip the chat | |
| and set everything by hand in the "Advanced" accordion in Step 2. | |
| 2. **Step 2 - upload your documents** β one or more PDFs or images. | |
| 3. Each page's text is pulled directly from the PDF when it has a text | |
| layer; scanned/image-only pages are rendered and run through | |
| Tesseract OCR. | |
| 4. The text is scanned for notification keywords and both standard and | |
| custom fields, per the scoping above. | |
| 5. Results are shown as two tidy (one-fact-per-row) tables β extracted | |
| fields and notification hits β and exported as three CSVs: | |
| - `ocr_fields_*.csv` β file, page, field_type (standard/custom), | |
| field_name, field_value, OCR source/confidence. | |
| - `ocr_notifications_*.csv` β file, page, category, keyword, context, | |
| OCR source/confidence. | |
| - `ocr_run_metadata_*.csv` β an audit record of exactly what produced | |
| the run: categories, notification keywords, custom fields, the | |
| match filter, the chat model used, and the full chat transcript. | |
| This is the lineage trail for anyone auditing why a given row was | |
| (or wasn't) extracted. | |
| Long/tidy tables were chosen over one wide fixed-schema table so that | |
| irrelevant fields never show up as blank columns, and so the output | |
| loads cleanly into a database, pivot table, or BI tool without | |
| reshaping β consistent with standard data-quality practice (e.g. DAMA | |
| DMBOK's completeness, validity, and lineage dimensions). | |
| ## Chat assistant setup | |
| The Step 1 assistant calls the Hugging Face Inference API, so it needs a token: | |
| - **On a Space:** add a repo secret named `HF_TOKEN` (Settings -> | |
| Variables and secrets) with a token that has Inference API access. | |
| - **Locally / as a fallback:** paste a token into the "Use your own | |
| Hugging Face token" accordion in Step 1; it's only used for that session. | |
| The token needs **Inference Providers** permission: use the simple | |
| "Read" token type, or on a fine-grained token check "Make calls to | |
| Inference Providers". | |
| The assistant tries `Qwen/Qwen2.5-7B-Instruct` first, then falls back to | |
| `mistralai/Mistral-7B-Instruct-v0.3` and `Qwen/Qwen2.5-72B-Instruct` if | |
| a provider doesn't carry it. Set an `HF_CHAT_MODEL` env var/Space | |
| variable to force a specific model instead. | |
| If the chat call fails or no token is available, the rest of the app | |
| still works fully via the "Advanced: edit settings manually" accordion | |
| in Step 2 β the chat is a convenience layer on top, not a dependency. | |
| ## Sample documents | |
| Three fictitious, clearly watermarked demo PDFs are generated on first | |
| launch (by `sample_docs/generate_samples.py` β they aren't committed, | |
| since the Hub requires LFS for binaries) and are loadable with one click | |
| from Step 2 (each button also presets the matching extraction settings, | |
| so Run works immediately): | |
| - **Construction change order** β PO/SAP numbers, cost overrun amounts, | |
| a safety-violation field note, OSHA cert reference (native text layer). | |
| - **Accounting / tax invoice** β invoice number, line items, tax rate, | |
| past-due/credit-hold language (native text layer). | |
| - **Bill of lading** β saved as an image-only "scanned" page, so it | |
| exercises the full Tesseract OCR path with confidence scores; custom | |
| fields pull BOL/reference numbers, weights, and delivery date. | |
| Every sample carries a "FICTITIOUS DATA - NOT REAL DATA" banner, | |
| watermark, and footer. Regenerate them manually with | |
| `python sample_docs/generate_samples.py`. | |
| ## Local development | |
| ```bash | |
| pip install -r requirements.txt | |
| # Tesseract must also be installed on the system, e.g.: | |
| # apt-get install tesseract-ocr | |
| export HF_TOKEN=hf_... # optional, enables the chat tab | |
| python app.py | |
| ``` | |
| ## Files | |
| - `app.py` β Gradio UI and orchestration. | |
| - `ocr_engine.py` β PDF/image loading and OCR (PyMuPDF + Tesseract). | |
| - `extractors.py` β keyword notification scanning, category-scoped | |
| standard field extraction, and generic label->value custom field | |
| extraction. | |
| - `chat_config.py` β chat assistant that turns natural-language | |
| instructions into extraction settings via a Hugging Face chat model. | |