Skip to main content

multixtract — Vendor-neutral document extraction, OCR, chunking, and embeddings for RAG pipelines

CI Coverage PyPI Downloads Python Docs License: MIT Ruff mypy

Pull text, tables, and images out of PDFs, Word, PowerPoint, Excel/CSV and more — let any vision model describe the images, chunk everything for retrieval, embed it, and store the result anywhere.

The core is tiny (just Pillow + ImageHash). Every format parser and every cloud SDK is an optional extra — install only what you need.

multixtract hero


Highlights

Vendor-neutral — swap OpenAI for Azure, Qwen, Llama, or your own model with one line
Extract text, tables, and images from 15+ file formats
Modular — use only extraction, or run the full extract → vision → chunk → embed → store pipeline
Fully offline — local vision models, no API key, no cloud
Tiny core install — only Pillow + ImageHash; every heavy dependency is optional
Fully typed — mypy and pyright compatible out of the box


Why Multixtract?

Most libraries optimise for one part of the workflow — parse documents, run OCR, generate embeddings, or store vectors. You end up stitching together five packages with incompatible interfaces and rebuilding the same pipeline on every project.

multixtract connects all of them without locking you into a provider. Swap OpenAI for Azure or a local model, swap Azure Blob for S3, add a new file format — none of it touches the rest of the pipeline.

What multixtract is not: It is not a vector database, retrieval framework, or chat system. It focuses on document ingestion and preparation — getting clean, structured, chunked content into whatever AI system you're building.

Feature multixtract Unstructured Docling
PDF
DOCX
PPTX
XLSX / CSV Partial
EPUB / RTF / HTML / Email Partial
Vendor-neutral vision model
Bring your own embeddings
Bring your own storage backend Partial Partial
Fully modular pipeline Partial Partial
Optional dependencies
Offline / no-cloud mode Partial
Core install size Pillow + ImageHash Heavy Heavy

Quick Start

pip install "multixtract[pdf,docx,pptx,xlsx]"

One call. Any document. Done.

from multixtract import Pipeline

Pipeline().process("report.pdf")                      # extract → filter → chunk
Pipeline().process("report.pdf", split_chunks=True)   # + write individual chunk files

Or stay close to the data:

from multixtract import extract_document, chunk_document

document, images = extract_document("report.pdf")
chunks = chunk_document(document, base_name="report")

Supported formats: PDF · DOCX · PPTX · XLSX · CSV · EPUB · HTML · RTF · Email · Images · Plain text · Markdown — and legacy .doc / .ppt via LibreOffice.

Vision providers: OpenAI · Azure OpenAI · Qwen2.5-VL · Llama 3.2 Vision · SmolVLM (CPU) · bring your own.

Full installation guide · Recipes · Provider setup


Document Schema

Every call to extract_document returns the same structure regardless of input format:

PDF / DOCX / PPTX / XLSX / …
        │
        ▼
{
  "_base_name": "report",
  "metadata": { "format": "pdf", "page_count": 12, ... },
  "pgs": [
    {
      "pg_num": 1,
      "kind":   "page",
      "title":  "Executive Summary",
      "txt":    "The quarterly results show a 12% increase...",
      "tables": [
        [["Region", "Q1", "Q2"], ["North", "1.2M", "1.4M"], ...]
      ],
      "imgs": [
        { "image_id": "report-p1-img0", "width": 800, "height": 600 }
      ],
      "hyperlinks": ["https://example.com/data"]
    },
    ...
  ]
}

Full data model and chunk schema


Architecture

multixtract architecture

┌─────────────────────────────────────────────────────────────────┐
│                        Your document                            │
│          PDF · DOCX · PPTX · XLSX · EPUB · HTML · RTF …         │
└────────────────────────────┬────────────────────────────────────┘
                             │
                    ┌────────▼────────┐
                    │   Extractors    │  (registry — one per format)
                    └────────┬────────┘
                             │
              ┌──────────────┼──────────────┐
              │              │              │
         ┌────▼────┐   ┌─────▼─────┐  ┌─────▼───┐
         │  Text   │   │  Tables   │  │ Images  │
         └────┬────┘   └─────┬─────┘  └─────┬───┘
              │              │              │
              │              │    ┌─────────▼───────────┐
              │              │    │  ImageFilterPipeline│
              │              │    │  · dimension        │
              │              │    │  · solid-color      │
              │              │    │  · icon rejection   │
              │              │    │  · logo dedup (hash)│
              │              │    └─────────┬───────────┘
              │              │              │
              │              │    ┌─────────▼───────────┐
              │              │    │     VisionModel     │
              │              │    │   OpenAI · Azure    │
              │              │    │  Qwen · Llama · CPU │
              │              │    │  (or skip entirely) │
              │              │    └─────────┬───────────┘
              │              │              │
              └──────────────┴──────────────┘
                             │
                    ┌────────▼────────┐
                    │    Chunking     │  sliding-window · table-MD · image
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
                    │    Embedder     │  OpenAI · Azure · BYO · (skip)
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
                    │    BlobStore    │  LocalDisk · AzureBlob · S3 · BYO
                    └─────────────────┘

The pipeline talks only to three interfaces — it never imports a vendor directly:

Interface Job Built-in implementations
VisionModel image → caption + OCR + description OpenAIVisionModel, AzureOpenAIVisionModel, Qwen2VLVisionModel, SmolVLMVisionModel, Llama32VisionModel
Embedder text → vector OpenAIEmbedder, AzureOpenAIEmbedder
BlobStore save bytes/JSON LocalDiskStore, AzureBlobStore

Add a new format with register_extractor. Plug in S3, GCS, or any backend by implementing three methods on BlobStore.


Integrations

Multixtract is an extraction and chunking layer, not a RAG framework. It fits underneath the tools you already use:

from multixtract import extract_document, chunk_document
from langchain.schema import Document as LCDocument

document, _ = extract_document("report.pdf")
chunks = chunk_document(document, base_name="report")

# LangChain
lc_docs = [LCDocument(page_content=c["content"], metadata={"pg": c["pg_num"]}) for c in chunks]

# LlamaIndex
from llama_index.core import Document as LIDocument
li_docs = [LIDocument(text=c["content"], metadata={"chunk_id": c["chunk_id"]}) for c in chunks]

Example projects

Integration What it shows
LangChain + Chroma Ingest → Chroma vector store → RetrievalQA
Azure AI Search Ingest → hybrid keyword + vector search → GPT-4o answer
LlamaIndex Ingest → LlamaIndex VectorStoreIndex → query engine
pgvector Ingest → PostgreSQL + pgvector → cosine similarity search
Semantic Kernel Ingest → SK memory store → prompt function RAG
Offline OCR Tesseract OCR on images — no API key, no cloud, no GPU

Each example is a self-contained ingest.py with a --query flag so you can extract, store, and query in one command.


Features

  • Multi-format: PDF, Word, PowerPoint, Excel/CSV, EPUB, HTML, RTF, email, images (+ legacy .doc/.ppt via LibreOffice)
  • Cross-page image deduplication via xref tracking
  • Image filters: solid-color / tiny-icon / dimension / reference-logo (perceptual hash)
  • Sliding-window text chunking (~500 tokens, ~50 overlap) at sentence boundaries
  • Tables serialized to Markdown; images embedded once and reused
  • Parallel vision calls (vision_workers), batched embeddings
  • Resume support — skip documents already in the store (skip_if_exists)
  • Two-stage chunking: _chunks.json written automatically; pass split_chunks=True to also write flat individual chunk documents ready for Azure AI Search or any vector store
  • build_index_document() — transforms a raw chunk into a flat, AI-Search-ready document (renames embeddingcontent_vector, flattens metadata)
  • safe_index_key() — sanitizes any string to a valid Azure AI Search document key
  • Fully typed — py.typed marker, compatible with mypy and pyright

Roadmap

  • PDF / DOCX / PPTX / XLSX extraction
  • EPUB / HTML / RTF / email extraction
  • Azure OpenAI vision + embeddings integration
  • Local vision models (Qwen2.5-VL, Llama 3.2, SmolVLM)
  • Azure Blob Storage backend
  • Sliding-window chunking with sentence-boundary awareness
  • Smart image filtering (dimension, solid-color, logo dedup)
  • Document-level metadata on every chunk (file_path, doc_id, last_updated, …)
  • Individual chunk splitting — split_chunks=True or split_chunks_file() writes per-chunk documents for AI Search ingestion
  • build_index_document() — flat AI-Search-optimized output with content_vector, flattened metadata
  • Figure-caption association (link extracted images to their nearest caption)
  • Table-of-contents aware chunking (respect heading hierarchy)
  • multisense — companion RAG pipeline library built on multixtract

PRs and feature requests welcome via GitHub Issues.


Performance

Extracts a 50-page PDF in ~4 s and a 100-slide PPTX in ~0.14 s on a standard developer machine (no GPU, no API key). Chunking adds negligible overhead.

Full benchmark results and methodology


Documentation

Installation Extras, formats, providers
Recipes OpenAI · Azure · extract-only · chunk-only · offline OCR
Providers OpenAI · Azure · Qwen · SmolVLM · Llama
Data model Document schema · chunk schema · metadata fields
Performance Benchmark results and methodology
Compatibility Python · OS · torch / CUDA combinations
Troubleshooting LibreOffice · CUDA · Azure auth · common errors
API Reference Full public API

Contributing

pip install -e ".[dev,pdf,docx,pptx,xlsx,epub,html,rtf]"
pytest
ruff check src tests
mypy src/multixtract --ignore-missing-imports --no-error-summary
python benchmarks/run_benchmarks.py

See CONTRIBUTING.md for guidelines. Bug reports and PRs are welcome.


Example Applications

  • Internal RAG systems on Azure OpenAI
  • Enterprise search over mixed document libraries
  • Research document processing pipelines

Using multixtract in your project? Open a PR to add it here.


License

MIT — see LICENSE.

Download files

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

Source Distribution

multixtract-0.1.2.tar.gz (66.0 kB view details)

Uploaded Source

Built Distribution

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

multixtract-0.1.2-py3-none-any.whl (82.7 kB view details)

Uploaded Python 3

File details

Details for the file multixtract-0.1.2.tar.gz.

File metadata

  • Download URL: multixtract-0.1.2.tar.gz
  • Upload date:
  • Size: 66.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for multixtract-0.1.2.tar.gz
Algorithm Hash digest
SHA256 25a9971936a49ba5324ed0be8f73db10e139f935d41643df64cf011e8c60365d
MD5 091ce5e7513c234137613fab186625b1
BLAKE2b-256 636aa7d48df84232e30f9a2224c5d3bb01178aa93f362dfc4206a860d94c33f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for multixtract-0.1.2.tar.gz:

Publisher: publish.yml on srivnamrata/multixtract

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file multixtract-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: multixtract-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 82.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for multixtract-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 61bfcf0c29ad60451618232a3168ca12722bcc361cc57285578af54e099abc9f
MD5 d3d46949b0bd467c92b7320e6f4eb00b
BLAKE2b-256 ca5d2d98c192178a04f561305352ba4f5ec72b9eb4cd0d1bce3a09ad3dda918d

See more details on using hashes here.

Provenance

The following attestation bundles were made for multixtract-0.1.2-py3-none-any.whl:

Publisher: publish.yml on srivnamrata/multixtract

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 files

0.1.1

2 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