mirror of
https://github.com/hwchase17/langchain.git
synced 2025-06-26 16:43:35 +00:00
PyMuPDF4LLM integration to LangChain (#29953)
## PyMuPDF4LLM integration to LangChain for PDF content extraction in Markdown format ### Description [PyMuPDF4LLM](https://github.com/pymupdf/RAG) makes it easier to extract PDF content in Markdown format, needed for LLM & RAG applications. (License: GNU Affero General Public License v3.0) [langchain-pymupdf4llm](https://github.com/lakinduboteju/langchain-pymupdf4llm) integrates PyMuPDF4LLM to LangChain as a Document Loader. (License: MIT License) This pull request introduces the integration of [PyMuPDF4LLM](https://pymupdf.readthedocs.io/en/latest/pymupdf4llm) into the LangChain project as an integration package: [`langchain-pymupdf4llm`](https://github.com/lakinduboteju/langchain-pymupdf4llm). The most important changes include adding new Jupyter notebooks to document the integration and updating the package configuration file to include the new package. ### Documentation: * `docs/docs/integrations/providers/pymupdf4llm.ipynb`: Added a new Jupyter notebook to document the integration of `PyMuPDF4LLM` with LangChain, including installation instructions and class imports. * `docs/docs/integrations/document_loaders/pymupdf4llm.ipynb`: Added a new Jupyter notebook to document the usage of `langchain-pymupdf4llm` as a LangChain integration package in detail. ### Package registration: * `libs/packages.yml`: Updated the package configuration file to include the `langchain-pymupdf4llm` package. ### Additional information * Related to: https://github.com/langchain-ai/langchain/pull/29848 --------- Co-authored-by: Chester Curme <chester.curme@gmail.com>
This commit is contained in:
parent
d98c3f76c2
commit
e0e9e560b3
721
docs/docs/integrations/document_loaders/pymupdf4llm.ipynb
Normal file
721
docs/docs/integrations/document_loaders/pymupdf4llm.ipynb
Normal file
@ -0,0 +1,721 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"sidebar_label: PyMuPDF4LLM\n",
|
||||
"---"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# PyMuPDF4LLMLoader\n",
|
||||
"\n",
|
||||
"This notebook provides a quick overview for getting started with PyMuPDF4LLM [document loader](https://python.langchain.com/docs/concepts/#document-loaders). For detailed documentation of all PyMuPDF4LLMLoader features and configurations head to the [GitHub repository](https://github.com/lakinduboteju/langchain-pymupdf4llm).\n",
|
||||
"\n",
|
||||
"## Overview\n",
|
||||
"\n",
|
||||
"### Integration details\n",
|
||||
"\n",
|
||||
"| Class | Package | Local | Serializable | JS support |\n",
|
||||
"| :--- | :--- | :---: | :---: | :---: |\n",
|
||||
"| [PyMuPDF4LLMLoader](https://github.com/lakinduboteju/langchain-pymupdf4llm) | [langchain_pymupdf4llm](https://pypi.org/project/langchain-pymupdf4llm) | ✅ | ❌ | ❌ |\n",
|
||||
"\n",
|
||||
"### Loader features\n",
|
||||
"\n",
|
||||
"| Source | Document Lazy Loading | Native Async Support | Extract Images | Extract Tables |\n",
|
||||
"| :---: | :---: | :---: | :---: | :---: |\n",
|
||||
"| PyMuPDF4LLMLoader | ✅ | ❌ | ✅ | ✅ |\n",
|
||||
"\n",
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"To access PyMuPDF4LLM document loader you'll need to install the `langchain-pymupdf4llm` integration package.\n",
|
||||
"\n",
|
||||
"### Credentials\n",
|
||||
"\n",
|
||||
"No credentials are required to use PyMuPDF4LLMLoader."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you want to get automated best in-class tracing of your model calls you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# os.environ[\"LANGSMITH_API_KEY\"] = getpass.getpass(\"Enter your LangSmith API key: \")\n",
|
||||
"# os.environ[\"LANGSMITH_TRACING\"] = \"true\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Installation\n",
|
||||
"\n",
|
||||
"Install **langchain_community** and **langchain-pymupdf4llm**."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install -qU langchain_community langchain-pymupdf4llm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Initialization\n",
|
||||
"\n",
|
||||
"Now we can instantiate our model object and load documents:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_pymupdf4llm import PyMuPDF4LLMLoader\n",
|
||||
"\n",
|
||||
"file_path = \"./example_data/layout-parser-paper.pdf\"\n",
|
||||
"loader = PyMuPDF4LLMLoader(file_path)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Document(metadata={'producer': 'pdfTeX-1.40.21', 'creator': 'LaTeX with hyperref', 'creationdate': '2021-06-22T01:27:10+00:00', 'source': './example_data/layout-parser-paper.pdf', 'file_path': './example_data/layout-parser-paper.pdf', 'total_pages': 16, 'format': 'PDF 1.5', 'title': '', 'author': '', 'subject': '', 'keywords': '', 'moddate': '2021-06-22T01:27:10+00:00', 'trapped': '', 'modDate': 'D:20210622012710Z', 'creationDate': 'D:20210622012710Z', 'page': 0}, page_content='```\\nLayoutParser: A Unified Toolkit for Deep\\n\\n## Learning Based Document Image Analysis\\n\\n```\\n\\nZejiang Shen[1] (<28>), Ruochen Zhang[2], Melissa Dell[3], Benjamin Charles Germain\\nLee[4], Jacob Carlson[3], and Weining Li[5]\\n\\n1 Allen Institute for AI\\n```\\n shannons@allenai.org\\n\\n```\\n2 Brown University\\n```\\n ruochen zhang@brown.edu\\n\\n```\\n3 Harvard University\\n_{melissadell,jacob carlson}@fas.harvard.edu_\\n4 University of Washington\\n```\\n bcgl@cs.washington.edu\\n\\n```\\n5 University of Waterloo\\n```\\n w422li@uwaterloo.ca\\n\\n```\\n\\n**Abstract. Recent advances in document image analysis (DIA) have been**\\nprimarily driven by the application of neural networks. Ideally, research\\noutcomes could be easily deployed in production and extended for further\\ninvestigation. However, various factors like loosely organized codebases\\nand sophisticated model configurations complicate the easy reuse of important innovations by a wide audience. Though there have been on-going\\nefforts to improve reusability and simplify deep learning (DL) model\\ndevelopment in disciplines like natural language processing and computer\\nvision, none of them are optimized for challenges in the domain of DIA.\\nThis represents a major gap in the existing toolkit, as DIA is central to\\nacademic research across a wide range of disciplines in the social sciences\\nand humanities. This paper introduces LayoutParser, an open-source\\nlibrary for streamlining the usage of DL in DIA research and applications. The core LayoutParser library comes with a set of simple and\\nintuitive interfaces for applying and customizing DL models for layout detection, character recognition, and many other document processing tasks.\\nTo promote extensibility, LayoutParser also incorporates a community\\nplatform for sharing both pre-trained models and full document digitization pipelines. We demonstrate that LayoutParser is helpful for both\\nlightweight and large-scale digitization pipelines in real-word use cases.\\n[The library is publicly available at https://layout-parser.github.io.](https://layout-parser.github.io)\\n\\n**Keywords: Document Image Analysis · Deep Learning · Layout Analysis**\\n\\n - Character Recognition · Open Source library · Toolkit.\\n\\n### 1 Introduction\\n\\n\\nDeep Learning(DL)-based approaches are the state-of-the-art for a wide range of\\ndocument image analysis (DIA) tasks including document image classification [11,\\n\\n')"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"docs = loader.load()\n",
|
||||
"docs[0]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'producer': 'pdfTeX-1.40.21',\n",
|
||||
" 'creator': 'LaTeX with hyperref',\n",
|
||||
" 'creationdate': '2021-06-22T01:27:10+00:00',\n",
|
||||
" 'source': './example_data/layout-parser-paper.pdf',\n",
|
||||
" 'file_path': './example_data/layout-parser-paper.pdf',\n",
|
||||
" 'total_pages': 16,\n",
|
||||
" 'format': 'PDF 1.5',\n",
|
||||
" 'title': '',\n",
|
||||
" 'author': '',\n",
|
||||
" 'subject': '',\n",
|
||||
" 'keywords': '',\n",
|
||||
" 'moddate': '2021-06-22T01:27:10+00:00',\n",
|
||||
" 'trapped': '',\n",
|
||||
" 'modDate': 'D:20210622012710Z',\n",
|
||||
" 'creationDate': 'D:20210622012710Z',\n",
|
||||
" 'page': 0}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import pprint\n",
|
||||
"\n",
|
||||
"pprint.pp(docs[0].metadata)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Lazy Load"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"6"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pages = []\n",
|
||||
"for doc in loader.lazy_load():\n",
|
||||
" pages.append(doc)\n",
|
||||
" if len(pages) >= 10:\n",
|
||||
" # do some paged operation, e.g.\n",
|
||||
" # index.upsert(page)\n",
|
||||
"\n",
|
||||
" pages = []\n",
|
||||
"len(pages)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from IPython.display import Markdown, display\n",
|
||||
"\n",
|
||||
"part = pages[0].page_content[778:1189]\n",
|
||||
"print(part)\n",
|
||||
"# Markdown rendering\n",
|
||||
"display(Markdown(part))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'producer': 'pdfTeX-1.40.21',\n",
|
||||
" 'creator': 'LaTeX with hyperref',\n",
|
||||
" 'creationdate': '2021-06-22T01:27:10+00:00',\n",
|
||||
" 'source': './example_data/layout-parser-paper.pdf',\n",
|
||||
" 'file_path': './example_data/layout-parser-paper.pdf',\n",
|
||||
" 'total_pages': 16,\n",
|
||||
" 'format': 'PDF 1.5',\n",
|
||||
" 'title': '',\n",
|
||||
" 'author': '',\n",
|
||||
" 'subject': '',\n",
|
||||
" 'keywords': '',\n",
|
||||
" 'moddate': '2021-06-22T01:27:10+00:00',\n",
|
||||
" 'trapped': '',\n",
|
||||
" 'modDate': 'D:20210622012710Z',\n",
|
||||
" 'creationDate': 'D:20210622012710Z',\n",
|
||||
" 'page': 10}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pprint.pp(pages[0].metadata)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The metadata attribute contains at least the following keys:\n",
|
||||
"- source\n",
|
||||
"- page (if in mode *page*)\n",
|
||||
"- total_page\n",
|
||||
"- creationdate\n",
|
||||
"- creator\n",
|
||||
"- producer\n",
|
||||
"\n",
|
||||
"Additional metadata are specific to each parser.\n",
|
||||
"These pieces of information can be helpful (to categorize your PDFs for example)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Splitting mode & custom pages delimiter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"When loading the PDF file you can split it in two different ways:\n",
|
||||
"- By page\n",
|
||||
"- As a single text flow\n",
|
||||
"\n",
|
||||
"By default PyMuPDF4LLMLoader will split the PDF by page."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Extract the PDF by page. Each page is extracted as a langchain Document object:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"16\n",
|
||||
"{'producer': 'pdfTeX-1.40.21',\n",
|
||||
" 'creator': 'LaTeX with hyperref',\n",
|
||||
" 'creationdate': '2021-06-22T01:27:10+00:00',\n",
|
||||
" 'source': './example_data/layout-parser-paper.pdf',\n",
|
||||
" 'file_path': './example_data/layout-parser-paper.pdf',\n",
|
||||
" 'total_pages': 16,\n",
|
||||
" 'format': 'PDF 1.5',\n",
|
||||
" 'title': '',\n",
|
||||
" 'author': '',\n",
|
||||
" 'subject': '',\n",
|
||||
" 'keywords': '',\n",
|
||||
" 'moddate': '2021-06-22T01:27:10+00:00',\n",
|
||||
" 'trapped': '',\n",
|
||||
" 'modDate': 'D:20210622012710Z',\n",
|
||||
" 'creationDate': 'D:20210622012710Z',\n",
|
||||
" 'page': 0}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"loader = PyMuPDF4LLMLoader(\n",
|
||||
" \"./example_data/layout-parser-paper.pdf\",\n",
|
||||
" mode=\"page\",\n",
|
||||
")\n",
|
||||
"docs = loader.load()\n",
|
||||
"\n",
|
||||
"print(len(docs))\n",
|
||||
"pprint.pp(docs[0].metadata)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In this mode the pdf is split by pages and the resulting Documents metadata contains the `page` (page number). But in some cases we could want to process the pdf as a single text flow (so we don't cut some paragraphs in half). In this case you can use the *single* mode :"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Extract the whole PDF as a single langchain Document object:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1\n",
|
||||
"{'producer': 'pdfTeX-1.40.21',\n",
|
||||
" 'creator': 'LaTeX with hyperref',\n",
|
||||
" 'creationdate': '2021-06-22T01:27:10+00:00',\n",
|
||||
" 'source': './example_data/layout-parser-paper.pdf',\n",
|
||||
" 'file_path': './example_data/layout-parser-paper.pdf',\n",
|
||||
" 'total_pages': 16,\n",
|
||||
" 'format': 'PDF 1.5',\n",
|
||||
" 'title': '',\n",
|
||||
" 'author': '',\n",
|
||||
" 'subject': '',\n",
|
||||
" 'keywords': '',\n",
|
||||
" 'moddate': '2021-06-22T01:27:10+00:00',\n",
|
||||
" 'trapped': '',\n",
|
||||
" 'modDate': 'D:20210622012710Z',\n",
|
||||
" 'creationDate': 'D:20210622012710Z'}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"loader = PyMuPDF4LLMLoader(\n",
|
||||
" \"./example_data/layout-parser-paper.pdf\",\n",
|
||||
" mode=\"single\",\n",
|
||||
")\n",
|
||||
"docs = loader.load()\n",
|
||||
"\n",
|
||||
"print(len(docs))\n",
|
||||
"pprint.pp(docs[0].metadata)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Logically, in this mode, the `page` (page_number) metadata disappears. Here's how to clearly identify where pages end in the text flow :"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Add a custom *pages_delimiter* to identify where are ends of pages in *single* mode:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"loader = PyMuPDF4LLMLoader(\n",
|
||||
" \"./example_data/layout-parser-paper.pdf\",\n",
|
||||
" mode=\"single\",\n",
|
||||
" pages_delimiter=\"\\n-------THIS IS A CUSTOM END OF PAGE-------\\n\\n\",\n",
|
||||
")\n",
|
||||
"docs = loader.load()\n",
|
||||
"\n",
|
||||
"part = docs[0].page_content[10663:11317]\n",
|
||||
"print(part)\n",
|
||||
"display(Markdown(part))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The default `pages_delimiter` is \\n-----\\n\\n.\n",
|
||||
"But this could simply be \\n, or \\f to clearly indicate a page change, or \\<!-- PAGE BREAK --> for seamless injection in a Markdown viewer without a visual effect."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Extract images from the PDF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You can extract images from your PDFs (in text form) with a choice of three different solutions:\n",
|
||||
"- rapidOCR (lightweight Optical Character Recognition tool)\n",
|
||||
"- Tesseract (OCR tool with high precision)\n",
|
||||
"- Multimodal language model\n",
|
||||
"\n",
|
||||
"The result is inserted at the end of text of the page."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Extract images from the PDF with rapidOCR:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install -qU rapidocr-onnxruntime pillow"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.document_loaders.parsers import RapidOCRBlobParser\n",
|
||||
"\n",
|
||||
"loader = PyMuPDF4LLMLoader(\n",
|
||||
" \"./example_data/layout-parser-paper.pdf\",\n",
|
||||
" mode=\"page\",\n",
|
||||
" extract_images=True,\n",
|
||||
" images_parser=RapidOCRBlobParser(),\n",
|
||||
")\n",
|
||||
"docs = loader.load()\n",
|
||||
"\n",
|
||||
"part = docs[5].page_content[1863:]\n",
|
||||
"print(part)\n",
|
||||
"display(Markdown(part))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Be careful, RapidOCR is designed to work with Chinese and English, not other languages."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Extract images from the PDF with Tesseract:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install -qU pytesseract"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.document_loaders.parsers import TesseractBlobParser\n",
|
||||
"\n",
|
||||
"loader = PyMuPDF4LLMLoader(\n",
|
||||
" \"./example_data/layout-parser-paper.pdf\",\n",
|
||||
" mode=\"page\",\n",
|
||||
" extract_images=True,\n",
|
||||
" images_parser=TesseractBlobParser(),\n",
|
||||
")\n",
|
||||
"docs = loader.load()\n",
|
||||
"\n",
|
||||
"print(docs[5].page_content[1863:])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Extract images from the PDF with multimodal model:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install -qU langchain_openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 39,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 39,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"from dotenv import load_dotenv\n",
|
||||
"\n",
|
||||
"load_dotenv()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from getpass import getpass\n",
|
||||
"\n",
|
||||
"if not os.environ.get(\"OPENAI_API_KEY\"):\n",
|
||||
" os.environ[\"OPENAI_API_KEY\"] = getpass(\"OpenAI API key =\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.document_loaders.parsers import LLMImageBlobParser\n",
|
||||
"from langchain_openai import ChatOpenAI\n",
|
||||
"\n",
|
||||
"loader = PyMuPDF4LLMLoader(\n",
|
||||
" \"./example_data/layout-parser-paper.pdf\",\n",
|
||||
" mode=\"page\",\n",
|
||||
" extract_images=True,\n",
|
||||
" images_parser=LLMImageBlobParser(\n",
|
||||
" model=ChatOpenAI(model=\"gpt-4o-mini\", max_tokens=1024)\n",
|
||||
" ),\n",
|
||||
")\n",
|
||||
"docs = loader.load()\n",
|
||||
"\n",
|
||||
"print(docs[5].page_content[1863:])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Extract tables from the PDF\n",
|
||||
"\n",
|
||||
"With PyMUPDF4LLM you can extract tables from your PDFs in *markdown* format :"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"loader = PyMuPDF4LLMLoader(\n",
|
||||
" \"./example_data/layout-parser-paper.pdf\",\n",
|
||||
" mode=\"page\",\n",
|
||||
" # \"lines_strict\" is the default strategy and\n",
|
||||
" # is the most accurate for tables with column and row lines,\n",
|
||||
" # but may not work well with all documents.\n",
|
||||
" # \"lines\" is a less strict strategy that may work better with\n",
|
||||
" # some documents.\n",
|
||||
" # \"text\" is the least strict strategy and may work better\n",
|
||||
" # with documents that do not have tables with lines.\n",
|
||||
" table_strategy=\"lines\",\n",
|
||||
")\n",
|
||||
"docs = loader.load()\n",
|
||||
"\n",
|
||||
"part = docs[4].page_content[3210:]\n",
|
||||
"print(part)\n",
|
||||
"display(Markdown(part))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Working with Files\n",
|
||||
"\n",
|
||||
"Many document loaders involve parsing files. The difference between such loaders usually stems from how the file is parsed, rather than how the file is loaded. For example, you can use `open` to read the binary content of either a PDF or a markdown file, but you need different parsing logic to convert that binary data into text.\n",
|
||||
"\n",
|
||||
"As a result, it can be helpful to decouple the parsing logic from the loading logic, which makes it easier to re-use a given parser regardless of how the data was loaded.\n",
|
||||
"You can use this strategy to analyze different files, with the same parsing parameters."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.document_loaders import FileSystemBlobLoader\n",
|
||||
"from langchain_community.document_loaders.generic import GenericLoader\n",
|
||||
"from langchain_pymupdf4llm import PyMuPDF4LLMParser\n",
|
||||
"\n",
|
||||
"loader = GenericLoader(\n",
|
||||
" blob_loader=FileSystemBlobLoader(\n",
|
||||
" path=\"./example_data/\",\n",
|
||||
" glob=\"*.pdf\",\n",
|
||||
" ),\n",
|
||||
" blob_parser=PyMuPDF4LLMParser(),\n",
|
||||
")\n",
|
||||
"docs = loader.load()\n",
|
||||
"\n",
|
||||
"part = docs[0].page_content[:562]\n",
|
||||
"print(part)\n",
|
||||
"display(Markdown(part))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## API reference\n",
|
||||
"\n",
|
||||
"For detailed documentation of all PyMuPDF4LLMLoader features and configurations head to the GitHub repository: https://github.com/lakinduboteju/langchain-pymupdf4llm"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.21"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
59
docs/docs/integrations/providers/pymupdf4llm.ipynb
Normal file
59
docs/docs/integrations/providers/pymupdf4llm.ipynb
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# PyMuPDF4LLM\n",
|
||||
"\n",
|
||||
"[PyMuPDF4LLM](https://pymupdf.readthedocs.io/en/latest/pymupdf4llm) is aimed to make it easier to extract PDF content in Markdown format, needed for LLM & RAG applications.\n",
|
||||
"\n",
|
||||
"[langchain-pymupdf4llm](https://github.com/lakinduboteju/langchain-pymupdf4llm) integrates PyMuPDF4LLM to LangChain as a Document Loader."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install -qU langchain-pymupdf4llm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "y8ku6X96sebl"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_pymupdf4llm import PyMuPDF4LLMLoader, PyMuPDF4LLMParser"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.11"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
@ -888,6 +888,13 @@ const FEATURE_TABLES = {
|
||||
api: "Package",
|
||||
apiLink: "https://python.langchain.com/api_reference/community/document_loaders/langchain_community.document_loaders.pdf.PyMuPDFLoader.html"
|
||||
},
|
||||
{
|
||||
name: "PyMuPDF4LLM",
|
||||
link: "pymupdf4llm",
|
||||
source: "Load PDF content to Markdown using PyMuPDF4LLM",
|
||||
api: "Package",
|
||||
apiLink: "https://github.com/lakinduboteju/langchain-pymupdf4llm"
|
||||
},
|
||||
{
|
||||
name: "PDFMiner",
|
||||
link: "pdfminer",
|
||||
|
@ -462,8 +462,11 @@ packages:
|
||||
- name: langchain-permit
|
||||
path: .
|
||||
repo: permitio/langchain-permit
|
||||
- name: langchain-pymupdf4llm
|
||||
path: .
|
||||
repo: lakinduboteju/langchain-pymupdf4llm
|
||||
- name: langchain-writer
|
||||
path: .
|
||||
repo: writer/langchain-writer
|
||||
downloads: 0
|
||||
downloads_updated_at: '2025-02-24T13:19:19.816059+00:00'
|
||||
downloads_updated_at: '2025-02-24T13:19:19.816059+00:00'
|
||||
|
Loading…
Reference in New Issue
Block a user