Skip to content

Examples: Answer questions about a PDF document - #132

Open
florinutz wants to merge 1 commit into
mainfrom
flo/130/pdf-example
Open

Examples: Answer questions about a PDF document#132
florinutz wants to merge 1 commit into
mainfrom
flo/130/pdf-example

Conversation

@florinutz

Copy link
Copy Markdown
Contributor

Closes #130. Supersedes the PDF half of #17.

What it does

Loads the European patent EP0666666B1 straight from its canonical URL, splits each page into 500-character fragments, indexes them in CrateDBVectorStore, and runs three queries against the result. 13 pages become 102 fragments.

The specification is published in English, German and French, so the three queries are the same question in each of those languages, answered from one shared index. That is a property of the document rather than decoration, and it shows something the plain-text example cannot.

Where it came from

The working code is c3cba55 under #17, not the later examples-2 branch, where get_documents() was left mid-experiment with three stacked unreachable returns and a read of the PDF from the working directory.

Rebuilt on current main from there: the docstring no longer claims to use state_of_the_union.txt or to be about Hugging Face, the branch's pyproject.toml stanza is dropped entirely (it pinned langchain-openai <0.3 and pytest <9), and the script header asks for 3.10 rather than 3.9. Embeddings stay on OpenAI, so this costs CI one PDF fetch and nothing else. A key-free path is #131.

Verification

The suite executes every file under examples/, so pypdf joins the test group. Running the program's own get_documents() and store calls against a crate/crate:nightly container, with only the embedding provider swapped out (no key on this machine), loads, splits, indexes and searches end to end. ruff check, ruff format --diff and mypy . are clean, and pdf.py now behaves like the other OpenAI examples under pytest: it needs the key CI supplies.

One thing to decide

PyPDFLoader comes from langchain_community, which emits a sunset warning on import pointing at standalone integration packages. There is no langchain-pypdf on PyPI to move to. Shipping here and revisiting seems right, but it is a choice rather than an oversight.

@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b5dddab8-77b6-4ae5-b215-b87672e2d13b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@florinutz
florinutz marked this pull request as ready for review August 28, 2026 15:58
@florinutz
florinutz requested a review from bgunebakan August 28, 2026 15:58
@florinutz florinutz self-assigned this Aug 28, 2026
@florinutz florinutz added the documentation Improvements or additions to documentation label Aug 28, 2026
Load the European patent EP0666666B1 from its canonical URL, split each page
into fragments, index them in `CrateDBVectorStore`, and query the result.
Document retrieval over a PDF is the shape most people arrive looking for,
and the existing vector example reads a plain text file.

The specification is published in English, German and French, so the program
asks the same question in each of the three, which the embeddings answer from
one shared index.

`pypdf` joins the test group because the suite executes every example.
@florinutz
florinutz force-pushed the flo/130/pdf-example branch from f0f37c7 to 2340569 Compare August 31, 2026 09:19

@bgunebakan bgunebakan left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks, added some comments.

Comment thread examples/basic/pdf.py
Comment on lines +66 to +69
fragments = []
for page in loader.load():
fragments += text_splitter.create_documents([page.page_content])
return fragments

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This loop drops all the metadata PyPDFLoader gives you. create_documents() builds fresh Documents from raw strings, so every one of the 102 fragments comes out with metadata == {}, so no source, no page, no page_label.

Suggested change
fragments = []
for page in loader.load():
fragments += text_splitter.create_documents([page.page_content])
return fragments
return text_splitter.split_documents(loader.load())

Mostly flagging this because it's an example, and "which page did this answer come from?" is the first thing anyone asks of a PDF RAG pipeline. Losing page makes that unanswerable. Bonus: three lines become one :)

Comment thread examples/basic/pdf.py
"""

# Define resource loader.
loader = PyPDFLoader(RESOURCE_URL)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PyPDFLoader fetches remote URLs through a bare requests.get(...) with no timeout. Since the test suite runs every example, a stalled CDN would hang the CI job until GitHub's 6-hour limit.

The other two network examples both use timeout=10 (vector_search.py and document_loader.py)
It's not a blocker but a simple fix could prevent future pipeline issues.

Comment thread examples/basic/pdf.py
# Embed each fragment, and load them into the vector store.
vector_store = CrateDBVectorStore.from_documents(
documents=documents,
embedding=OpenAIEmbeddings(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

from_documents() writes in langchain collection as default, it's not a problem on CI because it drops the DB on every test but locally, all examples goes on same collection (eg. vector_search.py) small fix can be good to show users adding custom collection.

Suggested change
embedding=OpenAIEmbeddings(),
embedding=OpenAIEmbeddings(),
collection_name="pdf_example",

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

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Example: PDF document retrieval

2 participants