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, XLSX 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.0.tar.gz (42.0 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.0-py3-none-any.whl (62.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: cyberdocextractor-0.1.0.tar.gz
  • Upload date:
  • Size: 42.0 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.0.tar.gz
Algorithm Hash digest
SHA256 e5f899c661054a45743348c4fbae8866906915bcc7cf9adf4d72d26482cf0964
MD5 ef79929c324e038e957aa01b0e1af02a
BLAKE2b-256 54843a3b04fc3c5956107e57176b38de42f8b5aa94aef4924e1fa272161ebd43

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cyberdocextractor-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 303d933ca629fcbb60ba7c25ad3bd54109ac8cea74a6038887cb3df36270e5a0
MD5 bd2c468138e0c548f1c8fe1c2bea53c9
BLAKE2b-256 272a2061e0c06f2c9f3fb6808cb404024a89b7daaa523f1c49317fc09f9f249f

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