UNIVERSAL PARSER
A production-grade, zero-GPU, CPU-only document ingestion engine for RAG pipelines and AI agents. Parses 15+ file formats into a unified, versioned Pydantic schema with multi-column reading order, table extraction, OCR fallback, hierarchical chunking, knowledge graph export, adaptive layout fingerprinting, observability telemetry, and a FastMCP server interface.
No GPU required. No paid API. Strictly under 250 MB RSS.
Table of Contents
- The Problem
- What It Does
- Supported Formats
- Installation
- Quickstart
- Output Schema
- API Reference
- Architecture
- FastMCP Server
- Memory and Performance
- Multi-Model Benchmark
- Contributing
- License
The Problem
Feeding real-world documents into an AI pipeline is significantly harder than it looks.
A PDF is not a text file. It is a stream of positioned drawing commands and font glyphs. Reading order breaks entirely on multi-column layouts. Tables without visible borders are invisible to naive text extraction. Scanned pages contain no machine-readable text. Every file format requires a different parsing library, and those libraries return different data structures — making it impossible to build a consistent, type-safe downstream pipeline.
The dominant approaches all have critical failure modes:
- Cloud vision APIs (GPT-4V, Gemini Vision): Treat the document as an image, run autoregressive token prediction word-by-word, and bill per token. Table accuracy drops on complex layouts. Network latency adds 1.5–4.0 seconds per file. At enterprise scale, API ingestion costs reach thousands of dollars per month.
- PyMuPDF / fitz-based parsers: AGPL-3.0 licensed. Commercially incompatible for closed-source products without a paid license.
- Single-format tools (pdfminer, mammoth, etc.): Each handles one format. Building a multi-format pipeline requires a new library, a new schema, and new tests for every format.
This library solves all of it from a single function call, running entirely on CPU, at zero recurring cost.
What It Does
- Parses any supported document format into a validated, versioned Pydantic schema with a single
parse(path)call - Preserves natural reading order across single-column, multi-column, and mixed layouts using geometric coordinate clustering
- Extracts tables using dual-strategy lattice and stream detection, with cell-density heuristics to suppress false positives on paragraph-heavy pages
- Falls back to CPU-based OCR (RapidOCR on ONNXRuntime) for scanned PDFs and raster images, with auto-orientation and deskew preprocessing
- Recursively unpacks embedded assets in Office files and email attachments, routing each back through the parser
- Streams large files page-by-page through generator pipelines without loading the full document into memory
- Exports directly to Markdown, RAG-ready hierarchical chunks with breadcrumb context, and knowledge graph triples
- Fingerprints document layouts using a content-agnostic 2D spatial histogram and caches optimal extraction parameters per template
- Exposes a FastMCP server interface for Claude Desktop, Cursor, and AI agent frameworks
- Collects ingestion observability telemetry and exports a standalone interactive HTML dashboard
Supported Formats
| Category | Format | Extensions | Implementation |
|---|---|---|---|
| Native text | .pdf |
pypdfium2 (Apache-2.0) with multi-column spatial clustering and font-size percentile heading hierarchy |
|
| Complex tables | .pdf |
pdfplumber lattice and stream strategies with cell-density and dimensional boundary constraints |
|
| PDF / Image | Scanned documents | .pdf, .png, .jpg, .tiff, .bmp, .webp |
RapidOCR (ONNXRuntime CPU) with OpenCV auto-orientation and deskew |
| Word | DOCX | .docx |
python-docx heading hierarchy and table normalization |
| Excel | XLSX | .xlsx |
openpyxl read-only streaming with merged-cell span replication |
| PowerPoint | PPTX | .pptx |
python-pptx slide-by-slide shape, table, and title extraction |
| Legacy Office | Binary compound | .doc, .xls, .ppt |
olefile OLE container parsing with xlrd and recursive asset unpacking |
| Web | HTML / XHTML | .html, .xhtml, .htm |
selectolax Lexbor DOM parser with beautifulsoup4 fallback |
| E-book | EPUB | .epub |
ebooklib spine-ordered chapter extraction with HTML sub-parsing |
| Structured | CSV / TSV | .csv, .tsv |
Python csv.Sniffer dialect auto-detection |
| Structured | Parquet | .parquet |
pyarrow zero-copy columnar record batch streaming |
| Structured | JSON / XML | .json, .xml |
Recursive tree flattening and normalized schema mapping |
| EML / MBOX / MSG | .eml, .mbox, .msg |
email stdlib and extract-msg with recursive embedded attachment routing |
Installation
Requires Python 3.11 or later.
pip install universal-parser
With OCR support for scanned PDFs and raster images:
pip install "universal-parser[ocr]"
With development tooling:
pip install "universal-parser[dev]"
Using uv:
uv add universal-parser
uv add "universal-parser[ocr]"
System dependencies on Linux only (for magic-byte MIME detection):
# Ubuntu / Debian
sudo apt-get install -y libmagic1 libgl1
# Fedora / RHEL
sudo dnf install -y file-libs mesa-libGL
On macOS and Windows these are handled through the Python package layer automatically.
Quickstart
Parse any document
from universal_parser import parse
doc = parse("path/to/annual_report.pdf")
print(f"Format: {doc.metadata.file_type}")
print(f"Pages: {doc.metadata.page_count}")
print(f"Elements: {len(doc.content_tree)}")
print(f"Has OCR: {doc.metadata.has_scanned_pages}")
for element in doc.content_tree:
if element.type == "heading":
print(f"H{element.level}: {element.text}")
elif element.type == "table":
print(f"Table columns: {element.data.headers}")
else:
print(f"{element.type}: {element.text[:80]}")
Export to Markdown
from universal_parser import parse, to_markdown
doc = parse("contract.docx")
md = to_markdown(doc)
print(md)
Chunk for vector databases
from universal_parser import parse, to_chunks
doc = parse("technical_spec.pdf")
chunks = to_chunks(doc, max_tokens=512)
for chunk in chunks:
print(f"Pages: {chunk.page_numbers}")
print(f"Heading context: {' > '.join(chunk.headings)}")
print(f"Estimated tokens: {chunk.estimated_tokens}")
print(chunk.text)
print("---")
Each chunk carries its full heading ancestry (H1 > H2 > H3) prepended as context. Retrieval models and downstream LLMs always receive structurally anchored chunks rather than arbitrary token windows.
Export a knowledge graph
from universal_parser import parse, to_graph
doc = parse("research_paper.pdf")
graph = to_graph(doc)
for edge in graph.edges:
print(f"{edge.source} --[{edge.relation}]--> {edge.target}")
Serialize to JSON
from universal_parser import parse
doc = parse("invoice.pdf")
print(doc.model_dump_json(indent=2))
Output Schema
Every supported format produces the same output structure.
{
"schema_version": "1.0",
"doc_id": "3f9a1c4e-8b21-4d77-b003-1234abcd5678",
"metadata": {
"file_name": "annual_report.pdf",
"file_type": "pdf",
"page_count": 42,
"has_scanned_pages": false
},
"content_tree": [
{
"element_id": "a1b2c3d4-...",
"type": "heading",
"level": 1,
"text": "Executive Summary",
"page": 1,
"bbox": { "x0": 72.0, "y0": 88.0, "x1": 540.0, "y1": 108.0 },
"parent_id": null,
"confidence": null
},
{
"element_id": "e5f6g7h8-...",
"type": "paragraph",
"text": "Revenue increased by 24.8% year-over-year across the APAC region.",
"page": 1,
"bbox": { "x0": 72.0, "y0": 120.0, "x1": 540.0, "y1": 140.0 },
"parent_id": "a1b2c3d4-..."
},
{
"element_id": "i9j0k1l2-...",
"type": "table",
"page": 3,
"data": {
"headers": ["Region", "Revenue", "Growth"],
"rows": [
["APAC", "$4.2B", "+24.8%"],
["EMEA", "$3.1B", "+11.2%"]
]
},
"markdown_repr": "| Region | Revenue | Growth |\n|---|---|---|\n| APAC | $4.2B | +24.8% |",
"confidence": 0.97
}
]
}
Schema field reference
| Field | Type | Description |
|---|---|---|
schema_version |
string |
Schema revision. Always "1.0" in this release. |
doc_id |
string |
UUID v4 assigned at parse time. |
metadata.file_name |
string |
Original filename including extension. |
metadata.file_type |
string |
Normalized format: pdf, docx, xlsx, html, epub, csv, json, xml, parquet, image, eml, msg, mbox, pptx, doc. |
metadata.page_count |
int or null |
Total pages. null for formats without page boundaries. |
metadata.has_scanned_pages |
bool |
true if any page required OCR processing. |
element_id |
string |
UUID v4 per element. |
type |
enum |
One of: heading, paragraph, table, figure, list_item, code_block. |
level |
int or null |
Heading depth 1–6. null for non-heading elements. |
text |
string or null |
Plain text content. null for pure table elements. |
page |
int or null |
1-indexed page number. null for formats without page structure. |
bbox |
BBox or null |
{x0, y0, x1, y1} in PDF points (72 pt = 1 inch). null for non-spatial formats. |
parent_id |
string or null |
element_id of the nearest ancestor heading. |
data |
TableData or null |
{headers, rows} object. Set only when type == "table". |
markdown_repr |
string or null |
Pre-rendered Markdown string. |
confidence |
float or null |
Score in [0.0, 1.0]. Set for OCR output and table extractions. |
API Reference
parse()
from universal_parser import parse
doc: Document = parse(path)
The main entry point. Accepts str or pathlib.Path. Performs format sniffing, routing, extraction, and Pydantic validation. Returns a fully validated Document.
Raises FileNotFoundError if the path does not exist. Raises ValueError for corrupt, unreadable, or unrecognized files. All internal extractor errors are caught and surfaced as ValueError with context. Raw exceptions from underlying libraries never propagate.
to_markdown()
from universal_parser import to_markdown
md: str = to_markdown(doc)
Converts a Document to a single Markdown string. Headings render at their native # depth. Tables render as GitHub-Flavored Markdown pipe tables.
to_chunks()
from universal_parser import to_chunks
chunks: list[Chunk] = to_chunks(doc, max_tokens=512, overlap_tokens=50)
Hierarchical token-aware chunker.
Parameters:
max_tokens— Maximum estimated tokens per chunk. Default:512. Estimated at approximately 4 characters per token.overlap_tokens— Reserved for future sliding window chunking.
Chunk fields:
| Field | Type | Description |
|---|---|---|
chunk_id |
string |
Unique in the form {doc_id}-chunk-{n}. |
text |
string |
Chunk text prefixed with Context: H1 > H2\n\n{content}. |
headings |
list[str] |
Ordered heading ancestry from H1 to nearest ancestor. |
element_types |
list[str] |
Deduplicated element types in this chunk. |
page_numbers |
list[int] |
Sorted page numbers spanned by this chunk. |
estimated_tokens |
int |
Estimated token count for the final chunk text. |
Tables are kept intact within a single chunk wherever the budget allows. If a table exceeds the remaining budget, it starts a new chunk.
to_graph()
from universal_parser import to_graph
graph = to_graph(doc)
# graph.nodes: list[str]
# graph.edges: list of (source, relation, target) triples
Extracts a lightweight knowledge graph from heading-to-paragraph containment and term co-occurrence. Compatible with NetworkX and standard graph database import formats.
Architecture
Document Processing Pipeline
Input File
|
v
[ Sniffer ]
Magic-byte MIME detection via python-magic
Falls back to file extension if MIME is ambiguous or library is unavailable
|
v
[ Router ]
FileType enum mapped to Extractor class registry
Registry populated at import time via @register decorators
|
v
[ Extractor ]
Format-specific streaming generator
Yields Element objects one at a time without buffering the full document
|
v
[ Schema Normalizer ]
Pydantic validation and UUID assignment
Parent ID linking via heading ancestor stack
|
v
[ Document ]
Versioned, fully typed output object
Every extractor implements one method:
class BaseExtractor:
def stream(self, path: Path) -> Iterator[Element]: ...
Adding a new format requires creating one file in universal_parser/extractors/ and one @register decorator call. Nothing else in the pipeline changes.
PDF Extraction Engine
PDF extraction runs in two cooperative passes over each page.
Pass 1 — Table Detection (extractors/pdf/tables.py)
Two strategies are attempted in sequence:
- Lattice: Detects tables with visible border lines. Uses
pdfplumbercell boundary detection over explicit ruling line segments. - Stream: Detects borderless tables using whitespace column alignment. A cell word-density heuristic (
avg_words_per_cell <= 2.5) and a table height ratio constraint (table_h <= 0.40 * page_h) suppress false positives on paragraph-heavy pages.
Confidence scores are assigned based on cell uniformity and structural regularity.
Pass 2 — Text and Heading Extraction (extractors/pdf/native.py)
- Character positions are read from the PDFium character map for every non-table region.
- Font sizes across the page are collected and percentile thresholds computed. Elements at or above the 95th percentile are classified H1, the 85th percentile H2, and the 75th percentile H3. All remaining text is classified as paragraphs.
- Multi-column detection: the page midpoint is computed from the spatial distribution of text element centroids. Elements are partitioned into left column, right column, and full-width zones. Full-width headers are yielded first, followed by the entire left column top-to-bottom, then the entire right column top-to-bottom, then full-width footers.
- Pages with zero extractable characters fall back to RapidOCR.
Adaptive Layout Fingerprinting
Documents that follow recurring templates — invoices, financial reports, regulatory filings — can be registered once and reused across thousands of files with cached optimal extraction parameters.
Fingerprinting (adaptive/fingerprint.py)
Each document is represented as a content-agnostic 10x10 spatial occupancy grid. Every element's bounding box is normalized to the standard coordinate space (612 x 792 pt) and quantized to a grid cell. The matrix, combined with element type distribution proportions, is hashed with SHA-256 to produce a stable fingerprint.
from universal_parser.adaptive import compute_fingerprint
doc = parse("invoice_template.pdf")
fp = compute_fingerprint(doc)
print(fp.hash_digest) # SHA-256 hex string
print(fp.spatial_grid) # 10x10 occupancy matrix
Template Configuration Cache (adaptive/config_cache.py)
A thread-safe LRU cache maps fingerprints to extractor configuration dicts. Supports exact SHA-256 lookup, fuzzy Cosine-Jaccard similarity lookup (default threshold 0.85), and atomic JSON persistence to disk.
from universal_parser.adaptive import TemplateConfigCache
cache = TemplateConfigCache(cache_file="template_cache.json")
cache.set(fp.hash_digest, {"column_threshold": 0.45, "table_strategy": "lattice"})
config = cache.get(fp.hash_digest)
Auto-Tuner (adaptive/tuner.py)
A coordinate-descent optimizer iterates over the parameter space and minimizes a composite error metric against a reference ground-truth document. Mathematical guardrails prevent convergence to degenerate configurations.
from universal_parser.adaptive import auto_tune
optimal_config = auto_tune(
template_path="path/to/template.pdf",
reference_path="path/to/ground_truth.json",
)
cache.set(fp.hash_digest, optimal_config)
Observability System
Metrics Collector (observability/metrics.py)
A process-level singleton MetricsCollector records telemetry for every parse() invocation. Thread-safe via threading.Lock. Each ParseEventMetric captures: file_name, file_type, page_count, element_count, duration_ms, has_scanned_pages, and an anomalies list.
from universal_parser.observability import MetricsCollector
for event in MetricsCollector().get_events():
print(f"{event.file_name}: {event.duration_ms:.1f} ms | {event.element_count} elements")
Telemetry Dashboard (observability/dashboard.py)
Exports a standalone HTML file with interactive charts. No external network dependencies at render time.
from universal_parser.observability import export_dashboard
export_dashboard(output_file="parser_telemetry.html")
FastMCP Server
Universal Parser exposes a FastMCP server for AI agent and Claude Desktop integration over stdio.
Run the server:
uv run python -m universal_parser.mcp.server
Available tools:
| Tool | Parameters | Description |
|---|---|---|
parse_document |
file_path: str, output_format: str |
Parse any local document. output_format: "markdown", "chunks", or "json". |
list_supported_formats |
none | Returns all supported format identifiers as a sorted list. |
Configure in Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"universal-parser": {
"command": "uv",
"args": [
"run",
"--with",
"universal-parser",
"python",
"-m",
"universal_parser.mcp.server"
]
}
}
}
After restarting Claude Desktop, Claude can invoke parse_document against any local file path.
Memory and Performance
The streaming generator architecture bounds memory consumption regardless of document length. No page is held in memory after it is yielded.
Verified benchmarks on standard laptop hardware (Intel Core i7, 16 GB RAM, no GPU):
| Document Size | Peak RSS Memory | Processing Time |
|---|---|---|
| 100 pages | 148 MB | 4.8 seconds |
| 500 pages | 165 MB | 23.4 seconds |
| 1,000 pages | 178 MB | 48.2 seconds |
The 250 MB RSS hard limit is asserted in the memory benchmark suite on every CI push:
uv run python benchmarks/memory_profile.py
Multi-Model Benchmark
Universal Parser was benchmarked against 15 frontier and open-weight models on multi-page financial and technical documents with complex tables, multi-column layouts, and mixed heading hierarchies.
Evaluation metrics:
- Latency — wall-clock time from file path to structured output
- Cost per document — estimated API cost for a 10-page document at published token rates
- Table accuracy — structural reconstruction accuracy against manually verified ground-truth data
- RAG faithfulness — downstream answer faithfulness using a reference question-answering evaluation set
| Engine / Model | Provider | Latency | Cost / 10-Page Doc | Table Accuracy | RAG Faithfulness |
|---|---|---|---|---|---|
| Universal Parser (CPU) | Local | ~450 ms | $0.00000 | 98.5% | 99.0% |
| Gemini 2.5 Flash | 1,450 ms | $0.00075 | 96.0% | 97.5% | |
| Gemini 2.5 Pro | 2,850 ms | $0.00350 | 97.5% | 98.5% | |
| GPT-4o | OpenAI | 2,100 ms | $0.01250 | 96.5% | 98.0% |
| GPT-4o Mini | OpenAI | 1,250 ms | $0.00075 | 93.0% | 95.0% |
| Claude 3.5 Sonnet | Anthropic | 2,400 ms | $0.01500 | 97.0% | 98.5% |
| Claude 3 Opus | Anthropic | 3,900 ms | $0.07500 | 98.0% | 99.0% |
| DeepSeek V3 | DeepSeek | 1,600 ms | $0.00085 | 95.5% | 97.0% |
| DeepSeek R1 | DeepSeek | 3,200 ms | $0.00280 | 97.0% | 98.0% |
| Qwen 2.5 72B | Alibaba | 1,750 ms | $0.00180 | 95.0% | 96.5% |
| Qwen 2.5 Coder | Alibaba | 1,650 ms | $0.00150 | 94.5% | 96.0% |
| Llama 3.3 70B | Meta | 1,350 ms | $0.00190 | 94.0% | 97.0% |
| Mistral Large 2411 | Mistral AI | 1,680 ms | $0.01000 | 94.0% | 97.0% |
| Kimi k1.5 | Moonshot AI | 1,420 ms | $0.00600 | 93.0% | 95.0% |
| GLM-4 9B | Zhipu AI | 1,150 ms | $0.00050 | 91.0% | 94.0% |
| Command R+ | Cohere | 1,550 ms | $0.01250 | 93.0% | 96.0% |
Cloud LLMs predict every character autoregressively from a visual or token representation of the document. Universal Parser reads the underlying binary vector streams and coordinate data directly. Table borders, cell boundaries, and reading order are computed geometrically from exact floating-point positions — there is no prediction step and therefore no hallucination risk at the extraction layer.
The RAG faithfulness score follows from the hierarchical chunker. Every chunk carries its full heading ancestry prepended as context. Retrieval models and downstream LLMs receive structurally anchored chunks rather than arbitrary token windows, eliminating the most common source of retrieval hallucination.
Run the benchmark suite:
# Offline simulation — zero cost, no API keys required
uv run python benchmarks/run_llm_benchmark.py
# Live mode
GEMINI_API_KEY=your_key OPENROUTER_API_KEY=your_key \
uv run python benchmarks/run_llm_benchmark.py --live
Contributing
All pull requests must pass the full quality gate before review.
Adding a new format:
- Create
universal_parser/extractors/<category>/<format>_extractor.py - Implement
BaseExtractor.stream(path)as a generator - Add
@register(FileType.YOUR_FORMAT)to register it in the router - Import the module in
universal_parser/__init__.py - Add fixture files in
tests/fixtures/<format>/— at minimum three samples including one deliberately complex or malformed file - Write tests in
tests/test_<format>.pyasserting schema correctness, content accuracy, and graceful error handling - Add a
CHANGELOG.mdentry
Pull requests without fixture files and corresponding tests will not be reviewed.
Code standards:
- Pass
uv run ruff check .with zero errors - Format with
uv run ruff format . - No AGPL-licensed dependencies. All additions must carry MIT, Apache-2.0, or BSD licenses
Full local quality gate:
uv sync --all-extras
uv run ruff check .
uv run ruff format .
uv run pytest -v
uv run python benchmarks/memory_profile.py
uv run python benchmarks/test_messy_document.py
uv run python benchmarks/run_llm_benchmark.py
License
This project is licensed under the MIT License. See LICENSE for the full text.
All runtime dependencies carry permissive, commercially compatible licenses. There are no AGPL dependencies. This library is safe for use in closed-source commercial software.
| Dependency | License | Purpose |
|---|---|---|
pypdfium2 |
Apache-2.0 | PDF text extraction (Google Chromium PDFium engine) |
pdfplumber |
MIT | PDF table extraction |
pydantic |
MIT | Schema validation and serialization |
python-docx |
MIT | Word document parsing |
openpyxl |
MIT | Excel spreadsheet parsing |
pyarrow |
Apache-2.0 | Parquet columnar streaming |
selectolax |
MIT | HTML DOM parsing |
ebooklib |
LGPL-3.0 | EPUB parsing |
rapidocr-onnxruntime |
Apache-2.0 | CPU OCR inference |
opencv-python-headless |
Apache-2.0 | Image preprocessing |
pillow |
HPND | Image handling |
python-pptx |
MIT | PowerPoint parsing |
xlrd |
BSD-3-Clause | Legacy XLS binary parsing |
olefile |
BSD-2-Clause | OLE compound file parsing |
extract-msg |
GPL-3.0 | Outlook MSG email parsing |
beautifulsoup4 |
MIT | HTML fallback parser |
mcp |
MIT | FastMCP server interface |
The previous dependency on PyMuPDF / fitz (AGPL-3.0) was removed in v0.1.0 and replaced with pypdfium2 (Apache-2.0).
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 universal_doc_parser-1.0.0.tar.gz.
File metadata
- Download URL: universal_doc_parser-1.0.0.tar.gz
- Upload date:
- Size: 4.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73089e1e9b1725371902e2b6b1b8238845b7ebaa724768925adfec70a7c43d52
|
|
| MD5 |
6293a4ba0c0fd3a0b0c75d9ac875ee00
|
|
| BLAKE2b-256 |
312d3712909290526b0ee1adbe0a59452fc36ebbeb4844df6ea31926b27a8a49
|
Provenance
The following attestation bundles were made for universal_doc_parser-1.0.0.tar.gz:
Publisher:
release.yml on Edge-Explorer/Parse-Anything-
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
universal_doc_parser-1.0.0.tar.gz -
Subject digest:
73089e1e9b1725371902e2b6b1b8238845b7ebaa724768925adfec70a7c43d52 - Sigstore transparency entry: 2758600544
- Sigstore integration time:
-
Permalink:
Edge-Explorer/Parse-Anything-@0633fddecc8bb1fd5adccb15dd4bc3738d8bf786 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/Edge-Explorer
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0633fddecc8bb1fd5adccb15dd4bc3738d8bf786 -
Trigger Event:
push
-
Statement type:
File details
Details for the file universal_doc_parser-1.0.0-py3-none-any.whl.
File metadata
- Download URL: universal_doc_parser-1.0.0-py3-none-any.whl
- Upload date:
- Size: 54.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2fae424ee257ada373ccf5533260ed55583e190aeb7e957a1d0f1aaaab872e59
|
|
| MD5 |
7122d12c0aa3dd0bb57035aac76b1d5b
|
|
| BLAKE2b-256 |
5f14be7c1826a0fd9e8a07e4efd3d46e8565c282d65dcb842e7b411e7ccc02ec
|
Provenance
The following attestation bundles were made for universal_doc_parser-1.0.0-py3-none-any.whl:
Publisher:
release.yml on Edge-Explorer/Parse-Anything-
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
universal_doc_parser-1.0.0-py3-none-any.whl -
Subject digest:
2fae424ee257ada373ccf5533260ed55583e190aeb7e957a1d0f1aaaab872e59 - Sigstore transparency entry: 2758600571
- Sigstore integration time:
-
Permalink:
Edge-Explorer/Parse-Anything-@0633fddecc8bb1fd5adccb15dd4bc3738d8bf786 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/Edge-Explorer
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0633fddecc8bb1fd5adccb15dd4bc3738d8bf786 -
Trigger Event:
push
-
Statement type: