Skip to content

Converters API

Document format converters used in Stage 0 (Preprocess).

Converter Registry

scinr.newton.converters.registry

converters/registry.py — Extension-to-converter registry.

Provides get_converter(path) which returns the appropriate BaseConverter instance for a given file path.

apply_converter_overrides

apply_converter_overrides(
    overrides: dict[str, type],
) -> None

Apply converter overrides/additions to the registry.

Parameters

overrides: Dict mapping file extensions (without leading dot, lowercase) to BaseConverter subclasses. Existing extensions are overridden. New extensions are registered.

Raises

ConfigurationError If any converter class is not a subclass of BaseConverter.

Example

configure(extra_converters={ "pdf": MyCustomPdfConverter, # override built-in PDF converter "epub": EpubConverter, # add new format })

get_converter

get_converter(path: Path) -> BaseConverter

Return the appropriate converter instance for path.

Parameters

path: File to be converted. The extension (case-insensitive, without leading dot) is used to look up the converter.

Returns

BaseConverter A freshly instantiated converter for the file's format.

Raises

UnsupportedFormatError If no converter is registered for the file's extension.

list_supported_extensions

list_supported_extensions() -> list[str]

Return all registered file extensions in sorted order.

Returns

list[str] Sorted list of supported extensions (without leading dots).

Base Classes

scinr.newton.converters.base

converters/base.py — Core dataclasses and abstract base converter.

Defines the intermediate document format that all converters produce, and the BaseConverter abstract class that all format-specific converters must implement.

BaseConverter

Bases: ABC

Abstract base class for all format-specific converters.

Subclasses must: 1. Define supported_extensions (frozenset of lowercase extensions without leading dot, e.g. frozenset({"pdf"})). 2. Implement convert(source).

Parameters

supported_extensions : frozenset[str] Class attribute listing the file extensions this converter handles.

convert abstractmethod

convert(source: Path) -> IntermediateDocument

Convert source to the intermediate document format.

Parameters

source: Path to the source file to convert.

Returns

IntermediateDocument The converted document with one or more pages.

Raises

ConversionError If conversion fails for any reason. FileNotFoundError If source does not exist.

convert_and_write

convert_and_write(source: Path, output_dir: Path) -> Path

Convert source and write the result to output_dir.

The output file is named {source.stem}.json. If a file with that name already exists, a numeric suffix is appended to avoid silent overwriting (e.g. doc_1.json).

Parameters

source: Path to the source file to convert. output_dir: Directory where the JSON output will be written. Created automatically if it does not exist.

Returns

Path Path to the written output file.

Raises

ConversionError If conversion fails.

ConversionError

Bases: ConverterError, ScinrError

Raised when a converter fails to process a specific file.

ConverterError

Bases: Exception

Base class for converter errors (kept for backward compatibility).

IntermediateDocument

Bases: BaseModel

A complete document in the intermediate format.

This is the root object serialised to JSON and written to data/input/ or data/input-pruebas/.

to_json

to_json(indent: int = 2) -> str

Serialise to JSON string.

Parameters

indent: JSON indentation level.

Returns

str JSON representation of this document.

IntermediatePage

Bases: BaseModel

A single page of a document in the intermediate format.

This schema mirrors the Mistral OCR output consumed by Stage 1.

PageDimensions

Bases: BaseModel

Physical dimensions of a page.

PageImage

Bases: BaseModel

An image extracted from a page.

Parameters

index: Zero-based position of the image within the page. base64: Base64-encoded image bytes. media_type: MIME type of the image (e.g. "image/png"). description: Optional textual description. Left empty by converters; filled by Stage 1 using LLM vision.

UnsupportedFormatError

Bases: ConverterError

Raised when no converter is registered for the given file extension.

Format Converters

scinr.newton.converters.pdf

converters/pdf.py — PDF to Markdown converter via Mistral OCR API.

Encodes the PDF as base64 and submits it to the Mistral OCR endpoint (POST https://api.mistral.ai/v1/ocr). The API response already matches the intermediate document format, so each page is mapped directly to an IntermediatePage.

Para PDFs que exceden los límites de la API de Mistral OCR (máx. 1000 páginas / 50 MB por solicitud), el documento se divide automáticamente en chunks contiguos (ver pdf_splitter.py), cada uno se envía por separado, y los resultados se reúnen de forma transparente preservando el índice de página absoluto del documento original. El manejo de errores por chunk es configurable vía mistral_ocr_error_strategy ("fail_fast" por defecto, o "best_effort").

PdfConverter

Bases: BaseConverter

Convert .pdf files to the intermediate format via Mistral OCR.

Sends the PDF to the Mistral OCR API and maps the response to an :class:~converters.base.IntermediateDocument. Each page returned by Mistral becomes one :class:~converters.base.IntermediatePage.

Si el PDF excede los límites configurados de páginas o bytes, se divide en chunks contiguos (ver :mod:pdf_splitter), cada uno se envía por separado a la API, y las páginas resultantes se reúnen preservando el índice absoluto del documento original.

Parameters

api_key: Mistral API key. If None, the value of the environment variable MISTRAL_API_KEY is used at conversion time. safe_max_pages: Override explícito del máximo de páginas por chunk. Si None, se resuelve vía get_config() o el default del módulo. safe_max_bytes: Override explícito del máximo de bytes por chunk. Si None, se resuelve vía get_config() o el default del módulo. max_retries: Override explícito del número máximo de intentos por chunk. retry_backoff_seconds: Override explícito de la base del backoff exponencial entre reintentos. error_strategy: Override explícito de la estrategia de manejo de errores por chunk: "fail_fast" o "best_effort".

Nota: esta estrategia solo aplica a fallos de red/API por chunk
(reintentos agotados, errores HTTP no reintentables) sobre chunks
ya generados por ``split_pdf()``. NO cubre el caso en que la
propia partición inicial falla estructuralmente
(:class:`PdfSplitError`, una página individual que excede
``safe_max_bytes`` incluso aislada) — en ese caso el documento
aborta siempre, independientemente del ``error_strategy``
configurado.

convert

convert(source: Path) -> IntermediateDocument

Convert a PDF file to the intermediate format.

Parameters

source: Path to the .pdf file.

Returns

IntermediateDocument Document with one :class:~converters.base.IntermediatePage per PDF page recognised by Mistral OCR. If el documento fue dividido en chunks y alguno falló en modo best_effort, missing_page_ranges contendrá los rangos omitidos.

Raises

FileNotFoundError If source does not exist. ConversionError If the Mistral API key is not available, the HTTP request fails, or the response is in an unexpected format.

scinr.newton.converters.docx

converters/docx.py — Microsoft Word DOCX to Markdown converter.

The DOCX document is split into pages using a two-layer strategy (tried in order, first match wins):

  1. Explicit breaks — any <w:br w:type="page"/> run or <w:sectPr> section break triggers a page flush. A safety cap of _PARAGRAPHS_PER_PAGE elements is also applied so that a single logical section never grows unbounded.
  2. Paragraph count — fallback; a new page every _PARAGRAPHS_PER_PAGE elements (paragraphs + tables counted together).

No content is ever discarded.

DocxConverter

Bases: BaseConverter

Convert .docx files to a paginated Markdown document.

Uses python-docx to iterate over paragraphs and tables in document order. Headings are detected via paragraph style names and prefixed with the appropriate number of # characters. Tables are rendered as GFM Markdown tables.

Pagination strategy (first applicable wins):

  1. Explicit breaks (<w:br w:type="page"/> or <w:sectPr>), with a _PARAGRAPHS_PER_PAGE safety cap per section.
  2. Paragraph/table count — new page every _PARAGRAPHS_PER_PAGE elements.

convert

convert(source: Path) -> IntermediateDocument

Convert a DOCX file to the intermediate format.

Parameters:

Name Type Description Default
source Path

Path to the .docx file.

required

Returns:

Type Description
IntermediateDocument

Multi-page document. The number of pages depends on which

IntermediateDocument

pagination strategy is applied (see class docstring).

Raises:

Type Description
ConversionError

If python-docx is not installed or the file cannot be parsed.

FileNotFoundError

If source does not exist.

scinr.newton.converters.pptx

converters/pptx.py — Microsoft PowerPoint PPTX to Markdown converter.

Each slide is rendered as a separate page. Text frames are converted to Markdown (titles get a # prefix). Images are extracted as base64-encoded PageImage objects. Tables are rendered as GFM Markdown tables.

PptxConverter

Bases: BaseConverter

Convert .pptx files to the intermediate format.

Each slide becomes a separate IntermediatePage. Text is extracted from all text frames (title shapes get a # prefix). Images are base64-encoded and stored as PageImage objects. Tables are converted to GFM Markdown tables.

Requires python-pptx and optionally Pillow for media-type detection (falls back to image/png if Pillow is unavailable).

convert

convert(source: Path) -> IntermediateDocument

Convert a PPTX file to the intermediate format.

Parameters

source: Path to the .pptx file.

Returns

IntermediateDocument Multi-page document, one page per slide.

Raises

ConversionError If python-pptx is not installed or the file cannot be parsed. FileNotFoundError If source does not exist.

scinr.newton.converters.xlsx

converters/xlsx.py — XLSX/XLS files are handled by the tabular ingestion pipeline.

XLSX/XLS files do not require conversion to an intermediate format. Use: python main.py --stage tabular --input-raw

XlsxConverter

Bases: BaseConverter

Redirect handler for .xlsx and .xls files.

XLSX/XLS files are processed directly and efficiently by the tabular ingestion pipeline. This converter raises a :class:ConversionError with a clear redirect message so that callers know to use the correct pipeline stage.

scinr.newton.converters.csv

converters/csv.py — CSV files are handled by the tabular ingestion pipeline.

CSV files do not require conversion to an intermediate format. Use: python main.py --stage tabular --input-raw

CsvConverter

Bases: BaseConverter

Redirect handler for .csv files.

CSV files are processed directly and efficiently by the tabular ingestion pipeline. This converter raises a :class:ConversionError with a clear redirect message so that callers know to use the correct pipeline stage.

scinr.newton.converters.html

converters/html.py — HTML/HTM to Markdown converter.

Extracts structured text from HTML using BeautifulSoup4 + lxml, converts headings/paragraphs/lists/tables to GFM Markdown, and removes noise (scripts, styles, nav, footer).

The document is split into pages at H1 headings (# … in Markdown). Each H1 and its following content form one page. If the HTML has no H1 headings the entire document is a single page. No content is discarded.

HtmlConverter

Bases: BaseConverter

Convert .html and .htm files to the intermediate format.

Parses the HTML with BeautifulSoup4 (lxml backend) and converts the document structure to GFM Markdown. The output is split into one page per H1 heading (# …). Documents without H1 headings produce a single page.

convert

convert(source: Path) -> IntermediateDocument

Convert an HTML file.

Parameters:

Name Type Description Default
source Path

Path to the .html or .htm file.

required

Returns:

Type Description
IntermediateDocument

Multi-page document split at H1 headings (one page per H1

IntermediateDocument

section). Produces a single page when no H1 headings are

IntermediateDocument

present.

Raises:

Type Description
ConversionError

If BeautifulSoup4 or lxml is not installed, or the file cannot be parsed.

scinr.newton.converters.api_json

converters/api_json.py — REST JSON API to intermediate document converter.

Fetches one or more pages of a JSON API, navigates the response with JSONPath expressions, and maps each item to an :class:~converters.base.IntermediatePage. Supports two pagination strategies: following a next URL field (next_url) and classic offset/limit pagination (offset_limit).

Config files can be YAML or JSON and are validated with Pydantic v2.

ApiJsonConverter

Convert a REST JSON API response to the intermediate document format.

This converter does not inherit from :class:~converters.base.BaseConverter because its source is a URL, not a file path. Use :meth:convert_from_url as the main entry point.

Parameters

config: Mapping configuration describing how to navigate the API response. headers: Optional HTTP headers sent with every request (e.g. auth tokens).

convert_from_url

convert_from_url(url: str) -> IntermediateDocument

Fetch the API and convert the response to the intermediate format.

Parameters

url: Base URL of the API endpoint.

Returns

IntermediateDocument One :class:~converters.base.IntermediatePage per item extracted from the API response.

Raises

ConversionError If the HTTP request fails or the response cannot be parsed.

from_config_file classmethod

from_config_file(
    config_path: Path, headers: dict[str, str] | None = None
) -> ApiJsonConverter

Load configuration from a YAML or JSON file.

Parameters

config_path: Path to a .yaml, .yml, or .json config file. headers: Optional HTTP headers forwarded to the constructor.

Returns

ApiJsonConverter

Raises

ConversionError If the file cannot be read, parsed, or validated.

ApiMappingConfig

Bases: BaseModel

Mapping configuration for a JSON REST API.

Parameters

document_name: Human-readable name used in log messages. items_path: JSONPath expression pointing to the array of items in each API response. Use "$" when the response is directly a list. page_fields: Mapping of field roles to JSONPath expressions evaluated on each item. Recognised keys: "title", "content", "metadata" (value may be a list of JSONPath strings). pagination: Optional pagination configuration.

PaginationConfig

Bases: BaseModel

Pagination strategy for a JSON API.

Parameters

type: Pagination strategy: "next_url" follows a URL embedded in the response; "offset_limit" increments an offset query parameter. next_url_path: JSONPath expression pointing to the next-page URL in the response. Only used when type == "next_url". offset_param: Name of the offset query parameter. Only used when type == "offset_limit". limit_param: Name of the limit query parameter. Only used when type == "offset_limit". limit: Page size for offset/limit pagination. total_path: JSONPath expression pointing to the total item count in the response. Only used when type == "offset_limit". max_pages: Hard cap on the number of requests made to prevent infinite loops.

scinr.newton.converters.api_xml

converters/api_xml.py — REST XML / SOAP API to intermediate document converter.

Fetches XML responses (REST or SOAP), parses them with lxml, navigates the document with XPath expressions, and maps each matched element to an :class:~converters.base.IntermediatePage. Supports two pagination strategies (next_url and offset_limit) and optional SOAP envelope wrapping.

Config files can be YAML or JSON and are validated with Pydantic v2.

ApiXmlConverter

Convert a REST XML or SOAP API response to the intermediate format.

This converter does not inherit from :class:~converters.base.BaseConverter because its source is a URL, not a file path. Use :meth:convert_from_url as the main entry point.

Parameters

config: Mapping configuration describing how to navigate the API response. headers: Optional HTTP headers merged into every request (auth tokens, custom headers, etc.). SOAP-related headers are added automatically when required.

convert_from_url

convert_from_url(
    url: str, soap_body: str | None = None
) -> IntermediateDocument

Fetch the API and convert the response to the intermediate format.

Parameters

url: URL of the API endpoint. soap_body: SOAP body content (without the envelope). If provided and config.soap_envelope_template is not None (or config.soap_action is set), the body is wrapped in the SOAP envelope template before sending.

Returns

IntermediateDocument One :class:~converters.base.IntermediatePage per XML element matched by items_xpath.

Raises

ConversionError If the HTTP request fails or the XML cannot be parsed.

from_config_file classmethod

from_config_file(
    config_path: Path, headers: dict[str, str] | None = None
) -> ApiXmlConverter

Load configuration from a YAML or JSON file.

Parameters

config_path: Path to a .yaml, .yml, or .json config file. headers: Optional HTTP headers forwarded to the constructor.

Returns

ApiXmlConverter

Raises

ConversionError If the file cannot be read, parsed, or validated.

ApiXmlMappingConfig

Bases: BaseModel

Mapping configuration for an XML REST or SOAP API.

Parameters

document_name: Human-readable name used in log messages. items_xpath: XPath expression selecting the elements to convert to pages (e.g. "//record"). page_fields: Mapping of field roles to XPath expressions evaluated on each element. Recognised keys: "title", "content", "metadata" (value may be a list of XPath strings). namespaces: XML namespace prefix-to-URI mapping passed to all XPath calls. pagination: Optional pagination configuration. soap_action: Value of the SOAPAction HTTP header. When set, requests are sent as SOAP POSTs. soap_envelope_template: XML template for the SOAP envelope. Must contain a {body} placeholder. When None and soap_action is set, the default SOAP 1.1 envelope is used.

XmlPaginationConfig

Bases: BaseModel

Pagination strategy for an XML API.

Parameters

type: Pagination strategy: "next_url" follows a URL embedded in the response; "offset_limit" increments an offset query parameter. next_url_xpath: XPath expression pointing to the next-page URL text. Only used when type == "next_url". offset_param: Name of the offset query parameter. Only used when type == "offset_limit". limit_param: Name of the limit query parameter. Only used when type == "offset_limit". limit: Page size for offset/limit pagination. total_xpath: XPath expression pointing to the total item count text. Only used when type == "offset_limit". max_pages: Hard cap on the number of requests made to prevent infinite loops.

scinr.newton.converters.text

converters/text.py — Plain text and Markdown converter.

The file is paginated into chunks of _LINES_PER_PAGE lines. Each chunk becomes a separate IntermediatePage. .md files are passed through unchanged (already Markdown); .txt files are used directly. No lines are ever discarded.

TextConverter

Bases: BaseConverter

Convert .txt and .md files to the intermediate format.

The file content is split into pages of _LINES_PER_PAGE lines. Markdown files are passed through as-is; plain text files are used directly. An empty file produces a single empty page.

convert

convert(source: Path) -> IntermediateDocument

Convert a text or Markdown file.

Parameters:

Name Type Description Default
source Path

Path to the .txt or .md file.

required

Returns:

Type Description
IntermediateDocument

Multi-page document (one page per _LINES_PER_PAGE lines).

IntermediateDocument

An empty file produces a single empty page.

Raises:

Type Description
ConversionError

If the file cannot be read.