← Back to list

Here’s how I extracted content from PDF files without an API key

I explored Kreuzberg as a document intelligence tool to extract content from PDF files

Arunabh Bora · 2025-02-25 11:25 · 1 claps · 3.5 min read
#document-intelligence #text-extraction #kreuzberg
Open on Medium ↗

Here’s how I extracted content from PDF files without an API key

I explored Kreuzberg as a document intelligence tool to extract content from PDF files

Image generated using FLUX.1-dev

Image generated using FLUX.1-dev

Document intelligence is the process of using AI and machine learning to automatically extract, classify, and analyze data from documents, transforming unstructured content into understandable content.

When we speak of document intelligence, the first tools that come to mind are AWS Textract or Azure Document Intelligence. These tools are highly effective and well-suited for complex use cases. However, they come with a price tag and can create vendor lock-in with cloud platforms.

There are also free alternatives, like Unstructured, which offer a lot of features for parsing and extracting data from documents. These tools are a great option for smaller projects or teams looking to avoid cloud dependencies and maintain control over their infrastructure.

Where is document intelligence used?

Document intelligence is used in LLM power applications, mostly in RAG systems. It helps us to extract insights from large documents that have complex structures, such as tables, nested sections, and dense text, which would be time-consuming and error-prone to process manually.

By automating data extraction, document intelligence makes it easier to analyze lengthy reports, research papers, or legal contracts, turning unstructured content into actionable knowledge.

How does Kreuzberg help?

Kreuzberg is a lightweight Python library for text extraction from documents. It provides a unified asynchronous interface for handling multiple document formats.

Kreuzberg has only two dependencies: Tesseract and Pandoc. All processing is done locally, without the need for API calls. This makes it ideal for use in serverless functions and Dockerized applications.

[embed]GitHub - Goldziher/kreuzberg: A text extraction library supporting PDFs, images, office documents… A text extraction library supporting PDFs, images, office documents and more - Goldziher/kreuzberggithub.com

Kreuzberg under the hood

Kreuzberg is equipped with a powerful suite of tools for handling diverse document types. For PDF processing, it uses pdfium2 for searchable PDFs and Tesseract OCR for scanned content. Its document conversion capabilities include Pandoc for various document and markup formats, python-pptx for PowerPoint files, html-to-markdown for converting HTML content, and calamine for Excel spreadsheets with multi-sheet support. On the text processing side, Kreuzberg offers smart encoding detection, along with seamless handling of both Markdown and plain text files.

Therefore, it can handle multiple file formats — pdf, docx, pptx, rtf, pub, html, txt, xlsx, jpg etc. You can read about it in the official Github repo.

The library offers function for both single file processing and batch processing (both sync and async).

All extraction functions return an ExtractionResult object or a list of object (for batch functions). The ExtractionResult object has the following attributes:

  • content: The extracted text (str)
  • mime_type: Output format ("text/plain" or "text/markdown" for Pandoc conversions)
  • metadata: A metadata dictionary. Currently this dictionary is only populated when extracting documents using pandoc.

Testing it out

I tested it out using some sample PDF documents. You can check out the repo on my Github.

1 — Using Kreuzbreg on a searchable/scanned PDF file.

from pathlib import Path
from kreuzberg import extract_file
from kreuzberg import ExtractionResult
from kreuzberg import PSMMode

# Basic file extraction
async def extract_document():
    # Extract from a PDF file with default settings
    pdf_result: ExtractionResult = await extract_file("data/searchable-pdf.pdf")
    return pdf_result

if __name__ == "__main__":
    import asyncio
    res = asyncio.run(extract_document())

    # Export to markdown
    with open("results/output-searchable-pdf.md", "w") as f:
        f.write(res.content)
        print("Output written to output.md")

2 — Using Kreuzberg in a batch extract

from pathlib import Path
from kreuzberg import batch_extract_file, batch_extract_bytes, batch_extract_file_sync
import asyncio

# Process multiple files concurrently
async def process_documents(file_paths: list[Path]) -> None:
    # Extract from multiple files
    results = await batch_extract_file(file_paths)
    return results

if __name__ == "__main__":
    # Process multiple files concurrently
    file_paths = [Path("data/batch-extract/sample-doc-1.pdf"), Path("data/batch-extract/sample-doc-2.pdf")] 
    res = asyncio.run(process_documents(file_paths))
    for path, result in zip(file_paths, res):
        print(f"File {path}: {result.content[:100]}...")
        with open(f'results/batch-extract-results/{path.stem}.md', 'w') as f:
            f.write(str(result))

Observations

In both the single and batch extraction tests, Kreuzberg successfully extracted content from PDF files. Its performance on scanned documents was impressive, handling OCR well.

Screenshot of text extracted from searchable pdf

Screenshot of text extracted from searchable pdf

Screenshot of text extracted from scanned pdf

Screenshot of text extracted from scanned pdf

However, I noticed limitations when extracting tables. The tool flattened the table structure, losing the row and column organization. This made it difficult to analyze tabular data, especially in documents where preserving the layout was essential for proper interpretation.

Despite this, Kreuzberg is a solid choice for local, API-free document extraction — especially if your primary goal is text extraction rather than structured data.

https://buymeacoffee.com/arunabhbora

https://buymeacoffee.com/arunabhbora


메타데이터
post_id
f9d25403203a
slug
heres-how-i-extracted-content-from-pdf-files-without-an-api-key-f9d25403203a
url
https://medium.com/@arunabh223/heres-how-i-extracted-content-from-pdf-files-without-an-api-key-f9d25403203a
canonical_url
https://medium.com/@arunabh223/heres-how-i-extracted-content-from-pdf-files-without-an-api-key-f9d25403203a
author_url
https://medium.com/@arunabh223
status
ok
fetched_at
2026-08-21 17:48:53