Metadata-Version: 2.4
Name: terbium-parse
Version: 2.0.0
Summary: A god-level algorithmic multi-file parser (PDF/PPTX/XLSX/CSV) that scores its own confidence and only reaches for AI when it is genuinely stuck.
Author: anishfyi
License: MIT
Project-URL: Homepage, https://velofy.co/terbium/
Project-URL: Documentation, https://velofy.co/terbium/
Project-URL: Repository, https://github.com/velofy/terbium
Project-URL: Changelog, https://velofy.co/terbium/changelog/
Keywords: parser,pdf,pptx,xlsx,csv,extraction,document,ai,llm
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Text Processing :: General
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PyMuPDF>=1.24
Requires-Dist: python-pptx>=0.6.23
Requires-Dist: openpyxl>=3.1
Requires-Dist: pillow>=10.0
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.34; extra == "anthropic"
Provides-Extra: openai
Requires-Dist: openai>=1.45; extra == "openai"
Provides-Extra: kimi
Requires-Dist: openai>=1.45; extra == "kimi"
Provides-Extra: grok
Requires-Dist: openai>=1.45; extra == "grok"
Provides-Extra: gemini
Requires-Dist: google-generativeai>=0.7; extra == "gemini"
Provides-Extra: ai
Requires-Dist: anthropic>=0.34; extra == "ai"
Requires-Dist: openai>=1.45; extra == "ai"
Requires-Dist: google-generativeai>=0.7; extra == "ai"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Dynamic: license-file

<p align="center">
  <a href="https://velofy.co/terbium/"><picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/velofy/terbium/main/assets/tile-dark.svg">
    <img alt="terbium" src="https://raw.githubusercontent.com/velofy/terbium/main/assets/tile-light.svg" width="360">
  </picture></a>
</p>

<p align="center"><strong>Business documents in. Clean rows out.</strong></p>

<p align="center">
  <a href="https://pypi.org/project/terbium-parse/"><img alt="PyPI" src="https://img.shields.io/pypi/v/terbium-parse?label=pypi&color=12130f"></a>
  <a href="https://github.com/velofy/terbium/blob/main/pyproject.toml"><img alt="Python 3.9+" src="https://img.shields.io/badge/python-3.9+-12130f"></a>
  <a href="https://github.com/velofy/terbium/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-12130f"></a>
</p>

<p align="center">
  <a href="https://velofy.co/terbium/">Documentation</a> ·
  <a href="https://velofy.co/terbium/quickstart/">Quickstart</a> ·
  <a href="https://github.com/velofy/terbium/blob/main/CHANGELOG.md">Changelog</a> ·
  <a href="https://github.com/velofy/terbium/releases">Releases</a> ·
  <a href="https://github.com/anishfyi/trove">Trove</a>
</p>

terbium parses business documents (vendor catalogues first, plus invoices, receipts, resumes, price lists and decks) into clean rows. It rebuilds structure from the position of every word, scores its own confidence, and only calls an AI model when the algorithm cannot be sure.

---

<h3 align="center">Sponsors</h3>

<p align="center"><strong>Primary sponsor</strong></p>

<p align="center">
  <a href="https://go.nodemaven.com/terbiumreadmeoct" title="NodeMaven: best proxy for web scraping and automation">
    <img src="https://velofy.co/images/sponsors/nodemaven-banner.webp" alt="NodeMaven: best proxy for web scraping and automation with the highest quality IP" width="720">
  </a>
</p>

**[NodeMaven](https://go.nodemaven.com/terbiumreadmeoct)**: the most efficient proxy provider for web scraping and automation, with the highest quality IPs on the market.

Why [NodeMaven](https://go.nodemaven.com/terbiumreadmeoct)?

- ZIP targeting
- 99.9% uptime
- IP filtering: every proxy has a fraud score under 97%
- No KYC required
- Free tools: Proxy Bandwidth Checker, Meta Tag Checker, IP Lookup and more

Codes for terbium users: `TERBIUM35` for 35% off mobile and residential proxies, `TERBIUM40` for 40% off ISP (static) proxies.

---

## Install

```bash
pip install terbium-parse
```

The PyPI name is `terbium-parse`; you `import terbium`, and the command is `terbium`. (The PyPI project named `terbium` is unrelated.) `terbium --version` prints the installed version.

Optional AI lanes: `pip install "terbium-parse[anthropic]"` (or `openai`, `kimi`, `grok`, `gemini`, or `ai` for all). OCR of images and image-only pages needs a local `tesseract` binary. Details: [Installation](https://velofy.co/terbium/installation/).

## Example

Point it at a vendor catalogue and get a table of products, each with its name, SKU, materials or ingredients, dimensions and image. Then a CSV.

```python
import terbium

rows = terbium.build_catalog("vendor_catalogue.pdf", images_dir="images/")
terbium.to_catalog_csv(rows, "catalogue.csv")
# rows: {"sku": "RG-1001", "name": "Anatolia Kilim", "materials": "wool",
#        "dimensions": None, "image": "Anatolia_Kilim.jpeg", "page": 12}
```

The same engine reads other documents:

```python
doc = terbium.parse("invoice.pdf")                     # line items, totals, vendor
cv = terbium.parse("maria_cv.pdf", doc_type="resume")  # sections, experience, skills
print(doc.stats)   # Stats(total=..., confident=..., ambiguous=...)
```

```bash
terbium catalogue.pdf --csv out.csv                    # product table + photos, no AI
terbium invoice.pdf --csv rows.csv --html report.html  # CSV + self-contained report
```

## Features

- **Structure from geometry.** Running headers are stripped, two-page spreads split, and columns, rows and matrices rebuilt from word positions. The table detector is content-agnostic.
- **Catalog table.** Each product photo anchors a row; the name, SKU, materials and dimensions are mined from nearby text, and the photo is extracted and named after the product.
- **Many document types.** Automatic classification into catalogue, lookbook, transaction, resume, table or deck, with `--type` to override.
- **Formats.** PDF, PPTX, XLSX, CSV, and PNG, JPG, WEBP or TIFF images through local OCR.
- **Confidence on every record.** Each record carries a 0.05 to 1.0 score and the reasons behind it.
- **AI only where needed.** Hard tables go to a routed model tier (Haiku, Sonnet or Opus class) across Claude (default), GPT, Kimi, Grok and Gemini. With no key, terbium prints which pages need help and which tier it recommends.
- **Feeds.** Normalized colour, material and dimension fields, plus Shopify CSV and PIM JSON exporters.

## Documentation

- [Overview](https://velofy.co/terbium/)
- [Installation](https://velofy.co/terbium/installation/) and [Quickstart](https://velofy.co/terbium/quickstart/)
- [The catalog table](https://velofy.co/terbium/catalog/) and [Pulling out images](https://velofy.co/terbium/images/)
- [Invoices, receipts and resumes](https://velofy.co/terbium/documents/)
- [File formats](https://velofy.co/terbium/formats/) and [Schemas](https://velofy.co/terbium/schemas/)
- [Confidence and escalation](https://velofy.co/terbium/confidence/)
- [AI lane and routing](https://velofy.co/terbium/ai-and-routing/)
- [Normalization and feeds](https://velofy.co/terbium/feeds/)
- [CLI reference](https://velofy.co/terbium/cli/) and [Python API reference](https://velofy.co/terbium/python-api/)
- [Document taxonomy](https://velofy.co/terbium/taxonomy/)
- [Evaluation](https://velofy.co/terbium/evaluation/) and [Changelog and status](https://velofy.co/terbium/changelog/)

Developer notes stay in this repository: [docs/DESIGN.md](https://github.com/velofy/terbium/blob/main/docs/DESIGN.md), [docs/ROADMAP.md](https://github.com/velofy/terbium/blob/main/docs/ROADMAP.md) and [docs/TAXONOMY.md](https://github.com/velofy/terbium/blob/main/docs/TAXONOMY.md).

## Contributing

Issues and pull requests are welcome at https://github.com/velofy/terbium. To work on the code:

```bash
git clone https://github.com/velofy/terbium.git
cd terbium
pip install -e ".[dev]"
python -m pytest -q
python eval/category_bench.py
```

## License

MIT. Built by [anishfyi](https://github.com/anishfyi). See [LICENSE](https://github.com/velofy/terbium/blob/main/LICENSE).

<div align="center"><sub>terbium · Tb · 65</sub></div>
