Skip to main content

langchain-pdf-inspector

A LangChain DocumentLoader integration that wraps the Rust-backed pdf-inspector library to load PDFs as plain text, markdown, positional text, or region-cropped text. It is designed as a langchain_community-style document loader integration.

Python Version License: MIT LangChain Core pdf-inspector PyPI

Introduction

langchain-pdf-inspector gives you a standard LangChain document loader for PDF files, backed by the Rust-powered pdf-inspector package. It returns langchain_core.documents.Document objects that plug straight into LangChain chains, retrievers, and vector stores.

Features

langchain-pdf-inspector is built on two small classes. PdfInspectorParser (a BaseBlobParser) parses a single Blob into Documents across four extraction paths — plain text, markdown (headings, lists, and tables preserved), positional text (text items with bounding boxes), and region-cropped text (cropped to [x0, y0, x1, y1] rectangles) — each in one of two modes: mode="single" (one Document for the whole PDF, the default) or mode="page" (one Document per page). PdfInspectorLoader (a BasePDFLoader) wraps the parser, resolves local, web (HTTP/HTTPS), and S3 paths, downloads remote files to a temporary file, and merges caller-supplied metadata on top of every Document. Because the heavy lifting is done by the Rust-backed pdf-inspector package, extraction is fast and accurate for both text-based and scanned PDFs.

[!NOTE] langchain-pdf-inspector is a standalone package (version 0.1.1) published on PyPI. It imports from its own langchain_pdf_inspector namespace, so use from langchain_pdf_inspector import PdfInspectorLoader rather than a langchain_community import.

Requirements

  • Python 3.12 or higher
  • langchain-core 1.5.3 or higher
  • pdf-inspector 0.2.6 or higher

Installation

Install langchain-pdf-inspector from PyPI:

pip install langchain-pdf-inspector
# or with uv
uv add langchain-pdf-inspector

Installing langchain-pdf-inspector also installs its pinned runtime dependencies, langchain-core and pdf-inspector. pdf-inspector is a required dependency; if it is missing, constructing the loader or parser raises a friendly ImportError telling you to run pip install pdf-inspector.

To install from source instead, clone the repository and run pip install . (or uv add .) from the repo root.

Usage

Create a loader from a local file, a web URL, or an S3 path:

from langchain_pdf_inspector import PdfInspectorLoader

# Local file
loader = PdfInspectorLoader("path/to/report.pdf")

# Web URL
loader = PdfInspectorLoader("https://example.com/report.pdf")

# With optional caller metadata
loader = PdfInspectorLoader(
    "report.pdf",
    metadata={"tenant": "acme", "document_id": "R-42"},
)

Call load() to get a list of Document objects:

loader = PdfInspectorLoader("path/to/report.pdf")

for doc in loader.load():
    print(doc.page_content)
    print(doc.metadata)

Use lazy_load() to stream documents:

loader = PdfInspectorLoader("report.pdf", mode="page", pages=[0, 1, 2])

for doc in loader.lazy_load():
    print(doc.metadata["page"], doc.page_content[:80])

Every Document carries source and a 1-indexed page; pdf_type and total_pages are attached whenever page detection succeeds. Caller-supplied metadata is merged on top of these keys, and wins on conflicts.

One document per page

mode="page" splits the PDF into one Document per page and requires pages, a non-empty list of 0-indexed pages. In page mode the content branches on output: output="markdown" yields per-page markdown with layout flags (needs_ocr, has_tables, has_multicolumn_layout); output="text" yields per-page positional or region-cropped text and requires extract_positions or extract_regions:

loader = PdfInspectorLoader(
    "report.pdf", mode="page", pages=[0, 1, 2], output="markdown"
)
for doc in loader.load():
    print(doc.metadata["page"], doc.metadata.get("has_tables"))

Markdown

Use output="markdown" in single mode to get the whole file as one Document of markdown, preserving headings, lists, and tables:

loader = PdfInspectorLoader("report.pdf", mode="single", output="markdown")
doc = loader.load()[0]
print(doc.page_content)

Positional text

Set extract_positions=True to extract text items with their positional data. In single mode all pages collapse into one joined Document (pages joined with page_delimiter); in page mode you get one Document per page:

loader = PdfInspectorLoader(
    "report.pdf", mode="page", pages=[0, 1, 2], extract_positions=True
)
for doc in loader.load():
    print(doc.metadata["page"], doc.page_content)

Region extraction

Set extract_regions=True and pass page_regions to crop text to [x0, y0, x1, y1] rectangles. extract_regions requires page_regions and is mutually exclusive with extract_positions:

# Single mode: one joined Document cropped to the given regions
loader = PdfInspectorLoader(
    "report.pdf",
    extract_regions=True,
    page_regions=[(0, [[10.0, 10.0, 200.0, 200.0]])],
)
for doc in loader.load():
    print(doc.metadata["page"], doc.page_content)

# Page mode: one region-cropped Document per page
loader = PdfInspectorLoader(
    "report.pdf",
    mode="page",
    pages=[0, 1, 2],
    extract_regions=True,
    page_regions=[(0, [[10.0, 10.0, 200.0, 200.0]])],
)
for doc in loader.load():
    print(doc.metadata["page"], doc.page_content)

Using the parser directly

PdfInspectorParser parses a Blob directly when you do not need path resolution or metadata merging:

from langchain_core.document_loaders.blob_loaders import Blob
from langchain_pdf_inspector import PdfInspectorParser

parser = PdfInspectorParser(mode="page", pages=[0, 1, 2], extract_positions=True)
blob = Blob.from_path("report.pdf")
docs = list(parser.lazy_parse(blob))  # or parser.parse(blob) for a list

Async loading

aload() and alazy_load() are inherited from BaseLoader and run the synchronous parsing work in a thread executor:

loader = PdfInspectorLoader("report.pdf")
docs = await loader.aload()

async for doc in loader.alazy_load():
    print(doc.page_content)

API reference

  • PdfInspectorLoader (src/langchain_pdf_inspector/pdf_inspector_loader.py) — a BasePDFLoader subclass that resolves local, web, and S3 paths, forwards extraction options to the parser, and merges caller metadata on top of every Document. Implements lazy_load(); load(), aload(), and alazy_load() come from BaseLoader.
  • PdfInspectorParser (src/langchain_pdf_inspector/pdf_inspector_parser.py) — a BaseBlobParser subclass that parses a Blob into Documents across four extraction paths and two modes. Implements lazy_parse() and parse().

Development

Install the development group with uv:

uv sync --group dev

The repo ships a dev container (VS Code, Python 3.12, uv, and TeX Live) that runs uv sync --group dev automatically on create.

  • Type checkinguv run mypy src
  • Lintinguv run ruff check .
  • Testsuv run pytest

Creating Test Documents

Test fixtures are PDFs compiled from LaTeX sources under tests/fixtures/tex/ by tests/fixtures/build_fixtures.py. Six fixtures are staged for incremental complexity — plain_text, headings, lists, two_column, tables, and complex_layout. The .tex sources are tracked; the built PDFs are gitignored build artifacts.

Build them with:

uv run python tests/fixtures/build_fixtures.py

The script requires pdflatex (pdfTeX) on PATH. On macOS, brew install --cask mactex-no-gui (or basictex) provides it; otherwise add its bin directory to PATH, for example export PATH="/Library/TeX/texbin:$PATH".

Licensing

  • Open source — the langchain-pdf-inspector integration code is licensed under the MIT License.
  • Third-party — the wrapped pdf-inspector package is distributed under its own license; see that package for details.

Contributing

Contributions are welcome. Report bugs, request features, or open a pull request on the repository.

⭐ Support this project

If you find this useful, please consider giving it a star — it helps others discover it!

Star on GitHub

Download files

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

Source Distribution

langchain_pdf_inspector-0.1.1.tar.gz (27.4 kB view details)

Uploaded Source

Built Distribution

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

langchain_pdf_inspector-0.1.1-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file langchain_pdf_inspector-0.1.1.tar.gz.

File metadata

  • Download URL: langchain_pdf_inspector-0.1.1.tar.gz
  • Upload date:
  • Size: 27.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for langchain_pdf_inspector-0.1.1.tar.gz
Algorithm Hash digest
SHA256 8c2927ef46628a50570353df5a59fb47039dff6e8b8df5251878616d0cbd717b
MD5 4209faa2e5076905cf082e973d611e0d
BLAKE2b-256 5596985967b264baf2a6696b5083ff5574a178ba4005e8d8a0b49ae824b59464

See more details on using hashes here.

File details

Details for the file langchain_pdf_inspector-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: langchain_pdf_inspector-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for langchain_pdf_inspector-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 50a57c1ced78a302a573f90e27b14fd72b497b5e445a7cdb068a65f450c8ebdf
MD5 6e2c59f53c8bd3eacd59429c6ed9f75d
BLAKE2b-256 8a77bfddbaedf361179c5332bc4c9fe30c992e525958c7da68fdb6833c5f5620

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page