Metadata-Version: 2.5
Name: langchain-pdfluent
Version: 0.2.0
Summary: LangChain document loader for PDFluent: PDF blocks, tables or markdown pages with page, box, kind and confidence, locally, fast or balanced quality.
Project-URL: Homepage, https://pdfluent.com
Project-URL: Documentation, https://pdfluent.com/docs
Project-URL: Pricing, https://pdfluent.com/sdk/pricing
Project-URL: Repository, https://github.com/pdfluent/pdfluent-sdk
Project-URL: Bug Tracker, https://github.com/pdfluent/pdfluent-sdk/issues
Author-email: "Innovation Trigger B.V." <team@pdfluent.com>
License-Expression: AGPL-3.0-only OR LicenseRef-PDFluent-Commercial
License-File: LICENSE
License-File: LICENSE-COMMERCIAL
Keywords: document-loader,langchain,pdf,pdfluent,rag
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing
Requires-Python: >=3.9
Requires-Dist: langchain-core>=0.3
Requires-Dist: pdfluent>=1.2.0
Description-Content-Type: text/markdown

# langchain-pdfluent

A [LangChain](https://github.com/langchain-ai/langchain) document loader for
[PDFluent](https://pdfluent.com). It reads a PDF with PDFluent's structured
extraction and hands LangChain `Document`s in reading order, with the page and
box each came from in its metadata so an answer can cite its source. Everything
runs locally. Your documents stay on your machine.

## Install

```bash
pip install langchain-pdfluent
```

It needs Python 3.9 or later and `pdfluent` 1.2.0 or later, which pip pulls in
automatically. It also depends on `langchain-core` (MIT).

## Quick start

```python
from langchain_pdfluent import PDFluentLoader

docs = PDFluentLoader("report.pdf").load()
print(docs[0].page_content, docs[0].metadata["page"])
```

A runnable notebook, load and split, is in
[`examples/load_and_split.ipynb`](examples/load_and_split.ipynb).

## Modes

`mode` decides what one `Document` is.

### Blocks mode

One document per paragraph, heading, list item or table (a table is one
document), in reading order. This is the default.

```python
from langchain_pdfluent import PDFluentLoader

loader = PDFluentLoader("report.pdf")
for doc in loader.lazy_load():
    print(doc.metadata["kind"], doc.metadata["page"], doc.metadata["bbox"])
```

### Markdown mode

One document per page, as markdown. Pass `quality="balanced"` for the
layout-model tier (see below).

```python
from langchain_pdfluent import PDFluentLoader

pages = PDFluentLoader("report.pdf", mode="markdown").load()
print(len(pages), "pages")
print(pages[0].page_content[:200])
```

### Document mode

One document for the whole selection: the markdown of every selected page,
joined by a blank line. `metadata["pages"]` lists the pages it covers.

```python
from langchain_pdfluent import PDFluentLoader

whole = PDFluentLoader("report.pdf", mode="document", pages=[0, 2]).load()
print(whole[0].metadata["pages"])
```

## Quality and pages

`quality` is `"fast"` (default) or `"balanced"`, the layout-model tier of
`pdfluent` 1.2. The balanced tier assembles markdown, so it goes with
`mode="markdown"` or `mode="document"`; with `mode="blocks"` the engine refuses
it and says so. It needs the model weights, installed once with the
`pdfluent` command-line tool:

```bash
pdfluent models install layout tables
```

```python
from langchain_pdfluent import PDFluentLoader

PDFluentLoader("report.pdf", mode="markdown", quality="balanced").load()
```

`pages=[0, 3]` loads exactly those pages (0-based); `first_page` and
`page_count` load a window.

## Options

| Argument | Default | What it does |
|---|---|---|
| `mode` | `"blocks"` | `"blocks"`, `"markdown"` (one document per page) or `"document"` (one document). |
| `quality` | `"fast"` | `"fast"` or `"balanced"` (markdown and document modes). |
| `model_dir` | `None` | Where the balanced tier finds its weights; `None` uses `PDFLUENT_MODEL_DIR` or the per-user model directory. |
| `table_model_dir` | `None` | Directory of the table-structure model; opts the balanced tier's tables into it. |
| `include_furniture` | `False` | Keep the running heads and page numbers a document repeats on every page. |
| `first_page`, `page_count` | `0`, `None` | Load a window of pages. |
| `pages` | `None` | Load exactly these 0-based pages instead of the window. |
| `hierarchical`, `max_chars` | `False`, `2000` | Add `section_path` and split long tables by rows. |

## Metadata

| Key | Value |
|---|---|
| `source` | the path the PDF was loaded from |
| `page` | 0-based page index (blocks and markdown modes) |
| `pages` | the 0-based pages a document covers (document mode) |
| `kind` | `paragraph`, `heading`, `list_item`, `table`, `header`, `footer`; `page` in markdown mode; `document` in document mode |
| `bbox` | `[x0, y0, x1, y1]` in points, origin at the bottom left of the page, y up (blocks mode) |
| `confidence` | the learned model's probability for `kind`, only where a model decided it |
| `section` | the last heading above the chunk |
| `section_path` | the enclosing headings (`hierarchical=True`) |
| `level` | a heading's level, 1 to 3 |
| `continues_previous` | `True` on the second half of a paragraph a page break cut in two |
| `toc_items` | the outline entries pointing at the page, as `[level, title, page]` triples (markdown and document modes) |
| `tables` | one `{"bbox", "rows", "columns"}` per table on the page (markdown mode) |

`bbox`, `toc_items` and `tables` are lists. A vector store that only accepts
scalar metadata, such as Chroma, needs `filter_complex_metadata` from
`langchain_community` over the documents first.

## Benchmarks

<!-- TODO: link the public pdfluent-bench here once that repository is public.
     No number goes into this README without an ID in CLAIMS.md. -->

Extraction quality is measured in the public `pdfluent-bench` repository
(link follows when it is public).

## Licence

AGPL-3.0 or a commercial licence, at your option; see `LICENSE` and
`LICENSE-COMMERCIAL`. The commercial licence is sold yearly and self-service at
<https://pdfluent.com/sdk/pricing>.
