Skip to main content

PyStreamPDF

PyPI CI Python 3.9+ License: Apache 2.0

Token-efficient PDF extraction for RAG: parse PDF structure and split content into token-budget-aware chunks.

What it is

PyStreamPDF combines a Rust/PDFium-backed core for real PDF parsing with a Python layer for semantic chunking, token-budget-aware caching, and OCR/validation. Instead of sending an entire document to a model, it parses PDF structure and splits content into semantic, token-budget-aware chunks so you can send only the relevant parts. It ships as pystreampdf on PyPI and imports as pystreampdf.

Features / Highlights

  • Semantic chunking — SemanticChunker splits text into token-aware chunks by element type rather than naive word-count splitting.
  • Token-budget system — TokenBudgetConfig / BudgetRule scale allocation within a fixed 500–1000 token range using keyword/field-based multipliers.
  • Dual-tier cache — PDFCache: L1 memory + L2 disk, HMAC-SHA256-signed on disk with owner-only (0600) permissions; a tampered cache file fails verification before any deserialization.
  • Real PDF security handling — pystreampdf._core.PyPdfDocument is backed by PDFium's actual encryption/permission APIs (is_encrypted(), permissions(), open_with_password()); a wrong or missing password fails closed.
  • Honest failure signaling — unparseable PDFs raise a real error; no fabricated placeholder content.
  • OCR and validation pipelines — ocr/ and validation/ are real implementations with dedicated test coverage.
  • Exact or heuristic token counts — uses len(text) / 4 by default (clearly labeled approximate); install the optional tiktoken extra for real BPE (cl100k_base) counts.
  • Optional MCP/DAB connector — exposes document-processing tools over MCP, binds to 127.0.0.1 only, read-only by default.

Who it's for / Use cases

  • RAG pipeline authors who want to reduce the volume of text sent per query without losing the parts that matter.
  • Token-cost-conscious teams that need to budget tokens per document type.
  • Document-processing services that need real encryption/permission detection and a cache that fails closed on tampering.
  • Agent/tool builders who want PDF extraction surfaced over MCP locally.

What it is not

  • There is no Document class and no .extract_relevant() / .token_savings API. That class never existed in the source. The real exported API is SemanticChunker, PDFCache, TokenBudgetConfig, and the Rust-backed pystreampdf.open().
  • No committed token-savings benchmark. Earlier "70% reduction" / "10-50x" claims were never backed by a checked-in benchmark and have been retracted. Actual savings depend on your documents and how narrowly you scope queries.
  • Prebuilt wheels are macOS arm64 only. A source distribution ships as of 2.3.0, so other platforms build from source, but that still requires a local Rust toolchain and a discoverable libpdfium (see scripts/download_pdfium.sh).
  • No realistic OCR/layout test fixtures yet. The OCR and table-validation code is real and unit-tested, but tests use synthetic images and mocks — no true multi-column layout or realistic scanned-document fixtures.
  • Cross-project integration is asserted, not demonstrated. Nothing in this repo imports from or is imported by StatGuardian, PyInferenceManager, or PyStreamMCP.
  • The Rust-backed pystreampdf.open() / load_index() silently becomes None if the compiled _core extension is unavailable (e.g. a from-source install without maturin develop), falling back to the pure-Python path rather than erroring.
  • The MCP connector has no authentication of its own. It binds to 127.0.0.1 with read-only permissions by default; exposing it further requires allow_remote=True.

Project status

Beta. Current version 2.3.0 (Development Status :: 4 - Beta). The last confirmed-green CI run reported pytest — 557 passed / 2 skipped and cargo test — 23 passed / 0 failed across Python 3.10/3.11/3.12. See docs/PRODUCT_VISION.md for what is real vs. partial.

Installation

pip install pystreampdf

# With exact token counting (tiktoken)
pip install "pystreampdf[tiktoken]"

Requires Python 3.9+.

Quick start

from pystreampdf import SemanticChunker, ElementType

with open("financial_report.pdf", "rb") as f:
    text = f.read().decode("latin-1", errors="ignore")  # or use a real PDF text extractor first

chunker = SemanticChunker(target_tokens=500)
chunks = chunker.chunk_content(
    text, element_type=ElementType.TEXT, page_start=1, page_end=1
)
print(f"Split into {len(chunks)} semantic chunks")

Usage

Budget-aware caching and chunking:

from pystreampdf import SemanticChunker, PDFCache, TokenBudgetConfig, BudgetRule, ElementType

budget_config = TokenBudgetConfig(
    base_budget=800,
    rules=[BudgetRule("complex", 1.1, match_fields=["filename"])]
)

cache = PDFCache(
    memory_limit_mb=500,
    disk_cache_dir="./pdf_cache",
    token_budget_config=budget_config,
)

def extract_pdf(pdf_path):
    chunks, preview, title, pages = cache.get_or_process(pdf_path, process_fn=extract_chunks)
    return chunks

chunker = SemanticChunker(target_tokens=500)
chunks = chunker.chunk_content(text, element_type=ElementType.TEXT, page_start=1, page_end=1)

Exact vs. heuristic token counts. By default counts use len(text) / 4. With the tiktoken extra installed, pystreampdf.tokenizer.is_exact() returns True and cl100k_base is used; check pystreampdf.tokenizer.TOKENIZER_MODE to see which mode produced a given number.

Rust-backed document API (examples/basic_parse.py) — document/page/structure inspection, requires the compiled _core extension:

import pystreampdf
doc = pystreampdf.open("report.pdf")  # None if _core isn't available

MCP connector — optional, local by default, read-only:

# see examples/mcp_pystreampdf.py

Documentation

Run the tests with:

make test          # cargo test && pytest tests/

Contributing

Contributions are welcome. See CONTRIBUTING.md and CODE_OF_CONDUCT.md. Security issues: see SECURITY.md for the reporting process and the cache/MCP security model.

License

This project is licensed under the Apache License 2.0.

Metadata

Release files for PyStreamPDF 2.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for PyStreamPDF 2.3.1
File Size Uploaded Provenance
pystreampdf-2.3.1.tar.gz 115.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for PyStreamPDF 2.3.1
File Interpreter ABI Platform
pystreampdf-2.3.1-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details

Total release size: 1.7 MB

Release files / pystreampdf-2.3.1.tar.gz

Download URL pystreampdf-2.3.1.tar.gz
Size 115.7 kB
Tags Source
SHA-256 checksum
How to use checksums
5f678285b83f71c7d26253f909de9f6cf36cd47e445a97474d536ffa6ae046b9
BLAKE2b-256 checksum
How to use checksums
c05e96ed8d36d05631762a56b9dc0e4d9d04116ba7290dcc6095809c62c5d572
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / pystreampdf-2.3.1-cp311-cp311-macosx_11_0_arm64.whl

Download URL pystreampdf-2.3.1-cp311-cp311-macosx_11_0_arm64.whl
Size 1.6 MB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c5b0dfcae304f6c7a164dbf711e34fd5b4e89fdbf3ea1c21656a22e287b57a56
BLAKE2b-256 checksum
How to use checksums
b7ad884a5bfd3d36b6fcbbad0296a6151e11361c0f29d5ff933af25c1cec0ce3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Security for PyStreamPDF 2.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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