Skip to content

Document Parser SDK ​

Before the WRL Chunker can characterize enterprise data at 40 byte granularity, Caber must extract clean UTF8 text, structural elements, byte offset mappings, and security metadata from heterogeneous document formats. While Caber includes built in parsers for PDF, Office documents (DOCX, XLSX, PPTX), HTML/Markdown, structured JSON/CSV/Parquet, source code, and OCR via Apache Tika and IBM Docling, enterprises often have proprietary file formats, CAD/engineering schematics, medical imaging reports (DICOM/HL7), or custom financial feeds.

The Caber Document Parser SDK (pycaber.parser_sdk in Python and document_parser_container / document_parser_types in Rust) enables developers to register custom document parsers and post extraction enrichers that plug directly into the DocParser.formatRouter pipeline.

Document Parser SDK and Connector SDK Extensibility
Figure 1: Document Parser SDK and Connector SDK Extensibility Pipeline Feeding caber_core
## 2. Core Data Structures

Every custom parser produces a ParsedDocument composed of DocumentElement records so that downstream 40 byte WRL Chunker matches can always be traced back to the exact page, table cell, or section of the original binary file:

Type / StructFieldsPurpose
DocumentMetadocument_sha256: str, mime_type: str | None, filename: str | None, suffix: strCoordinator supplied document identity envelope passed to /parse.
ElementTypeSection, Paragraph, Table, Figure, Footnote, Header, Footer, ListItem, Quote, CodeSemantic structural role of an extracted block.
DocumentElementid: Uuid, element_type: ElementType, content: str, page_number: int | None, order: int, properties: dict, bounding_box: BoundingBox | None, parent_id: Uuid | None, children_ids: list[Uuid]Atomic structural unit emitted by a parser.
ParsedDocumentid: Uuid, metadata: DocumentMetadata, elements: list[DocumentElement], structure: DocumentStructure, processing_info: ProcessingInfo, references: ReferenceMap, enhanced_toc: list[EnhancedTocEntry]Complete output passed to the WRL Chunker and shared-storage.
EnrichmentResultadded_elements: list[DocumentElement], annotations: dict[Uuid, list[Annotation]], additional_metadata: dict[str, Any], added_relationships: list[ElementRelationship], stage_metrics: StageMetricsAdditive enrichment payload merged into ParsedDocument.
HealthStatushealthy: bool, message: str, details: dict[str, Any]Readiness and liveness report emitted by GET /health.

3. Exhaustive Python SDK Reference (pycaber.parser_sdk) ​

The Python SDK is exposed via the pycaber.parser_sdk package (backed by the native pycaber_parser cdylib built with PyO3). It provides lifecycle functions, callback registration hooks, and server supervisors.

3.1 pycaber.parser_sdk.register_parser ​

Registers a Python callable as the active document parser for the container. The registered callback is invoked whenever the container receives a POST /parse request.

Syntax ​

python
def register_parser(callback: Callable[[str, dict[str, Any]], dict[str, Any] | str]) -> None

Parameters ​

ParameterTypeRequiredDescription
callbackCallable[[str, dict], dict | str]YesA Python callable accepting (file_path, config) and returning a dictionary or JSON string conforming to the canonical ParseEnvelope or ParsedDocument schema.

Return Value ​

  • None. Registers the callback globally or synchronously attaches it to the running ContainerServer.

Behavioral Guarantees & Exceptions ​

  • May be called before or after serve(). If called before serve(), the callback is queued in PENDING_PARSER and attached upon server boot.
  • If called while the server is active, it attaches dynamically to the live Tokio runtime.
  • Raises RuntimeError if invoked on an active server without a running Tokio event loop.
  • The callback receives:
    • file_path (str): Absolute filesystem path to the temporary work file containing document bytes.
    • config (dict): Combined configuration containing coordinator supplied custom_options, mime_type, and filename.

3.2 pycaber.parser_sdk.register_enricher ​

Registers a Python callable as the active document enricher for the container. The registered callback is invoked whenever the container receives a POST /enrich request.

Syntax ​

python
def register_enricher(callback: Callable[[str, dict[str, Any]], dict[str, Any] | str]) -> None

Parameters ​

ParameterTypeRequiredDescription
callbackCallable[[str, dict], dict | str]YesA Python callable accepting (document_json_path, config) and returning a dictionary or JSON string conforming to EnrichEnvelope or EnrichmentResult.

Return Value ​

  • None. Registers the enricher globally or attaches it to the running ContainerServer.

Behavioral Guarantees & Exceptions ​

  • Queued in PENDING_ENRICHER if invoked prior to serve().
  • Raises RuntimeError if called while the server is running without an accessible Tokio runtime context.
  • Enricher output is merged into the master document using the complementary merge pattern; existing element IDs and spans are preserved while new annotations and relationships are appended.

3.3 pycaber.parser_sdk.serve ​

Starts the container HTTP server using Axum and Tokio multi thread runtime, binding to the designated TCP port and blocking the calling thread until a graceful termination signal (SIGINT, SIGTERM, or Ctrl+C) is caught.

Syntax ​

python
def serve(
    config: ContainerConfig | None = None,
    port: int | None = None
) -> None

Parameters ​

ParameterTypeDefaultDescription
configContainerConfig | NoneNoneStructured container configuration object. If omitted, values are loaded from environment variables (CABER_PARSER_*).
portint | NoneNoneShorthand override for TCP port. If specified without config, equivalent to passing ContainerConfig(port=port).

Return Value ​

  • None. Blocks until server shutdown completes.

Behavioral Guarantees & Exceptions ​

  • Automatically releases the Python GIL during network polling and asynchronous dispatch (py.allow_threads).
  • If manifest_path is configured in ContainerConfig or CABER_PARSER_MANIFEST_PATH, the server loads and caches the manifest JSON file before opening TCP sockets.
  • Raises RuntimeError if Tokio runtime initialization fails or if binding the TCP socket fails (such as address already in use).

3.4 pycaber.parser_sdk.serve_worker_supervisor ​

Launches a multi process WorkerSupervisor backed container server. Designed for heavy machine learning and parsing workloads (such as IBM Docling or GLiNER) that require isolated worker processes to prevent Python memory fragmentation or interpreter crashes.

Syntax ​

python
def serve_worker_supervisor(
    capabilities: list[tuple[str, str]],
    config: ContainerConfig | None = None,
    port: int | None = None,
    python_path: str | None = None,
    scripts_dir: str | None = None,
    default_capability: str | None = None
) -> None

Parameters ​

ParameterTypeDefaultDescription
capabilitieslist[tuple[str, str]]RequiredList of (capability_name, runner_module) pairs (e.g. [("docling", "docling_runner"), ("gliner", "gliner_runner")]).
configContainerConfig | NoneNoneContainer configuration settings.
portint | NoneNoneShorthand TCP port override.
python_pathstr | NoneNonePath to worker Python interpreter executable. Defaults to active virtual environment executable.
scripts_dirstr | NoneNoneDirectory containing runner scripts. If omitted, uses embedded orchestrator scripts.
default_capabilitystr | NoneNoneCapability invoked when incoming request omits explicit capability selection. Defaults to the first entry in capabilities.

Return Value ​

  • None. Blocks until supervisor termination.

Behavioral Guarantees & Exceptions ​

  • Raises ValueError if capabilities is empty or if no default capability can be determined.
  • Employs fault tolerant pool initialization (start_tolerant). If an individual worker fails model loading (e.g. GPU out of memory), the failure reason is recorded in unavailable_capabilities.
  • GET /health reports the exact availability status per capability and returns HTTP 503 if the primary parse capability is unavailable.
  • Incoming requests targeting an unavailable capability are rejected with HTTP 503 before writing work files to disk.

3.5 pycaber.parser_sdk.ContainerConfig ​

Data configuration class governing container server behavior, timeouts, and resource paths.

Fields & Constructor ​

python
class ContainerConfig:
    port: int = 8081
    shutdown_timeout_seconds: int = 30
    manifest_path: str | None = None
    temp_dir: str | None = None

    def __init__(
        self,
        port: int = 8081,
        shutdown_timeout_seconds: int = 30,
        manifest_path: str | None = None,
        temp_dir: str | None = None
    ) -> None: ...

Field Specifications ​

FieldTypeDefaultEnvironment VariableDescription
portint8081CABER_PARSER_PORTTCP port on which the Axum REST engine listens.
shutdown_timeout_secondsint30CABER_PARSER_SHUTDOWN_TIMEOUTMaximum grace period in seconds to wait for in flight requests during shutdown.
manifest_pathstr | NoneNoneCABER_PARSER_MANIFEST_PATHPath to manifest.json describing parser capabilities and requirements.
temp_dirstr | NoneNoneCABER_PARSER_TEMP_DIRWorking directory for transient document disk buffers. Defaults to system temp directory.

4. Container HTTP REST Wire Protocol Specification ​

The Caber Document Parser Container exposes a standardized, versioned HTTP REST interface. Every request carries schema_version which must strictly match the engine schema version ("4.2").

Protocol Summary Table ​

MethodEndpointRequest BodySuccess ResponseError CodesDescription
POST/parseParseRequestParseResponse400, 500, 503Primary structural extraction endpoint.
POST/enrichEnrichRequestEnrichResponse400, 500, 503NLP and metadata enrichment endpoint.
GET/healthNoneHealthStatus200, 503Liveness and capability readiness probe.
GET/manifestNoneParserManifest200Parser declaration and resource metadata.

4.1 Endpoint: POST /parse ​

Executes primary structure and text extraction on an incoming document.

Request Headers ​

  • Content-Type: application/json

Request Payload (ParseRequest) ​

json
{
  "schema_version": "4.2",
  "handle": {
    "Bytes": {
      "data": "JVBERi0xLjQKJ..."
    }
  },
  "doc": {
    "document_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "mime_type": "application/pdf",
    "filename": "quarterly_financials.pdf",
    "suffix": ".pdf"
  },
  "config": {
    "extract_structure": true,
    "extract_tables": true,
    "ocr_enabled": false,
    "custom_options": {
      "capability": "docling",
      "detect_code": true
    }
  }
}

Response Payload (ParseResponse) ​

json
{
  "schema_version": "4.2",
  "document": {
    "id": "7b0a51c4-1422-4411-9e73-b3c12658cb02",
    "metadata": {
      "file_path": "quarterly_financials.pdf",
      "file_name": "quarterly_financials.pdf",
      "file_extension": "pdf",
      "mime_type": "application/pdf",
      "total_pages": 4
    },
    "elements": [
      {
        "id": "9a38f36c-946a-4d22-bf44-64b58e705b11",
        "element_type": "section",
        "content": "Consolidated Financial Statements",
        "page_number": 1,
        "order": 0,
        "properties": {
          "level": 1
        },
        "bounding_box": null,
        "parent_id": null,
        "children_ids": []
      },
      {
        "id": "18c886e2-2a54-469b-9860-75d164ad9c22",
        "element_type": "paragraph",
        "content": "Revenues for the fiscal quarter ended September 30 reached record highs.",
        "page_number": 1,
        "order": 1,
        "properties": {
          "word_count": 11,
          "bytes": 72
        },
        "bounding_box": null,
        "parent_id": null,
        "children_ids": []
      }
    ],
    "structure": {
      "section_count": 1,
      "paragraph_count": 1,
      "table_count": 0,
      "figure_count": 0,
      "footnote_count": 0,
      "total_word_count": 11,
      "total_bytes": 72
    },
    "processing_info": {
      "parser_type": "docling",
      "processing_time_ms": 142
    },
    "references": {
      "tables": {},
      "figures": {},
      "footnotes": {},
      "sections": {}
    },
    "enhanced_toc": []
  },
  "metrics": {
    "processing_time_ms": 142,
    "elements_processed": 2,
    "annotations_added": 0,
    "elements_added": 2
  }
}

Status Codes & Error Conditions ​

  • 200 OK: Successful document parsing.
  • 400 Bad Request: Schema version skew (schema_version != "4.2") or invalid base64 byte handle.
  • 500 Internal Server Error: Disk write failure, memory exhaustion, or parsing worker crash.
  • 503 Service Unavailable: No parser callback registered or requested supervisor capability is unavailable.

4.2 Endpoint: POST /enrich ​

Applies post parsing NLP, PII classification, or entity recognition to an existing ParsedDocument.

Request Payload (EnrichRequest) ​

json
{
  "schema_version": "4.2",
  "document": { ... },
  "handle": {
    "LocalPath": {
      "path": "/var/tmp/quarterly_financials.pdf"
    }
  },
  "doc": {
    "document_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "mime_type": "application/pdf",
    "filename": "quarterly_financials.pdf",
    "suffix": ".pdf"
  },
  "config": {
    "custom_options": {
      "capability": "gliner",
      "confidence_threshold": 0.85
    }
  }
}

Response Payload (EnrichResponse) ​

json
{
  "schema_version": "4.2",
  "result": {
    "added_elements": [],
    "annotations": {
      "18c886e2-2a54-469b-9860-75d164ad9c22": [
        {
          "annotation_type": "ner",
          "value": {
            "entity": "September 30",
            "label": "DATE"
          },
          "confidence": 0.98,
          "source_parser": "gliner_enricher"
        }
      ]
    },
    "additional_metadata": {
      "contains_financial_figures": true
    },
    "added_relationships": [],
    "stage_metrics": {
      "processing_time_ms": 38,
      "elements_processed": 2,
      "annotations_added": 1,
      "elements_added": 0
    }
  },
  "metrics": {
    "processing_time_ms": 38,
    "elements_processed": 2,
    "annotations_added": 1,
    "elements_added": 0
  }
}

4.3 Endpoint: GET /health ​

Liveness and capability readiness verification endpoint.

Response Payload (HealthStatus) ​

json
{
  "healthy": true,
  "message": "OK",
  "details": {
    "uptime_seconds": 3612,
    "parser_registered": true,
    "enricher_registered": true,
    "capabilities": {
      "docling": "ready",
      "gliner": "ready"
    }
  }
}

Unhealthy Response (HTTP 503) ​

json
{
  "healthy": false,
  "message": "primary parse capability unavailable",
  "details": {
    "uptime_seconds": 12,
    "parser_registered": false,
    "enricher_registered": true,
    "capabilities": {
      "docling": "unavailable: CUDA driver initialization failed (out of memory)"
    }
  }
}

4.4 Endpoint: GET /manifest ​

Returns the static capability manifest declaring supported MIME types, file formats, and resource allocations.

Response Payload (ParserManifest) ​

json
{
  "parser_type": "docling_standard_parser",
  "version": "2.5.0",
  "description": "High performance document parser for PDF, Office, and structured formats",
  "capabilities": ["StructureExtract", "Ocr"],
  "supported_formats": ["pdf", "docx", "pptx", "xlsx", "html"],
  "supported_languages": ["en", "de", "fr", "es"],
  "requires_gpu": true,
  "gpu_memory_mb": 8192,
  "min_memory_mb": 4096,
  "chain_position": "Primary",
  "produces": ["structure", "ocr_text"],
  "consumes": [],
  "python_dependencies": [
    {
      "package": "docling",
      "version_constraint": ">=2.0,<3.0",
      "optional": false
    }
  ],
  "required_config": [],
  "health_check_interval_seconds": 30
}

5. Parser CLI Command Reference (pycaber.parser_sdk.cli) ​

Caber provides dedicated command line interfaces to validate custom parsers, run local parse test suites, and verify byte offset alignment against the WRL Chunker.

5.1 python -m pycaber.parser_sdk.cli test-parse ​

Validates that a custom parser plugin correctly extracts elements and verifies that emitted byte spans round trip cleanly against the 40 byte WRL chunking engine.

Syntax ​

bash
.venv/bin/python -m pycaber.parser_sdk.cli test-parse [OPTIONS]

Parameter & Flag Options ​

Flag / OptionTypeRequiredDefaultDescription
--pluginstrYesN/ADot separated Python module path containing the parser class (e.g. my_org_parsers.hl7_clinical).
--inputpathYesN/AAbsolute or relative filesystem path to the test document file.
--verify-wrl-chunksflagNoFalseWhen present, immediately runs the extracted text through the WRL Chunker and verifies byte offset round trip integrity.
--min-chunk-bytesintNo40Minimum byte window size for WRL characterization verification.
--output-dirpathNoNoneOptional directory where extracted elements.json and fulltext.txt should be written.
--verboseflagNoFalseEmits detailed per element bounding boxes and processing timings.

Example Invocations ​

bash
# Validate HL7 parser and verify 40 byte WRL chunks
.venv/bin/python -m pycaber.parser_sdk.cli test-parse \
  --plugin my_org_parsers.hl7_clinical \
  --input tests/fixtures/sample_note.hl7 \
  --verify-wrl-chunks \
  --min-chunk-bytes 40

# Verbose inspection of CAD specification parser emitting to disk
.venv/bin/python -m pycaber.parser_sdk.cli test-parse \
  --plugin my_org_parsers.cad_spec \
  --input fixtures/engine_bracket.stepmeta \
  --output-dir /tmp/parsed_output \
  --verbose

Exit Codes ​

Exit CodeMeaning
0Success. All elements extracted, spans valid, and WRL chunk verification passed.
1Parse execution error or unhandled exception raised by plugin.
2Span boundary mismatch (e.g. utf8_end exceeds document length or spans overlap improperly).
3WRL chunk verification failed (element byte offsets failed round trip characterization).

7. Registering Custom Parsers in DocParser.formatRouter ​

Configure DocParser.formatRouter and DocParser.pluginModules in your deployment configuration (CSI_CONFIG_FILE) so Caber routes matching extensions or MIME types to your custom parser:

json
{
  "DocParser": {
    "defaultBackend": "docling",
    "fallbackBackend": "tika",
    "preserveByteOffsets": true,
    "pluginModules": [
      "my_org_parsers.hl7_clinical",
      "my_org_parsers.export_control"
    ],
    "formatRouter": {
      ".hl7": "hl7_clinical_parser",
      ".cadspec": "custom_cad_spec_parser",
      ".pdf": "docling",
      ".docx": "docling",
      ".pptx": "docling",
      ".html": "native_html",
      ".md": "native_markdown"
    }
  }
}