Skip to content

OCR Pipelines Reference

vlm4ocr.ocr_pipelines.IndependentPagePipeline

IndependentPagePipeline(
    process_page: ProcessPage,
    *,
    output_mode: str = "JSON",
    rotate_correction: Union[
        RotateCorrectionMethod, bool
    ] = False,
    max_dimension_pixels: Optional[int] = None
)

Concurrency + loading + assembly scaffold for OCR pipelines in which each page is processed INDEPENDENTLY of every other page.

You supply process_page(image, *, messages_logger=None) -> OCRPage. It receives a single, already-preprocessed page image (and an optional log sink) and returns a standalone OCRPage — typically produced by one or more OCREngine.ocr_image_async calls. Because it cannot access neighbouring pages, cross-page logic is unwritable and independence holds by construction; flows needing sibling context (doc-level classification, continuation pages, cross-page table merges) are out of scope.

The pipeline owns everything reusable: file loading, optional preprocessing (resize + tesseract rotate), page-level concurrency, page ordering, error handling, and OCRResult assembly. concurrent_ocr mirrors OCREngine.concurrent_ocr (same arguments, same first-complete-first-out AsyncGenerator[OCRResult]), so it is a drop-in.

Parameters:

process_page : Callable[..., Awaitable[OCRPage]] async (image, *, messages_logger=None) -> OCRPage. The returned page's text, bboxes, image_width/height and metadata are kept; the pipeline supplies the page's image_processing_status, index, and source path when assembling the result. output_mode : str, Optional Labels the produced OCRResult. Must be 'markdown', 'HTML', 'text', 'JSON', or 'bbox', and should match the output mode of the engines used inside process_page. rotate_correction : {"tesseract", False}, Optional Engine-free rotation correction applied before process_page. "vlm" rotation is not supported at this layer (it needs an engine and would escape the concurrency cap); do vlm-based rotation inside process_page if required. max_dimension_pixels : int, Optional If set, resize each page to fit within this dimension before process_page.

Source code in packages/vlm4ocr/vlm4ocr/ocr_pipelines.py
def __init__(self, process_page: ProcessPage, *, output_mode: str = "JSON",
             rotate_correction: Union[RotateCorrectionMethod, bool] = False,
             max_dimension_pixels: Optional[int] = None):
    if not callable(process_page):
        raise TypeError("process_page must be a callable returning an awaitable OCRPage")
    if output_mode not in ["markdown", "HTML", "text", "JSON", "bbox"]:
        raise ValueError("output_mode must be 'markdown', 'HTML', 'text', 'JSON', or 'bbox'.")
    self.process_page = process_page
    self.output_mode = output_mode
    self.rotate_correction = rotate_correction
    self.max_dimension_pixels = max_dimension_pixels
    # Engine-free processor: supports resize + tesseract rotate. vlm rotation needs an
    # engine and belongs inside process_page, so it is intentionally not offered here.
    self.image_processor = ImageProcessor()

concurrent_ocr

concurrent_ocr(
    file_paths: Union[str, Iterable[str]],
    concurrent_batch_size: int = 32,
    max_file_load: Optional[int] = None,
) -> AsyncGenerator[OCRResult, None]

Process files concurrently. First complete first out; output order not guaranteed.

Parameters:

file_paths : Union[str, Iterable[str]] A file path or list of file paths. Must be one of SUPPORTED_IMAGE_EXTS. concurrent_batch_size : int, Optional Global cap on pages processed concurrently (each page runs one process_page, so ~= concurrent VLM calls when process_page issues calls sequentially). max_file_load : int, Optional Maximum number of files open at once. Defaults to 2 * concurrent_batch_size.

Returns:

AsyncGenerator[OCRResult, None] Yields one OCRResult per file as it completes.

Source code in packages/vlm4ocr/vlm4ocr/ocr_pipelines.py
def concurrent_ocr(self, file_paths: Union[str, Iterable[str]],
                   concurrent_batch_size: int = 32,
                   max_file_load: Optional[int] = None) -> AsyncGenerator[OCRResult, None]:
    """
    Process files concurrently. First complete first out; output order not guaranteed.

    Parameters:
    -----------
    file_paths : Union[str, Iterable[str]]
        A file path or list of file paths. Must be one of SUPPORTED_IMAGE_EXTS.
    concurrent_batch_size : int, Optional
        Global cap on pages processed concurrently (each page runs one process_page,
        so ~= concurrent VLM calls when process_page issues calls sequentially).
    max_file_load : int, Optional
        Maximum number of files open at once. Defaults to 2 * concurrent_batch_size.

    Returns:
    --------
    AsyncGenerator[OCRResult, None]
        Yields one OCRResult per file as it completes.
    """
    if isinstance(file_paths, str):
        file_paths = [file_paths]
    if max_file_load is None:
        max_file_load = concurrent_batch_size * 2
    if not isinstance(max_file_load, int) or max_file_load <= 0:
        raise ValueError("max_file_load must be a positive integer")

    return self._ocr_async(list(file_paths), concurrent_batch_size, max_file_load)