Metadata-Version: 2.4
Name: cyberdocextractor
Version: 0.1.1
Summary: Production-grade document-to-Markdown conversion library with hexagonal architecture.
Author-email: Cyberdyne Corp <oss@cyberdyne.example>
License: MIT
License-File: LICENSE
Keywords: csv,document,docx,extraction,hexagonal,markdown,pdf,xlsx
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business
Classifier: Topic :: Text Processing :: Markup :: Markdown
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: jinja2>=3.1
Requires-Dist: typing-extensions>=4.12
Provides-Extra: all
Requires-Dist: defusedxml>=0.7; extra == 'all'
Requires-Dist: docling>=2.57; extra == 'all'
Requires-Dist: httpx>=0.27; extra == 'all'
Requires-Dist: openpyxl>=3.1; extra == 'all'
Requires-Dist: pdfplumber>=0.11; extra == 'all'
Requires-Dist: pillow>=10.0; extra == 'all'
Requires-Dist: pymupdf4llm>=0.0.5; extra == 'all'
Requires-Dist: pymupdf>=1.23; extra == 'all'
Requires-Dist: python-docx>=1.1; extra == 'all'
Requires-Dist: python-dotenv>=1.0; extra == 'all'
Requires-Dist: rich>=13.7; extra == 'all'
Requires-Dist: typer>=0.12; extra == 'all'
Requires-Dist: xlrd>=2.0; extra == 'all'
Provides-Extra: cli
Requires-Dist: rich>=13.7; extra == 'cli'
Requires-Dist: typer>=0.12; extra == 'cli'
Provides-Extra: doc
Requires-Dist: docling>=2.57; extra == 'doc'
Provides-Extra: docx
Requires-Dist: defusedxml>=0.7; extra == 'docx'
Requires-Dist: python-docx>=1.1; extra == 'docx'
Provides-Extra: llm
Requires-Dist: httpx>=0.27; extra == 'llm'
Requires-Dist: pillow>=10.0; extra == 'llm'
Requires-Dist: python-dotenv>=1.0; extra == 'llm'
Provides-Extra: pdf
Requires-Dist: pdfplumber>=0.11; extra == 'pdf'
Requires-Dist: pymupdf4llm>=0.0.5; extra == 'pdf'
Requires-Dist: pymupdf>=1.23; extra == 'pdf'
Provides-Extra: xlsx
Requires-Dist: defusedxml>=0.7; extra == 'xlsx'
Requires-Dist: openpyxl>=3.1; extra == 'xlsx'
Requires-Dist: xlrd>=2.0; extra == 'xlsx'
Description-Content-Type: text/markdown

# CyberDocExtractor

[![CI](https://github.com/CyberdyneCorp/CyberDocExtractor/actions/workflows/ci.yml/badge.svg)](https://github.com/CyberdyneCorp/CyberDocExtractor/actions/workflows/ci.yml)
[![Security](https://github.com/CyberdyneCorp/CyberDocExtractor/actions/workflows/security.yml/badge.svg)](https://github.com/CyberdyneCorp/CyberDocExtractor/actions/workflows/security.yml)
[![Coverage](https://img.shields.io/badge/coverage-%E2%89%A590%25-brightgreen)](./pyproject.toml)
[![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
[![Typed](https://img.shields.io/badge/typed-mypy%20strict-informational)](./pyproject.toml)

> **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](#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

```bash
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

```python
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:

```bash
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`](./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

```bash
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](./CONTRIBUTING.md) for details.

## Security

See [SECURITY.md](./SECURITY.md) for the responsible disclosure policy.

## License

MIT — see [LICENSE](./LICENSE).
