Skip to content

feat: add LiteParseLoader (LiteParse optional extra)#534

Open
jexp wants to merge 4 commits into
neo4j:mainfrom
jexp:feature/liteparse-loader
Open

feat: add LiteParseLoader (LiteParse optional extra)#534
jexp wants to merge 4 commits into
neo4j:mainfrom
jexp:feature/liteparse-loader

Conversation

@jexp

@jexp jexp commented May 28, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds LiteParseLoader in a new neo4j_graphrag.experimental.components.liteparse_loader module as an alternative PDF/document loader backed by LiteParse — a local, zero-cloud Rust parser with optional Tesseract OCR support
  • data_loader.py is unchanged — LiteParseLoader lives in its own module alongside the optional-dependency import guard
  • New liteparse optional extra: pip install "neo4j-graphrag[liteparse]"
  • Drop-in replacement for PdfLoader; pass as file_loader=LiteParseLoader() to SimpleKGPipeline

Changes

  • src/neo4j_graphrag/experimental/components/liteparse_loader.py — new module with LiteParseLoader
  • pyproject.tomlliteparse = ["liteparse>=2.0.0,<3.0.0"] optional extra + mypy override
  • CHANGELOG.md — entry under ## Next
  • examples/customize/build_graph/components/loaders/liteparse_loader.py — usage example
  • tests/unit/experimental/components/test_liteparse_loader.py — 9 unit tests (fully mocked)
  • tests/unit/experimental/components/test_liteparse_loader_integration.py — 5 integration tests (real liteparse; auto-skipped when absent)

Usage

from neo4j_graphrag.experimental.components.liteparse_loader import LiteParseLoader
from neo4j_graphrag.experimental.pipeline.kg_builder import SimpleKGPipeline

pipeline = SimpleKGPipeline(
    llm=...,
    driver=...,
    embedder=...,
    file_loader=LiteParseLoader(ocr_enabled=True),  # or LiteParseLoader() for text PDFs
    from_file=True,
)
await pipeline.run_async(file_path="document.pdf")

Test plan

  • uv run pytest tests/unit/experimental/components/test_liteparse_loader.py — 9 unit tests pass without liteparse installed
  • pip install "neo4j-graphrag[liteparse]" && uv run pytest tests/unit/experimental/components/test_liteparse_loader_integration.py — 5 integration tests pass with liteparse installed
  • Existing test_data_loader.py tests unaffected

@jexp jexp requested a review from a team as a code owner May 28, 2026 20:31
@jexp jexp force-pushed the feature/liteparse-loader branch from 82300a5 to 0b4241c Compare May 28, 2026 20:32
jexp added 4 commits June 24, 2026 01:37
Adds LiteParseLoader to neo4j_graphrag.experimental.components.data_loader
as an alternative PDF/document loader using LiteParse — a local, zero-cloud
Rust-based parser with optional Tesseract OCR support.

- New liteparse optional extra: pip install "neo4j-graphrag[liteparse]"
- Lazy-imports liteparse; raises a clear ImportError with install hint when absent
- Parser instance cached per loader to avoid repeated Rust init overhead
- Supports local FS fast-path (file path) and non-local FS (bytes) via fsspec
- 9 unit tests (fully mocked, no liteparse install required)
- 5 integration tests (real liteparse; auto-skipped when not installed)
- Usage example in examples/customize/build_graph/components/loaders/
Extracts LiteParseLoader from data_loader.py into a dedicated
liteparse_loader.py, keeping the optional-dependency import guard
and all liteparse-specific logic isolated from the core loaders.

data_loader.py is restored to only DataLoader, PdfLoader, MarkdownLoader.
Pass output_format='markdown' to get #/##-style headers in the parsed
text, enabling clean chaining with HierarchicalTextSplitter(header_strategy='markdown').
Bumps the liteparse version pin to >=2.1.0 to guarantee the param is available.

@AmirLayegh AmirLayegh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! 🙌
Left a few comments worth addressing before merging.

metadata=self.get_document_metadata(text, metadata),
document_type=DocumentType.PDF,
),
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering LiteParse also parses other document types such as DOCX, XLSX, PPTX, and images, loading a non-PDF file will result in document_type="pdf" in the returned DocumentInfo. Since the field is optional, it would be more accurate to infer the type from the file extension and fall back to None for unsupported types.

return self._parser

def load_file(self, filepath: str, fs: AbstractFileSystem) -> str:
"""Parse a document and return the full extracted text."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PdfLoader.load_file and MarkdownLoader.load_file both use file as the parameter name, but LiteParseLoader.load_file uses filepath. This can be renamed to file to stay consistent.

Comment thread uv.lock

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lock file pins liteparse==2.0.3 while pyproject.toml specifies >=2.1.0,<3.0.0. I guess the lock file should be regenerated accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants