rasgapdf 0.2.2__tar.gz → 0.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,200 +1,243 @@
1
- Metadata-Version: 2.4
2
- Name: rasgapdf
3
- Version: 0.2.2
4
- Summary: Ultra-fast 2D spatial PDF parser powered by pure Rust — extract exact [x0, y0, x1, y1] bounding boxes, text blocks, tables, images & vector paths in milliseconds for RAG & LLMs
5
- Author: Messias Martins
6
- Project-URL: Homepage, https://martinsmessias.github.io/rasgapdf/
7
- Project-URL: Repository, https://github.com/MartinsMessias/rasgapdf
8
- Project-URL: Documentation, https://github.com/MartinsMessias/rasgapdf/blob/main/docs/SCHEMA.md
9
- Project-URL: Live Demo, https://huggingface.co/spaces/martinsmessias/rasgapdf
10
- Project-URL: Hugging Face, https://huggingface.co/martinsmessias/rasgapdf
11
- Project-URL: Bug Tracker, https://github.com/MartinsMessias/rasgapdf/issues
12
- Project-URL: LLM Context, https://martinsmessias.github.io/rasgapdf/llms.txt
13
- Keywords: pdf,pdf-parser,spatial-pdf,bounding-box,layout-analysis,table-extraction,pdf-to-json,rag,llm,document-parsing,document-ai,coordinates,rust,mupdf
14
- Classifier: Development Status :: 4 - Beta
15
- Classifier: Intended Audience :: Developers
16
- Classifier: Intended Audience :: Science/Research
17
- Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Rust
19
- Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
20
- Classifier: Operating System :: POSIX :: Linux
21
- Classifier: Operating System :: Microsoft :: Windows
22
- Classifier: Operating System :: MacOS
23
- Classifier: Topic :: Text Processing :: General
24
- Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
25
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
- Requires-Python: >=3.8
27
- Description-Content-Type: text/markdown
28
-
29
- # ⚡ RasgaPDF
30
-
31
- <div align="center">
32
-
33
- **The Blazing-Fast 2D Spatial PDF Parser for Python.**
34
- *Extract exact physical coordinates `[x0, y0, x1, y1]`, word spans, text blocks, and tabular structures at native hardware speeds.*
35
-
36
- [![PyPI version](https://img.shields.io/pypi/v/rasgapdf.svg?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/rasgapdf/)
37
- [![Python versions](https://img.shields.io/pypi/pyversions/rasgapdf.svg?logo=python&logoColor=white)](https://pypi.org/project/rasgapdf/)
38
- [![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
39
-
40
- </div>
41
-
42
- ---
43
-
44
- ## 🚀 Why RasgaPDF?
45
-
46
- Most Python PDF extraction libraries make fragile guesses: they flatten multi-column layouts into corrupted text streams, mangle tables, and strip away 2D positional geometry.
47
-
48
- **RasgaPDF does one thing with uncompromising precision:**
49
- It returns the **exact 2D physical spatial geometry** of the PDF directly to Python:
50
-
51
- - **Exact Bounding Boxes:** Every character, word span, line, block, and table has exact coordinates `[x0, y0, x1, y1]`.
52
- - **Zero Lossy Heuristics:** No broken markdown assumptions. Downstream LLMs, RAG pipelines, or vision-language models receive the true physical layout.
53
- - **Pure Native Speed:** Powered by a SIMD-parallelized Rust core. Extracts typical pages in **~3 to 8 ms**.
54
- - **Self-Contained Wheel:** Pre-compiled native binaries bundled directly in the wheel. Zero external runtime dependencies.
55
-
56
- ---
57
-
58
- ## ⚡ Quick Benchmarks (Python)
59
-
60
- Measured on Intel Core i7-1365U (Single-thread latency, 1-page complex PDF):
61
-
62
- | Library | Parse Time | Output Type | Spatial Accuracy |
63
- | :--- | :--- | :--- | :--- |
64
- | **⚡ RasgaPDF (`parse_raw`)** | **~7.7 ms** | **Flat Coordinates `[x0, y0, x1, y1]`** | **Exact Physical Canvas** |
65
- | **🚀 RasgaPDF (`parse_pdf`)** | **~8.5 ms** | **Hierarchical Blocks & Tables** | **Exact Physical Canvas** |
66
- | PyMuPDF (`fitz`) | ~28.0 ms | Text / Pixmaps | Bounding Boxes |
67
- | `pdfplumber` | ~410.0 ms | Python Dicts | High Overhead |
68
- | `pypdf` | ~95.0 ms | Plain String | No Geometry |
69
-
70
- ---
71
-
72
- ## 📦 Installation
73
-
74
- ```bash
75
- pip install --upgrade rasgapdf
76
- ```
77
-
78
- ---
79
-
80
- ## 💡 Usage
81
-
82
- RasgaPDF offers two distinct modes for Python engineers:
83
-
84
- ### ⚡ Mode 1: Raw Physical Coordinates (`parse_raw`)
85
- The fastest and most direct extraction possible. Returns a flat list of physical 2D coordinates for every text span on the page, with zero block/table overhead (~3-8 ms):
86
-
87
- ```python
88
- import rasgapdf
89
-
90
- # Parse raw physical coordinates
91
- doc = rasgapdf.parse_raw("document.pdf")
92
-
93
- print(f"Extracted {doc['total_spans']} spans in {doc['parse_time_ms']:.2f} ms")
94
-
95
- for span in doc["spans"]:
96
- print(
97
- f"[Page {span['page']}] "
98
- f"bbox=({span['x0']:.2f}, {span['y0']:.2f}, {span['x1']:.2f}, {span['y1']:.2f}) "
99
- f"font={span['font_name']} ({span['font_size']}pt) "
100
- f"text=\"{span['text']}\""
101
- )
102
- ```
103
-
104
- #### Output Structure:
105
- ```json
106
- {
107
- "file_name": "document.pdf",
108
- "total_pages": 1,
109
- "total_spans": 20,
110
- "parse_time_ms": 7.78,
111
- "spans": [
112
- {
113
- "page": 1,
114
- "x0": 50.0,
115
- "y0": 67.0,
116
- "x1": 244.0,
117
- "y1": 83.0,
118
- "font_size": 12.0,
119
- "font_name": "Helvetica",
120
- "text": "The Future of Artificial Intelligence"
121
- }
122
- ]
123
- }
124
- ```
125
-
126
- ---
127
-
128
- ### 🎯 Mode 2: Hierarchical Structured Document (`parse_pdf`)
129
- Parses the visual hierarchy: paragraphs (`text_blocks`), text lines (`lines`), spans, and auto-detects matrix tables via column alignment:
130
-
131
- ```python
132
- import rasgapdf
133
-
134
- doc = rasgapdf.parse_pdf("invoice.pdf", detect_tables=True)
135
-
136
- for page in doc["pages"]:
137
- print(f"--- Page {page['page_number']} ({page['width']}x{page['height']} pt) ---")
138
-
139
- # 1. Inspect Text Blocks
140
- for block in page["text_blocks"]:
141
- print(f"Block #{block['block_id']} at {block['bbox']}:")
142
- for line in block["lines"]:
143
- print(f" Line: {line['text']}")
144
-
145
- # 2. Inspect Detected Tables
146
- for table in page["tables"]:
147
- print(f"Table ({table['col_count']} cols x {table['row_count']} rows):")
148
- print("Headers:", table["headers"])
149
- for row in table["rows"]:
150
- print("Row:", row)
151
- ```
152
-
153
- ---
154
-
155
- ## ⚙️ Parameters for `parse_pdf`
156
-
157
- | Parameter | Type | Default | Description |
158
- | :--- | :--- | :--- | :--- |
159
- | `file_path` | `str` | *required* | Path to the PDF file on disk |
160
- | `detect_tables` | `bool` | `True` | Automatically detect and reconstruct tables |
161
- | `min_table_cols` | `int` | `3` | Minimum number of columns required to classify as a table |
162
- | `col_tolerance` | `float` | `16.0` | Horizontal alignment threshold in typographical points |
163
- | `row_tolerance` | `float` | `6.0` | Vertical line clustering threshold in points |
164
- | `extract_images` | `bool` | `False` | Fill `page["images"]` with embedded image metadata (dimensions, colour space, filter, SHA-256, placement `bbox`) |
165
- | `extract_drawings` | `bool` | `False` | Fill `page["drawings"]` with vector paths (`line`/`curve`/`rect`/`quad` items, colours, dash, opacity) |
166
- | `keep_background_fills` | `bool` | `False` | Keep fills that cover the whole page (backgrounds are dropped by default) |
167
-
168
- ---
169
-
170
- ### 🖼️ Embedded Images & Vector Graphics
171
-
172
- Opt-in extraction of the graphics layer. Pixels are never decoded — metadata stays in the JSON and the original encoded stream is written to disk as-is:
173
-
174
- ```python
175
- import rasgapdf
176
-
177
- doc = rasgapdf.parse_pdf("report.pdf", extract_images=True, extract_drawings=True)
178
-
179
- page = doc["pages"][0]
180
- for image in page["images"]:
181
- print(image["name"], image["pixel_width"], "x", image["pixel_height"],
182
- image["filter"], image["bbox"])
183
-
184
- for drawing in page["drawings"]:
185
- print(drawing["drawing_id"], drawing["drawing_type"], drawing["stroke_color"])
186
-
187
- # Writes report JPEGs (e.g. page_001_img_001_xref7.jpg) plus manifest.json
188
- manifest = rasgapdf.extract_images("report.pdf", "./out")
189
- print(manifest["written"], "files written")
190
- ```
191
-
192
- ---
193
-
194
- ## 📄 License
195
-
196
- GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). Copyright (c) 2026 Messias Martins.
197
-
198
- RasgaPDF embeds and links against [MuPDF](https://mupdf.com/) (Artifex Software),
199
- which is distributed under the AGPL-3.0. That is why this project is licensed
200
- under the same terms.
1
+ Metadata-Version: 2.4
2
+ Name: rasgapdf
3
+ Version: 0.2.4
4
+ Summary: Ultra-fast 2D spatial PDF parser powered by pure Rust — extract exact [x0, y0, x1, y1] bounding boxes, text blocks, tables, images & vector paths in milliseconds for RAG & LLMs
5
+ Author: Messias Martins
6
+ Project-URL: Homepage, https://martinsmessias.github.io/rasgapdf/
7
+ Project-URL: Repository, https://github.com/MartinsMessias/rasgapdf
8
+ Project-URL: Documentation, https://github.com/MartinsMessias/rasgapdf/blob/main/docs/SCHEMA.md
9
+ Project-URL: Live Demo, https://huggingface.co/spaces/martinsmessias/rasgapdf
10
+ Project-URL: Hugging Face, https://huggingface.co/martinsmessias/rasgapdf
11
+ Project-URL: Bug Tracker, https://github.com/MartinsMessias/rasgapdf/issues
12
+ Project-URL: LLM Context, https://martinsmessias.github.io/rasgapdf/llms.txt
13
+ Keywords: pdf,pdf-parser,spatial-pdf,bounding-box,layout-analysis,table-extraction,pdf-to-json,rag,llm,document-parsing,document-ai,coordinates,rust,mupdf
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Rust
19
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Operating System :: Microsoft :: Windows
22
+ Classifier: Operating System :: MacOS
23
+ Classifier: Topic :: Text Processing :: General
24
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
25
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/markdown
28
+
29
+ # ⚡ RasgaPDF
30
+
31
+ <div align="center">
32
+
33
+ **The Blazing-Fast 2D Spatial PDF Parser for Python.**
34
+ *Extract exact physical coordinates `[x0, y0, x1, y1]`, word spans, text blocks, and tabular structures at native hardware speeds.*
35
+
36
+ [![PyPI version](https://img.shields.io/pypi/v/rasgapdf.svg?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/rasgapdf/)
37
+ [![Python versions](https://img.shields.io/pypi/pyversions/rasgapdf.svg?logo=python&logoColor=white)](https://pypi.org/project/rasgapdf/)
38
+ [![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
39
+
40
+ </div>
41
+
42
+ ---
43
+
44
+ ## 🚀 Why RasgaPDF?
45
+
46
+ Most Python PDF extraction libraries make fragile guesses: they flatten multi-column layouts into corrupted text streams, mangle tables, and strip away 2D positional geometry.
47
+
48
+ **RasgaPDF does one thing with uncompromising precision:**
49
+ It returns the **exact 2D physical spatial geometry** of the PDF directly to Python:
50
+
51
+ - **Exact Bounding Boxes:** Every character, word span, line, block, and table has exact coordinates `[x0, y0, x1, y1]`.
52
+ - **Zero Lossy Heuristics:** No broken markdown assumptions. Downstream LLMs, RAG pipelines, or vision-language models receive the true physical layout.
53
+ - **Pure Native Speed:** Powered by a SIMD-parallelized Rust core. Extracts typical pages in **~3 to 8 ms**.
54
+ - **Self-Contained Wheel:** Pre-compiled native binaries bundled directly in the wheel. Zero external runtime dependencies.
55
+
56
+ ---
57
+
58
+ ## ⚡ Quick Benchmarks (Python)
59
+
60
+ Measured on Intel Core i7-1365U (Single-thread latency, 1-page complex PDF):
61
+
62
+ | Library | Parse Time | Output Type | Spatial Accuracy |
63
+ | :--- | :--- | :--- | :--- |
64
+ | **⚡ RasgaPDF (`parse_raw`)** | **~7.7 ms** | **Flat Coordinates `[x0, y0, x1, y1]`** | **Exact Physical Canvas** |
65
+ | **🚀 RasgaPDF (`parse_pdf`)** | **~8.5 ms** | **Hierarchical Blocks & Tables** | **Exact Physical Canvas** |
66
+ | PyMuPDF (`fitz`) | ~28.0 ms | Text / Pixmaps | Bounding Boxes |
67
+ | `pdfplumber` | ~410.0 ms | Python Dicts | High Overhead |
68
+ | `pypdf` | ~95.0 ms | Plain String | No Geometry |
69
+
70
+ ---
71
+
72
+ ## 📦 Installation
73
+
74
+ ```bash
75
+ pip install --upgrade rasgapdf
76
+ ```
77
+
78
+ ---
79
+
80
+ ## 💡 Usage
81
+
82
+ RasgaPDF offers two distinct modes for Python engineers:
83
+
84
+ ### ⚡ Mode 1: Raw Physical Coordinates (`parse_raw`)
85
+ The fastest and most direct extraction possible. Returns a flat list of physical 2D coordinates for every text span on the page, with zero block/table overhead (~3-8 ms):
86
+
87
+ ```python
88
+ import rasgapdf
89
+
90
+ # Parse raw physical coordinates
91
+ doc = rasgapdf.parse_raw("document.pdf")
92
+
93
+ print(f"Extracted {doc['total_spans']} spans in {doc['parse_time_ms']:.2f} ms")
94
+
95
+ for span in doc["spans"]:
96
+ print(
97
+ f"[Page {span['page']}] "
98
+ f"bbox=({span['x0']:.2f}, {span['y0']:.2f}, {span['x1']:.2f}, {span['y1']:.2f}) "
99
+ f"font={span['font_name']} ({span['font_size']}pt) "
100
+ f"text=\"{span['text']}\""
101
+ )
102
+ ```
103
+
104
+ #### Output Structure:
105
+ ```json
106
+ {
107
+ "file_name": "document.pdf",
108
+ "total_pages": 1,
109
+ "total_spans": 20,
110
+ "parse_time_ms": 7.78,
111
+ "spans": [
112
+ {
113
+ "page": 1,
114
+ "x0": 50.0,
115
+ "y0": 67.0,
116
+ "x1": 244.0,
117
+ "y1": 83.0,
118
+ "font_size": 12.0,
119
+ "font_name": "Helvetica",
120
+ "text": "The Future of Artificial Intelligence"
121
+ }
122
+ ]
123
+ }
124
+ ```
125
+
126
+ ---
127
+
128
+ ### 🎯 Mode 2: Hierarchical Structured Document (`parse_pdf`)
129
+ Parses the visual hierarchy: paragraphs (`text_blocks`), text lines (`lines`), spans, and auto-detects matrix tables via column alignment:
130
+
131
+ ```python
132
+ import rasgapdf
133
+
134
+ doc = rasgapdf.parse_pdf("invoice.pdf", detect_tables=True)
135
+
136
+ for page in doc["pages"]:
137
+ print(f"--- Page {page['page_number']} ({page['width']}x{page['height']} pt) ---")
138
+
139
+ # 1. Inspect Text Blocks
140
+ for block in page["text_blocks"]:
141
+ print(f"Block #{block['block_id']} at {block['bbox']}:")
142
+ for line in block["lines"]:
143
+ print(f" Line: {line['text']}")
144
+
145
+ # 2. Inspect Detected Tables
146
+ for table in page["tables"]:
147
+ print(f"Table ({table['col_count']} cols x {table['row_count']} rows):")
148
+ print("Headers:", table["headers"])
149
+ for row in table["rows"]:
150
+ print("Row:", row)
151
+ ```
152
+
153
+ ---
154
+
155
+ ## ⚙️ Parameters for `parse_pdf`
156
+
157
+ | Parameter | Type | Default | Description |
158
+ | :--- | :--- | :--- | :--- |
159
+ | `file_path` | `str` | *required* | Path to the PDF file on disk |
160
+ | `detect_tables` | `bool` | `True` | Automatically detect and reconstruct tables |
161
+ | `min_table_cols` | `int` | `3` | Minimum number of columns required to classify as a table |
162
+ | `col_tolerance` | `float` | `16.0` | Horizontal alignment threshold in typographical points |
163
+ | `row_tolerance` | `float` | `6.0` | Vertical line clustering threshold in points |
164
+ | `extract_images` | `bool` | `False` | Fill `page["images"]` with embedded image metadata (dimensions, colour space, filter, SHA-256, placement `bbox`) |
165
+ | `extract_drawings` | `bool` | `False` | Fill `page["drawings"]` with vector paths (`line`/`curve`/`rect`/`quad` items, colours, dash, opacity) |
166
+ | `keep_background_fills` | `bool` | `False` | Keep fills that cover the whole page (backgrounds are dropped by default) |
167
+
168
+ ---
169
+
170
+ ### 🖼️ Embedded Images & Vector Graphics
171
+
172
+ Opt-in extraction of the graphics layer. Pixels are never decoded — metadata stays in the JSON and the original encoded stream is written to disk as-is:
173
+
174
+ ```python
175
+ import rasgapdf
176
+
177
+ doc = rasgapdf.parse_pdf("report.pdf", extract_images=True, extract_drawings=True)
178
+
179
+ page = doc["pages"][0]
180
+ for image in page["images"]:
181
+ print(image["name"], image["pixel_width"], "x", image["pixel_height"],
182
+ image["filter"], image["bbox"])
183
+
184
+ for drawing in page["drawings"]:
185
+ print(drawing["drawing_id"], drawing["drawing_type"], drawing["stroke_color"])
186
+
187
+ # Writes report JPEGs (e.g. page_001_img_001_xref7.jpg) plus manifest.json
188
+ manifest = rasgapdf.extract_images("report.pdf", "./out")
189
+ print(manifest["written"], "files written")
190
+ ```
191
+
192
+ ---
193
+
194
+ ---
195
+
196
+ ## 🦜️🔗 AI Framework Integrations (LangChain & LlamaIndex)
197
+
198
+ ### 🦜️ LangChain Document Loader
199
+ `python
200
+ from rasgapdf import RasgaPDFLoader
201
+
202
+ # 1 Document per page with markdown tables:
203
+ loader = RasgaPDFLoader('document.pdf', mode='pages')
204
+ docs = loader.load()
205
+
206
+ # Spatial RAG: 1 Document per block/table with exact [x0, y0, x1, y1] coordinates:
207
+ spatial_loader = RasgaPDFLoader('document.pdf', mode='elements')
208
+ chunks = spatial_loader.load()
209
+ for chunk in chunks:
210
+ print(chunk.metadata['bbox'], chunk.page_content[:40])
211
+ `
212
+
213
+ ### 🦙 LlamaIndex Reader
214
+ `python
215
+ from rasgapdf import RasgaPDFReader
216
+
217
+ reader = RasgaPDFReader(mode='pages')
218
+ documents = reader.load_data('financial_report.pdf')
219
+ `
220
+
221
+ ## 📄 License
222
+
223
+ GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). Copyright (c) 2026 Messias Martins.
224
+
225
+ RasgaPDF embeds and links against [MuPDF](https://mupdf.com/) (Artifex Software),
226
+ which is distributed under the AGPL-3.0. That is why this project is licensed
227
+ under the same terms.
228
+
229
+ ---
230
+
231
+ ## 💼 Commercial & Enterprise Licensing (AGPL-3.0 Waiver)
232
+
233
+ Need to use **RasgaPDF** in closed-source commercial software, proprietary SaaS platforms, private cloud environments, or corporate applications without releasing your source code under the AGPL-3.0?
234
+
235
+ A **Commercial / Enterprise License** is available directly from the author:
236
+
237
+ - **Complete AGPL-3.0 Exemption:** Keep your intellectual property, backend code, and SaaS infrastructure 100% closed-source and proprietary.
238
+ - **Enterprise SLA & Support:** Direct architecture advisory, guaranteed response times, and priority bug resolution.
239
+ - **On-Premise & Air-Gapped Appliances:** Ready-to-deploy private Docker containers for confidential banking, healthcare, and legal compliance (LGPD / GDPR).
240
+ - **Custom Spatial Features:** Tailored table extractors for bank statements, invoices, and court proceedings.
241
+
242
+ 📬 **Inquiries & Licensing:**
243
+ [👉 **Click here to Request a Commercial License & Pricing**](mailto:messiasads2017@gmail.com?subject=RasgaPDF%20Commercial%20License%20Inquiry) with details about your organization, use case, and estimated volume.