Deterministic document ingestion for PDF, DOCX, Excel, and CSV with quality-aware recovery.
Project description
DocGun
Quality-aware document ingestion for Python and RAG pipelines.
Package name:
docgun
Project name: DocGun
Install:pip install docgun
Import:from docgun import ingest
DocGun turns PDF, DOCX, Excel, and CSV files into a consistent typed document model. It combines deterministic parsing with extraction scoring, page-aware fallback, security limits, and explicit recovery states so incomplete scans do not silently look successful.
- Native PDF text, coordinates, tables, and page provenance with PyMuPDF.
- Ordered DOCX headings, paragraphs, lists, and tables.
- Bounded XLSX/XLSM and batched CSV extraction.
- Page-level Docling fallback with structured elements and provenance.
- Injectable OCR/VLM recovery for only the pages that need it.
- Measurable confidence reports and structured recovery attempts.
- ZIP/Open XML validation, encrypted-PDF detection, and ingestion limits.
- Python API, CLI, and FastAPI upload route.
- TXT, Markdown, HTML, JSON, XML, and PowerPoint support.
- Pluggable batched vectorization and bounded concurrent ingestion.
Before / After
from docgun import ingest
state = ingest("mixed-report.pdf")
print(state.status)
print(state.quality.confidence)
print(len(state.document.elements))
Example output:
completed
0.9142
47
When a scan cannot be recovered, DocGun returns recovery_required with page-level markers and diagnostics instead of presenting an empty page as successfully ingested.
Why Quality-Aware Ingestion?
Document parsers can return technically valid but incomplete output: a scanned page may yield only a footer, a fallback may omit pages, or a table detector may consume nearby text. DocGun makes those failure modes visible:
Input document
-> Validate size, signature, archive safety, and encryption
-> Inspect pages or workbook dimensions
-> Route to a deterministic native parser
-> Score content, structure, tables, and provenance
-> Compare page-level fallback candidates
-> Recover only weak pages with Docling or an OCR/VLM backend
-> Return typed elements, status, quality, warnings, and diagnostics
Pipeline statuses are completed, partially_completed, recovery_required, and failed.
Install
pip install docgun
For Docling and the complete fallback toolset:
pip install "docgun[full]"
For development:
pip install -e ".[dev,full]"
pytest -q
python -m build
Quick Start
Ingest a Document
from docgun import ingest
state = ingest("annual-report.pdf")
for element in state.document.elements:
print(element.type, element.text, element.location)
Inspect Recovery Diagnostics
for attempt in state.recovery_attempts:
print(attempt.action, attempt.status, attempt.error_message)
Configure Page-Level Vision Recovery
Implement extract_batch(rendered_pages) in your OCR or VLM adapter and inject it into the pipeline:
from docgun.agents.recovery import RecoveryEngine
from docgun.agents.vision import VisionPageRecovery
from docgun.pipeline.graph import ingest
class MyVisionBackend:
def extract_batch(self, pages):
return vision_client.extract(pages)
engine = RecoveryEngine(VisionPageRecovery(MyVisionBackend()))
state = ingest("scan.pdf", recovery_engine=engine)
Each backend result may contain text, type, table, bbox, and confidence fields.
CLI
Ingest a file and print the complete pipeline state as JSON:
docgun report.pdf
Print a compact summary:
docgun report.pdf --summary
Supported Formats
| Format | Native parser | Recovery |
|---|---|---|
| PyMuPDF | Docling, then configured page-level OCR/VLM | |
| DOCX | python-docx | Explicit low-confidence status |
| XLSX/XLSM | openpyxl | Explicit low-confidence status |
| CSV | PyArrow | Explicit low-confidence status |
| TXT/Markdown/HTML/JSON/XML | Safe structured-text parser | Explicit low-confidence status |
| PPTX | python-pptx | Layout and reading-order inference |
Vectorization and bulk ingestion
from docgun import discover_files, ingest_many, vectorize_document
for item in ingest_many(discover_files("documents"), workers=8):
if item.state and item.state.document:
records = vectorize_document(item.state.document)
vectorize_document uses deterministic local embeddings by default. Pass a callable embedding backend for production models.
The CLI accepts directories and uses concurrent workers:
docgun ./documents --workers 8 --summary
Architecture
src/docgun/
__init__.py # Public API
cli.py # Command-line interface
agents/ # Inspection, routing, confidence, quality, recovery
api/ # FastAPI upload route
chunking/ # Hierarchical and spreadsheet chunk helpers
domain/ # Typed elements, inspections, and errors
parsers/ # PDF, Docling, DOCX, Excel, and CSV parsers
pipeline/ # Orchestration state and policies
security/ # File limits and format validation
storage/ # Document and vector storage interfaces
tests/ # Unit and regression tests
.github/workflows/ # CI and trusted PyPI publishing
CHANGELOG.md # Release history
pyproject.toml # Package metadata and dependencies
FastAPI
The bundled route streams uploads to a bounded temporary file, maps ingestion errors to appropriate HTTP responses, and removes the temporary file after success or failure.
from fastapi import FastAPI
from docgun.api.routes import router
app = FastAPI()
app.include_router(router, prefix="/documents")
Development
pip install -e ".[dev,full]"
python -m pytest
python -m build
python -m twine check dist/*
License
MIT
Contributing
Contributions are welcome. Please include a representative document or minimal generated fixture, the expected elements, and a regression test for parser or recovery changes.
Citation
@software{DocGun2026,
title={DocGun: Quality-Aware Document Ingestion for Python},
author={Arkay92},
url={https://github.com/Arkay92/DocGun},
year={2026},
version={0.2.0},
}
Acknowledgments
- PyMuPDF for fast native PDF extraction and rendering.
- Docling for layout-aware document conversion.
- python-docx and openpyxl for Office document parsing.
- Apache Arrow for batched CSV ingestion.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file docgun-0.2.1.tar.gz.
File metadata
- Download URL: docgun-0.2.1.tar.gz
- Upload date:
- Size: 25.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5de98c3913c66063849986fb3a6f55d15c7e45080f92d8e78ba696b8bb89657
|
|
| MD5 |
5820d88ca93e58b7812f2e3252fcd8eb
|
|
| BLAKE2b-256 |
be711073b23b4c7076ba01ed36983c7819955996fce29f9a28a35d798d42f870
|
Provenance
The following attestation bundles were made for docgun-0.2.1.tar.gz:
Publisher:
publish.yml on Arkay92/DocGun
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
docgun-0.2.1.tar.gz -
Subject digest:
a5de98c3913c66063849986fb3a6f55d15c7e45080f92d8e78ba696b8bb89657 - Sigstore transparency entry: 2149396647
- Sigstore integration time:
-
Permalink:
Arkay92/DocGun@4a6e46034262b85d1bd160693f5bd009edd01b84 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/Arkay92
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4a6e46034262b85d1bd160693f5bd009edd01b84 -
Trigger Event:
push
-
Statement type:
File details
Details for the file docgun-0.2.1-py3-none-any.whl.
File metadata
- Download URL: docgun-0.2.1-py3-none-any.whl
- Upload date:
- Size: 37.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4a1bbe53fcf0d19237c5b8f18aecb8767f3860dbd29cdc409b14f573d8dcef3
|
|
| MD5 |
eedf6f56e7c3fae87910124bc59f10f1
|
|
| BLAKE2b-256 |
852999488ef63292f803f654e0b72ffaf4c2519ad7106ffa179d53779e803279
|
Provenance
The following attestation bundles were made for docgun-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on Arkay92/DocGun
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
docgun-0.2.1-py3-none-any.whl -
Subject digest:
d4a1bbe53fcf0d19237c5b8f18aecb8767f3860dbd29cdc409b14f573d8dcef3 - Sigstore transparency entry: 2149396835
- Sigstore integration time:
-
Permalink:
Arkay92/DocGun@4a6e46034262b85d1bd160693f5bd009edd01b84 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/Arkay92
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4a6e46034262b85d1bd160693f5bd009edd01b84 -
Trigger Event:
push
-
Statement type: