feat: add pdf-inspector as an optional PDF parser backend - #390
Open
Kushpatel49 wants to merge 1 commit into
Open
feat: add pdf-inspector as an optional PDF parser backend#390Kushpatel49 wants to merge 1 commit into
Kushpatel49 wants to merge 1 commit into
Conversation
Introduces `pdf_parser="pdf_inspector"` (opt-in) alongside the existing PyPDF2 default and PyMuPDF option. pdf-inspector emits per-page Markdown with GFM tables, heading tiers and list markers preserved, which the downstream tree_parser and node-summary steps consume directly. Changes: - utils.py: dispatch in extract_text_from_pdf, get_text_of_pages, get_page_tokens, get_number_of_pages. New classify_pdf() helper and SUPPORTED_PDF_PARSERS tuple. Lazy import so absence of pdf-inspector does not break the default path. - page_index.py: pass opt.pdf_parser to get_page_tokens. - config.yaml: new pdf_parser key (default "PyPDF2"). - run_pageindex.py: --pdf-parser CLI flag and --check-ocr preflight that refuses image-based PDFs upfront. - tests: 12 unit tests covering dispatch, unknown-parser rejection, soft fallback when pdf-inspector is missing, and end-to-end use against a fixture PDF (skipped when pdf-inspector is not installed). Benchmarked on the 8 fixture PDFs in examples/documents/: Total time: 15.3s -> 3.3s (4.6x faster) GFM tables found: 0 -> 639 ATX headings found: 4 -> 2028 List markers: 193 -> 699 pdf-inspector is not added to requirements.txt so it stays truly optional; users opt in via `pip install pdf-inspector` and either the CLI flag or config.yaml override.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
pdf_inspectoras an opt-in third backend alongside the existingPyPDF2(default) andPyMuPDFpaths inget_page_tokensand friends. Default behavior is unchanged — users opt in via--pdf-parser pdf_inspectoron the CLI orpdf_parser: "pdf_inspector"inconfig.yaml.pdf-inspector is a Rust-based PDF parser (with prebuilt Python wheels on PyPI) that emits per-page Markdown with GFM tables, heading tiers, and list markers preserved — signals PageIndex's tree parser and node-summary steps already consume.
Also adds an optional
--check-ocrpreflight that classifies the PDF with pdf-inspector and refuses image-based files upfront, so users don't spend LLM tokens on a document that needs OCR.Benchmark
Ran both backends against the eight fixture PDFs in
examples/documents/:Highlights:
2023-annual-report.pdf(222 p): 0 → 176 tables. Annual reports are the FinanceBench-shaped case where table structure is load-bearing.PRML.pdf(758 p): 0 → 1,212 ATX headings, i.e. real hierarchy signal for the tree.q1-fy25-earnings.pdf: 0 → 12 tables (every financial statement).four-lectures.pdfshows no regression.Changes
pageindex/utils.py—SUPPORTED_PDF_PARSERStuple, lazy_load_pdf_inspector(),classify_pdf()helper, andpdf_parser=branches inextract_text_from_pdf,get_text_of_pages,get_page_tokens,get_number_of_pages.get_number_of_pagesgracefully falls back to PyPDF2 if pdf-inspector isn't installed so opt-in stays soft.pageindex/page_index.py— one-line: threadsopt.pdf_parserintoget_page_tokens.pageindex/config.yaml— new keypdf_parser: "PyPDF2"(default preserved).run_pageindex.py—--pdf-parser {PyPDF2,PyMuPDF,pdf_inspector}and--check-ocrflags.tests/test_pdf_parser_backend.py— 12 unit tests covering dispatch, unknown-parser rejection, soft fallback when pdf-inspector is missing, and end-to-end use against a fixture PDF. All tests skip cleanly when pdf-inspector isn't installed.Compatibility
requirements.txt— it remains truly optional. Users who want it:pip install pdf-inspector.pdf_parser: "PyPDF2"means zero behavior change for existing users.Test plan
python -m pytest tests/— 30 passedrun_pageindex.py --helpshows new flagsrun_pageindex.py --pdf_path <image-based>.pdf --check-ocrcorrectly refuses with a helpful messagepip install pdf-inspector && python run_pageindex.py --pdf_path examples/documents/2023-annual-report-truncated.pdf --pdf-parser pdf_inspectorand compare the resulting tree JSON against the PyPDF2 baselineNotes for reviewer
pip install pdf-inspectoris a normal-speed install — nocargorequired.--check-ocrflag is deliberately its own switch (not implied by--pdf-parser pdf_inspector) so users can pair OCR gating with any backend.--check-ocrgate just makes that failure mode explicit instead of silent-garbage-in.