openextract
Structured extraction for Pythonv1.0 · MIT

Any file in.
A validated model out.

One function

openextract reads documents, images, audio, and video with the LLM of your choice and hands back a typed Pydantic object. Not a string. Not a dict. The model you asked for, already validated.

Install

Installs every provider SDK. For just one, use its extra, like [anthropic]. Set its API key and call extract.

pip install 'openextract[all]'
No media type needed
0000  25 50 44 46 2d 31 2e 35  %PDF-1.5
0008  0a 25 8f 0a 31 30 30 20  .%..100
0010  30 20 6f 62 6a 0a 3c 3c  0 obj.<<
0018  20 2f 46 69 6c 74 65 72   /Filter
0020  20 2f 46 6c 61 74 65 44   /FlateD
0028  65 63 6f 64 65 20 2f 4c  ecode /L
leading bytes →application/pdf
invoice.pdf → Invoice3 fields · validated
Every character on the page is a candidate. Three fields become your model.str · float · str
Exampleextract.py

Name the shape.
Get the facts.

Source — invoice.pdf

Halvorsen Print Co.1

Kanalgata 14, 5003 Bergen, Norway

Invoice
No. 2291
Issued
12 Sep 2026
Due
12 Oct 2026
Letterpress run, 500 cards860.00
Cotton stock, 600 gsm380.00
Total due1,240.002 EUR3
Call — extract.py
from pydantic import BaseModel
from openextract import extract


class Invoice(BaseModel):
    vendor: str
    total: float
    currency: str


invoice = extract(
    Invoice,
    "openai:gpt-5",
    "invoice.pdf",
)
Output — Invoice
1
vendor
Halvorsen Print Co.
2
total
1240.0
3
currency
EUR
Reference2 functions · 4 exceptions

Everything else
is inferred.

extract()What do I pass in?
extract(schema, model, source, instructions=None, *, media_type=None)
schema
The Pydantic model you want back.
model
A pydantic-ai model string like "anthropic:claude-sonnet-5", or a configured Model.
source
A file path, a pathlib.Path, an https:// URL, or raw bytes.
instructions
Optional guidance, like "Amounts are in EUR."
media_type
Only needed to override what openextract infers.
media_typeHow does it know the file type?

It takes the first answer it finds: the media_type you passed, the file extension, the URL's Content-Type header, then the file's leading bytes.

Recognized by content
PDF, PNG, JPEG, GIF, WebP, MP3, WAV, FLAC, OGG, MP4, and UTF-8 text.
exceptionsWhat happens when it fails?

Every error subclasses ExtractionError and keeps the original exception as its cause.

ModelError
The provider returns an error.
SchemaValidationError
The output doesn't match your schema.
ProviderNotInstalledError
The provider's SDK isn't installed.
ExtractionError
A URL can't be fetched.
providersWhich models can I use?

Any model pydantic-ai supports. Install the matching extra and set its API key.

pip install 'openextract[anthropic]'   # openai, google, bedrock, groq, mistral,
                                       # cohere, huggingface, openrouter, xai, all
extract_async()Is there an async version?

Yes. It takes the same arguments. Await it.

invoice = await extract_async(Invoice, "openai:gpt-5", "invoice.pdf")