Skip to main content

Production-grade document-to-Markdown conversion library with hexagonal architecture.

Project description

CyberDocExtractor

CI Security Coverage Python License: MIT Code style: ruff Typed

Production-grade Python library for converting PDF, DOCX, DOC, XLSX, XLS and CSV documents to Markdown. Multiple precision levels, automatic fallback, LLM-assisted image descriptions, and a strict hexagonal core.

⚠️ Status: early development (Phase 1 / Foundation). The public API is not yet stable. The project skeleton, tooling, CI, and architectural guardrails are in place; domain/application/infra layers are under construction. See the project roadmap.

Why another document extractor?

Extraction tooling is a fragmented landscape — each upstream library (Docling, PyMuPDF, pdfplumber, python-docx, openpyxl, …) has its own model, error semantics, and failure modes. CyberDocExtractor wraps them behind a single typed domain model and applies:

  • Hexagonal architecture — the domain doesn't know what PyMuPDF is.
  • Pluggable extractors — swap, reorder, or add adapters without touching the core.
  • Automatic fallback — if the preferred extractor fails, the next one in the policy chain is tried.
  • Deterministic quality scoring — every conversion comes with a 0.0-1.0 score so downstream consumers can gate on confidence.
  • Typed, immutable value objects everywhere.
  • Strict CI: mypy strict, ruff with pydocstyle, import-linter architectural contracts, coverage floor of 90%, matrix tests on Linux + macOS × Python 3.11/3.12/3.13.

Installation

pip install cyberdocextractor            # core only
pip install cyberdocextractor[pdf]       # + PDF adapters
pip install cyberdocextractor[docx]      # + DOCX adapter
pip install cyberdocextractor[xlsx]      # + XLSX adapter
pip install cyberdocextractor[llm]       # + LLM image description
pip install cyberdocextractor[cli]       # + Typer CLI
pip install cyberdocextractor[all]       # everything

Quick start

from pathlib import Path
from cyberdocextractor import Document, PrecisionLevel, build_pipeline

pipeline = build_pipeline()

source = Path("report.pdf")
doc = Document.from_path(source, precision=PrecisionLevel.BALANCED)

result = pipeline.convert(doc)
print(result.markdown.text)
print(f"quality={result.markdown.quality_score:.2f}, extractor={result.extractor}")

CLI:

cyberdoc convert report.pdf --level 2 --output report.md
cyberdoc batch ./inputs ./outputs --pattern '*.pdf'
cyberdoc status
cyberdoc version

Architecture

┌──────────────────────────────────────┐
│               CLI                    │  cyberdoc convert …
├──────────────────────────────────────┤
│            Application               │  ConversionPipeline + stages
│  (extraction → metadata → profile   │
│   → image enrichment → render)       │
├──────────────────────────────────────┤
│            Infrastructure            │  PyMuPDF, pdfplumber, Docling,
│                                      │  openpyxl, Jinja2, OpenAI-compat
├──────────────────────────────────────┤
│              Domain                  │  Document, Block, NormalizedDoc,
│   (pure, zero-dependency core)       │  Extractor / Policy / Renderer
└──────────────────────────────────────┘
            ▲ depends on (↑ only)

import-linter enforces the arrows in CI. See docs/architecture/overview.md (coming in Phase 7) for the full write-up.

Precision levels

Level Name Typical extractor Trade-off
1 FASTEST chunked PyMuPDF speed > fidelity, no table stats
2 BALANCED pymupdf4llm default; good text + table output
3 TABLE_OPTIMIZED pdfplumber best for structured tables
4 HIGHEST_QUALITY Docling OCR, images, layout — slowest

The SelectionPolicy picks the chain automatically from file size, MIME type, and hinted table presence, but callers can override with doc.precision = PrecisionLevel.HIGHEST_QUALITY.

Roadmap

Phase Scope Status
1 Tooling, CI, architectural scaffolding ✅ in progress
2 Domain layer (models, ports, rules) ⏳ next
3 Application layer + DI container
4 Infra adapters (extractors, LLM, Jinja)
5 CLI + public API
6 BDD scenarios
7 mkdocs-material site + ADRs
8 v0.1.0 release + PyPI publish

Development

just bootstrap   # install dev env
just check       # format + lint + types + arch + tests
just test        # tests with coverage gate
just docs-serve  # preview docs

See CONTRIBUTING.md for details.

Security

See SECURITY.md for the responsible disclosure policy.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cyberdocextractor-0.1.1.tar.gz (44.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cyberdocextractor-0.1.1-py3-none-any.whl (67.0 kB view details)

Uploaded Python 3

File details

Details for the file cyberdocextractor-0.1.1.tar.gz.

File metadata

  • Download URL: cyberdocextractor-0.1.1.tar.gz
  • Upload date:
  • Size: 44.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cyberdocextractor-0.1.1.tar.gz
Algorithm Hash digest
SHA256 24cf2674fac912309a935da8cabad404c23398f6219fc7551b86c18cad8ef9ae
MD5 87d8ca089e0cd0bac0e778ffd51e93eb
BLAKE2b-256 ac7e067d3764248dc374e65ef31f49fbeb15efe32dddd3f83c9b615901481c7d

See more details on using hashes here.

File details

Details for the file cyberdocextractor-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for cyberdocextractor-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ea769653bf44c12a2eec15fb27df52348ece9f530fcd125bf6f907fe6b00f9f2
MD5 c51f512bf5b1900e32b783a671ff6ed5
BLAKE2b-256 9d5cb6670fbf0991a6b7ff849cf10744536e3ef29e1da090a00bcbb43c777d2c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page