Operations API¶
The four operations. Each has a sync form and an async a-prefixed
form — use the async form inside a running event loop. parse is the only
operation that needs the OCR server; classify, split, and extract
accept either a ParseResult or a raw file path.
from ingestlib.operations import parse, classify, split, extract
from ingestlib.operations import aparse, aclassify, asplit, aextract
parse¶
ingestlib.operations.parse.pipeline.aparse
async
¶
aparse(path: Path | str, *, dpi: int = 200) -> ParseResult
Parse a document into a ParseResult (async).
path — PDF/DOCX/PPTX document, or a PNG/JPEG/WebP image (parsed as a one-page document) dpi — page render resolution for PDFs; 200 balances OCR accuracy against VLM token cost and memory (images keep their own size)
ingestlib.operations.parse.pipeline.parse ¶
parse(path: Path | str, *, dpi: int = 200) -> ParseResult
Parse a document into a ParseResult.
Synchronous wrapper around aparse(). If you're already inside an event loop, use aparse() instead.
classify¶
ingestlib.operations.classify.classifier.aclassify
async
¶
aclassify(
source: ParseResult | Path | str,
categories: dict[str, str] | None = None,
*,
target_pages: str | None = None,
max_pages: int | None = None,
) -> ClassifyResult
Classify a document's type (async).
source — a ParseResult from parse(), or a document/image path
(PDF/DOCX/PPTX/PNG/JPEG/WebP — no OCR run; images classify
through the vision LLM)
categories — optional {snake_case_label: description}, max 20; when given,
the result is one of these labels or "uncategorized". None
uses rules.yaml's classify: preset; {} forces open-ended.
target_pages — optional 1-based page selection like "1,3,5-7"
max_pages — optional cap applied after selection (the 100-page hard cap
always applies)
ingestlib.operations.classify.classifier.classify ¶
classify(
source: ParseResult | Path | str,
categories: dict[str, str] | None = None,
*,
target_pages: str | None = None,
max_pages: int | None = None,
) -> ClassifyResult
Classify a document's type. Sync wrapper — use aclassify() inside an event loop.
split¶
ingestlib.operations.split.splitter.asplit
async
¶
asplit(
source: ParseResult | Path | str,
*,
category: str | None = None,
max_chunk_tokens: int = DEFAULT_MAX_CHUNK_TOKENS,
vocabulary: dict[str, str] | None = None,
unmatched: str | None = None,
) -> SplitResult
Split a document into sections and natural chunks (async).
source — a ParseResult from parse(), or a PDF/DOCX/PPTX path
(no OCR run; scans and images have no text layer —
parse() them first)
category — optional document-type label (e.g. from classify()) used in
each chunk's embedding_text breadcrumb
max_chunk_tokens — ceiling on chunk size; natural boundaries rule below it
vocabulary — optional {section: description}, max 50; when given, Pass 1
is skipped and pages label against YOUR sections. None uses
rules.yaml's split: preset; {} forces LLM discovery.
unmatched — pages fitting no user category: "other" (default — an
honest other section) | "require" (left-neighbor repair)
| "skip" (dropped). None uses the preset.
ingestlib.operations.split.splitter.split ¶
split(
source: ParseResult | Path | str,
*,
category: str | None = None,
max_chunk_tokens: int = DEFAULT_MAX_CHUNK_TOKENS,
vocabulary: dict[str, str] | None = None,
unmatched: str | None = None,
) -> SplitResult
Split a document into sections and natural chunks.
Sync wrapper — use asplit() inside an event loop.
extract¶
ingestlib.operations.extract.extractor.aextract
async
¶
aextract(
source: ParseResult | Path | str,
schema: Type[SchemaT],
*,
mode: str = "one",
target_pages: str | None = None,
instructions: str | None = None,
) -> ExtractResult
Extract schema instances from a document (async).
source — a ParseResult from parse() (region-level provenance), or a document path (native text, page-level provenance; scans and images have no text layer — parse() them first) schema — any Pydantic model; its top-level fields are what gets extracted and cited mode — "one": a single instance per document (invoice, contract); "many": every instance found (receipts, line items) target_pages — optional 1-based page selection like "1,3,5-7" instructions — optional domain guidance appended to the prompt, e.g. "totals include tax; dates as YYYY-MM-DD"
Provenance is verified, never trusted: cited regions must exist, and a value that can't be found in its cited source has its confidence capped (FieldValue.grounded says which). 100-page cap, as everywhere.
ingestlib.operations.extract.extractor.extract ¶
extract(
source: ParseResult | Path | str,
schema: Type[SchemaT],
*,
mode: str = "one",
target_pages: str | None = None,
instructions: str | None = None,
) -> ExtractResult
Extract schema instances from a document. Sync wrapper — use aextract() inside an event loop.