pdfdancer-client-python 0.2.5__py3-none-any.whl → 0.2.6__py3-none-any.whl
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.
Potentially problematic release.
This version of pdfdancer-client-python might be problematic. Click here for more details.
- pdfdancer_client_python-0.2.6.dist-info/METADATA +189 -0
- {pdfdancer_client_python-0.2.5.dist-info → pdfdancer_client_python-0.2.6.dist-info}/RECORD +4 -4
- pdfdancer_client_python-0.2.5.dist-info/METADATA +0 -305
- {pdfdancer_client_python-0.2.5.dist-info → pdfdancer_client_python-0.2.6.dist-info}/WHEEL +0 -0
- {pdfdancer_client_python-0.2.5.dist-info → pdfdancer_client_python-0.2.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pdfdancer-client-python
|
|
3
|
+
Version: 0.2.6
|
|
4
|
+
Summary: Python client for PDFDancer API
|
|
5
|
+
Author-email: "The Famous Cat Ltd." <hi@thefamouscat.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://www.pdfdancer.com/
|
|
8
|
+
Project-URL: Repository, https://github.com/MenschMachine/pdfdancer-client-python
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: requests>=2.25.0
|
|
18
|
+
Requires-Dist: pydantic>=1.8.0
|
|
19
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
22
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
23
|
+
Requires-Dist: black>=22.0; extra == "dev"
|
|
24
|
+
Requires-Dist: flake8>=5.0; extra == "dev"
|
|
25
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
26
|
+
|
|
27
|
+
# PDFDancer Python Client
|
|
28
|
+
|
|
29
|
+
Automate PDF clean-up, redaction, form filling, and content injection against the PDFDancer API from Python. The client gives you page-scoped selectors, fluent editors, and builders so you can read, modify, and export PDFs programmatically in just a few lines.
|
|
30
|
+
|
|
31
|
+
## Highlights
|
|
32
|
+
|
|
33
|
+
- Locate anything inside a PDF—paragraphs, text lines, images, vector paths, pages, AcroForm fields—by page, coordinates, or text prefixes
|
|
34
|
+
- Edit or delete existing content with fluent paragraph/text editors and safe apply-on-exit context managers
|
|
35
|
+
- Fill or update form fields and propagate the changes back to the document instantly
|
|
36
|
+
- Add brand-new content with paragraph/image builders, custom fonts, and precise page positioning
|
|
37
|
+
- Download results as bytes for downstream processing or save directly to disk with one method call
|
|
38
|
+
|
|
39
|
+
## Core Capabilities
|
|
40
|
+
|
|
41
|
+
- Clean up layout by moving or deleting paragraphs, text lines, or shapes on specific pages
|
|
42
|
+
- Search and filter content (e.g., paragraphs starting with "Invoice") to drive custom workflows
|
|
43
|
+
- Redact or replace text in bulk with chained editor operations
|
|
44
|
+
- Populate AcroForms for contract generation or onboarding flows
|
|
45
|
+
- Insert logos, signatures, and generated paragraphs at deterministic coordinates
|
|
46
|
+
- Export modified PDFs as bytes for APIs, S3 uploads, or direct file saves
|
|
47
|
+
|
|
48
|
+
## Requirements
|
|
49
|
+
|
|
50
|
+
- Python 3.9 or newer
|
|
51
|
+
- A PDFDancer API token (set `PDFDANCER_TOKEN` or pass `token=...`)
|
|
52
|
+
- Network access to a PDFDancer service (defaults to `https://api.pdfdancer.com`; override with `PDFDANCER_BASE_URL`)
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install pdfdancer-client-python
|
|
58
|
+
|
|
59
|
+
# Editable install for local development
|
|
60
|
+
pip install -e .
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Getting Started
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from pathlib import Path
|
|
67
|
+
from pdfdancer import Color, PDFDancer
|
|
68
|
+
|
|
69
|
+
with PDFDancer.open(
|
|
70
|
+
pdf_data=Path("input.pdf"),
|
|
71
|
+
token="your-api-token", # optional when PDFDANCER_TOKEN is set
|
|
72
|
+
base_url="https://api.pdfdancer.com",
|
|
73
|
+
) as pdf:
|
|
74
|
+
# Locate existing content
|
|
75
|
+
heading = pdf.page(0).select_paragraphs_starting_with("Executive Summary")[0]
|
|
76
|
+
heading.edit().replace("Overview").apply()
|
|
77
|
+
|
|
78
|
+
# Add a new paragraph using the fluent builder
|
|
79
|
+
pdf.new_paragraph() \
|
|
80
|
+
.text("Generated with PDFDancer") \
|
|
81
|
+
.font("Helvetica", 12) \
|
|
82
|
+
.color(Color(70, 70, 70)) \
|
|
83
|
+
.line_spacing(1.4) \
|
|
84
|
+
.at(page_index=0, x=72, y=520) \
|
|
85
|
+
.add()
|
|
86
|
+
|
|
87
|
+
# Persist the modified document
|
|
88
|
+
pdf.save("output.pdf")
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Authentication Tips
|
|
92
|
+
|
|
93
|
+
- Prefer setting `PDFDANCER_TOKEN` in your environment for local development.
|
|
94
|
+
- Override the API host by setting `PDFDANCER_BASE_URL` or passing `base_url="https://sandbox.pdfdancer.com"`.
|
|
95
|
+
- Use the `timeout` parameter on `PDFDancer.open()` to adjust HTTP read timeouts.
|
|
96
|
+
|
|
97
|
+
## Selecting PDF Content
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
with PDFDancer.open("report.pdf") as pdf: # environment variables provide token/URL
|
|
101
|
+
all_paragraphs = pdf.select_paragraphs()
|
|
102
|
+
page_zero_images = pdf.page(0).select_images()
|
|
103
|
+
form_fields = pdf.page(2).select_form_fields()
|
|
104
|
+
paths_at_cursor = pdf.page(3).select_paths_at(x=150, y=320)
|
|
105
|
+
|
|
106
|
+
page = pdf.page(0).get()
|
|
107
|
+
print(page.internal_id, page.position.bounding_rect)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Selectors return rich objects (`ParagraphObject`, `TextLineObject`, `ImageObject`, `FormFieldObject`, etc.) with helpers such as `delete()`, `move_to(x, y)`, or `edit()` depending on the object type.
|
|
111
|
+
|
|
112
|
+
## Editing Text and Forms
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
with PDFDancer.open("report.pdf") as pdf:
|
|
116
|
+
paragraph = pdf.page(0).select_paragraphs_starting_with("Disclaimer")[0]
|
|
117
|
+
|
|
118
|
+
# Chain updates explicitly…
|
|
119
|
+
paragraph.edit() \
|
|
120
|
+
.replace("Updated disclaimer text") \
|
|
121
|
+
.font("Roboto-Regular", 11) \
|
|
122
|
+
.line_spacing(1.1) \
|
|
123
|
+
.move_to(72, 140) \
|
|
124
|
+
.apply()
|
|
125
|
+
|
|
126
|
+
# …or use the context manager to auto-apply on success
|
|
127
|
+
with paragraph.edit() as edit:
|
|
128
|
+
edit.replace("Context-managed update").color(Color(120, 0, 0))
|
|
129
|
+
|
|
130
|
+
# Update an AcroForm field
|
|
131
|
+
field = pdf.page(1).select_form_fields_by_name("signature")[0]
|
|
132
|
+
field.edit().value("Signed by Jane Doe").apply()
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Adding New Content
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
with PDFDancer.open("report.pdf") as pdf:
|
|
139
|
+
# Register fonts from the service
|
|
140
|
+
fonts = pdf.find_fonts("Roboto", 12)
|
|
141
|
+
pdf.register_font("/path/to/custom.ttf")
|
|
142
|
+
|
|
143
|
+
# Paragraphs
|
|
144
|
+
pdf.new_paragraph() \
|
|
145
|
+
.text("Greetings from PDFDancer!") \
|
|
146
|
+
.font(fonts[0].name, fonts[0].size) \
|
|
147
|
+
.at(page_index=0, x=220, y=480) \
|
|
148
|
+
.add()
|
|
149
|
+
|
|
150
|
+
# Raster images
|
|
151
|
+
pdf.new_image() \
|
|
152
|
+
.from_file(Path("logo.png")) \
|
|
153
|
+
.at(page=0, x=48, y=700) \
|
|
154
|
+
.add()
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Downloading Results
|
|
158
|
+
|
|
159
|
+
- `pdf.get_pdf_file()` returns the modified PDF as `bytes` (ideal for storage services or HTTP responses).
|
|
160
|
+
- `pdf.save("output.pdf")` writes directly to disk, creating directories when needed.
|
|
161
|
+
|
|
162
|
+
## Error Handling
|
|
163
|
+
|
|
164
|
+
Most operations raise subclasses of `PdfDancerException`:
|
|
165
|
+
|
|
166
|
+
- `ValidationException` for client-side validation issues (missing token, invalid coordinates, etc.).
|
|
167
|
+
- `FontNotFoundException` when the service cannot locate a requested font.
|
|
168
|
+
- `HttpClientException` for transport or server errors with detailed messages.
|
|
169
|
+
- `SessionException` when session creation fails.
|
|
170
|
+
|
|
171
|
+
Wrap complex workflows in `try/except` blocks to surface actionable errors to your users.
|
|
172
|
+
|
|
173
|
+
## Local Development
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
python -m venv venv
|
|
177
|
+
source venv/bin/activate # Windows: venv\Scripts\activate
|
|
178
|
+
pip install -e .
|
|
179
|
+
pip install -r requirements-dev.txt
|
|
180
|
+
|
|
181
|
+
pytest -q # run the fast unit suite
|
|
182
|
+
pytest tests/e2e # integration tests (requires live API + fixtures)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Package builds are handled by `python -m build`, and release artifacts are published via `python release.py`.
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
MIT © The Famous Cat Ltd.
|
|
@@ -5,7 +5,7 @@ pdfdancer/models.py,sha256=SmkKScr47uVs6FCWUAVIg6rucYrYHvbIxZngyA50XyI,15498
|
|
|
5
5
|
pdfdancer/paragraph_builder.py,sha256=bAfwX9U2YT1UGX9EKkPnGYvGK3SQP3X1ocxlgyLE_rU,8872
|
|
6
6
|
pdfdancer/pdfdancer_v1.py,sha256=Pgv-2L0pYQdOUVK2nUntrGB6hCDKUOMWHYuN8loBM3Q,35540
|
|
7
7
|
pdfdancer/types.py,sha256=05zvjA6MEQomNucUUKf5Z33dA7NVFCRu_6LR3Yom1yo,7633
|
|
8
|
-
pdfdancer_client_python-0.2.
|
|
9
|
-
pdfdancer_client_python-0.2.
|
|
10
|
-
pdfdancer_client_python-0.2.
|
|
11
|
-
pdfdancer_client_python-0.2.
|
|
8
|
+
pdfdancer_client_python-0.2.6.dist-info/METADATA,sha256=mQUfTZ7xhjoCWdo6g_5sAerVGtq-tBdaV93Nesj5CcI,6769
|
|
9
|
+
pdfdancer_client_python-0.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
+
pdfdancer_client_python-0.2.6.dist-info/top_level.txt,sha256=ICwSVRpcCKrdBF9QlaX9Y0e_N3Nk1p7QVxadGOnbxeY,10
|
|
11
|
+
pdfdancer_client_python-0.2.6.dist-info/RECORD,,
|
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pdfdancer-client-python
|
|
3
|
-
Version: 0.2.5
|
|
4
|
-
Summary: Python client for PDFDancer API
|
|
5
|
-
Author-email: "The Famous Cat Ltd." <hi@thefamouscat.com>
|
|
6
|
-
License: MIT
|
|
7
|
-
Project-URL: Homepage, https://www.pdfdancer.com/
|
|
8
|
-
Project-URL: Repository, https://github.com/MenschMachine/pdfdancer-client-python
|
|
9
|
-
Classifier: Development Status :: 4 - Beta
|
|
10
|
-
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
-
Description-Content-Type: text/markdown
|
|
17
|
-
Requires-Dist: requests>=2.25.0
|
|
18
|
-
Requires-Dist: pydantic>=1.8.0
|
|
19
|
-
Requires-Dist: typing-extensions>=4.0.0
|
|
20
|
-
Provides-Extra: dev
|
|
21
|
-
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
22
|
-
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
23
|
-
Requires-Dist: black>=22.0; extra == "dev"
|
|
24
|
-
Requires-Dist: flake8>=5.0; extra == "dev"
|
|
25
|
-
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
26
|
-
|
|
27
|
-
# PDFDancer Python Client
|
|
28
|
-
|
|
29
|
-
A Python client library for the PDFDancer PDF manipulation API that closely mirrors the Java client structure and functionality.
|
|
30
|
-
|
|
31
|
-
## Features
|
|
32
|
-
|
|
33
|
-
- **100% Manual Implementation** - Pure Python, no code generation
|
|
34
|
-
- **Java Client Compatibility** - Same methods, validation, and patterns
|
|
35
|
-
- **Session-based Operations** - Automatic session management
|
|
36
|
-
- **Builder Pattern** - Fluent ParagraphBuilder interface
|
|
37
|
-
- **Strict Validation** - Matches Java client validation exactly
|
|
38
|
-
- **Python Enhancements** - Type hints, context managers, Pathlib support
|
|
39
|
-
- **Comprehensive Testing** - 77 tests covering all functionality
|
|
40
|
-
|
|
41
|
-
## Installation
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
pip install pdfdancer-client-python
|
|
45
|
-
# Or for development:
|
|
46
|
-
pip install -e .
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Quick Start
|
|
50
|
-
|
|
51
|
-
```python
|
|
52
|
-
from pdfdancer import ClientV1, Position, Font, Color
|
|
53
|
-
|
|
54
|
-
# Create client (mirrors Java: new Client(token, pdfFile))
|
|
55
|
-
client = ClientV1(token="your-jwt-token", pdf_data="document.pdf")
|
|
56
|
-
|
|
57
|
-
# Find operations (mirrors Java client methods)
|
|
58
|
-
paragraphs = client.find_paragraphs(None)
|
|
59
|
-
images = client.find_images(Position.at_page(0))
|
|
60
|
-
|
|
61
|
-
# Manipulation operations (mirrors Java client methods)
|
|
62
|
-
client._delete(paragraphs[0])
|
|
63
|
-
client._move(images[0], Position.at_page_coordinates(0, 100, 200))
|
|
64
|
-
|
|
65
|
-
# Builder pattern (mirrors Java ParagraphBuilder)
|
|
66
|
-
paragraph = (client._paragraph_builder()
|
|
67
|
-
.from_string("Hello World")
|
|
68
|
-
.with_font(Font("Arial", 12))
|
|
69
|
-
.with_color(Color(255, 0, 0))
|
|
70
|
-
.with_position(Position.at_page(0))
|
|
71
|
-
.build())
|
|
72
|
-
|
|
73
|
-
client._add_paragraph(paragraph)
|
|
74
|
-
|
|
75
|
-
# Save result (mirrors Java savePDF)
|
|
76
|
-
client.save_pdf("output.pdf")
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Context Manager (Python Enhancement)
|
|
80
|
-
|
|
81
|
-
```python
|
|
82
|
-
from pdfdancer import ClientV1
|
|
83
|
-
|
|
84
|
-
# Automatic resource management
|
|
85
|
-
with ClientV1(token="jwt-token", pdf_data="input.pdf") as client:
|
|
86
|
-
paragraphs = client.find_paragraphs(None)
|
|
87
|
-
client._delete(paragraphs[0])
|
|
88
|
-
client.save_pdf("output.pdf")
|
|
89
|
-
# Session automatically cleaned up
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## API Methods
|
|
93
|
-
|
|
94
|
-
### Constructor Patterns
|
|
95
|
-
```python
|
|
96
|
-
# File path (Java: new Client(token, new File("pdf")))
|
|
97
|
-
client = ClientV1(token="jwt-token", pdf_data="document.pdf")
|
|
98
|
-
|
|
99
|
-
# Bytes (Java: new Client(token, pdfBytes, httpClient))
|
|
100
|
-
client = ClientV1(token="jwt-token", pdf_data=pdf_bytes)
|
|
101
|
-
|
|
102
|
-
# Custom server
|
|
103
|
-
client = ClientV1(token="jwt-token", pdf_data=pdf_file, base_url="https://api.server")
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Find Operations
|
|
107
|
-
|
|
108
|
-
```python
|
|
109
|
-
# Generic find (Java: client.find())
|
|
110
|
-
objects = client._find(ObjectType.PARAGRAPH, position)
|
|
111
|
-
|
|
112
|
-
# Specific finders (Java: client.findParagraphs(), etc.)
|
|
113
|
-
paragraphs = client._find_paragraphs(position)
|
|
114
|
-
images = client._find_images(position)
|
|
115
|
-
forms = client._find_form_x_objects(position)
|
|
116
|
-
paths = client._find_paths(position)
|
|
117
|
-
text_lines = client._find_text_lines(position)
|
|
118
|
-
|
|
119
|
-
# Page operations (Java: client.getPages(), client.getPage())
|
|
120
|
-
pages = client.get_pages()
|
|
121
|
-
page = client._get_page(1) # 1-based indexing
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Manipulation Operations
|
|
125
|
-
|
|
126
|
-
```python
|
|
127
|
-
# Delete (Java: client.delete(), client.deletePage())
|
|
128
|
-
result = client._delete(object_ref)
|
|
129
|
-
result = client._delete_page(page_ref)
|
|
130
|
-
|
|
131
|
-
# Move (Java: client.move())
|
|
132
|
-
result = client._move(object_ref, new_position)
|
|
133
|
-
|
|
134
|
-
# Add (Java: client.addImage(), client.addParagraph())
|
|
135
|
-
result = client._add_image(image, position)
|
|
136
|
-
result = client._add_paragraph(paragraph)
|
|
137
|
-
|
|
138
|
-
# Modify (Java: client.modifyParagraph(), client.modifyTextLine())
|
|
139
|
-
result = client._modify_paragraph(ref, new_paragraph)
|
|
140
|
-
result = client.modify_text_line(ref, "new text")
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Builder Pattern
|
|
144
|
-
|
|
145
|
-
```python
|
|
146
|
-
# Java: client.paragraphBuilder()
|
|
147
|
-
builder = client._paragraph_builder()
|
|
148
|
-
|
|
149
|
-
# Fluent interface (mirrors Java ParagraphBuilder)
|
|
150
|
-
paragraph = (builder
|
|
151
|
-
.from_string("Text content") # Java: fromString()
|
|
152
|
-
.with_font(Font("Arial", 12)) # Java: withFont()
|
|
153
|
-
.with_color(Color(255, 0, 0)) # Java: withColor()
|
|
154
|
-
.with_line_spacing(1.5) # Java: withLineSpacing()
|
|
155
|
-
.with_position(position) # Java: withPosition()
|
|
156
|
-
.build()) # Java: build()
|
|
157
|
-
|
|
158
|
-
# Font file registration (Java: withFont(File, double))
|
|
159
|
-
paragraph = (builder
|
|
160
|
-
.with_font_file("custom.ttf", 14.0) # Java: withFont(File, double)
|
|
161
|
-
.from_string("Custom font text")
|
|
162
|
-
.with_position(position)
|
|
163
|
-
.build())
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Position API
|
|
167
|
-
|
|
168
|
-
```python
|
|
169
|
-
from pdfdancer import Position
|
|
170
|
-
|
|
171
|
-
# Factory methods (Java: Position.fromPageNumber(), Position.onPageCoordinates())
|
|
172
|
-
position = Position.at_page(0)
|
|
173
|
-
position = Position.at_page_coordinates(0, 100, 200)
|
|
174
|
-
|
|
175
|
-
# Coordinate access (Java: position.getX(), position.getY())
|
|
176
|
-
x = position.x()
|
|
177
|
-
y = position.y()
|
|
178
|
-
|
|
179
|
-
# Movement (Java: position.moveX(), position.moveY())
|
|
180
|
-
position.move_x(50.0)
|
|
181
|
-
position.move_y(-25.0)
|
|
182
|
-
|
|
183
|
-
# Copy (Java: position.copy())
|
|
184
|
-
position_copy = position.copy()
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### Font Operations
|
|
188
|
-
```python
|
|
189
|
-
# Find fonts (Java: client.findFonts())
|
|
190
|
-
fonts = client.find_fonts("Arial", 12)
|
|
191
|
-
|
|
192
|
-
# Register custom font (Java: client.registerFont())
|
|
193
|
-
font_name = client.register_font("custom.ttf")
|
|
194
|
-
font_name = client.register_font(Path("font.ttf"))
|
|
195
|
-
font_name = client.register_font(font_bytes)
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Document Operations
|
|
199
|
-
```python
|
|
200
|
-
# Get PDF content (Java: client.getPDFFile())
|
|
201
|
-
pdf_bytes = client.get_pdf_file()
|
|
202
|
-
|
|
203
|
-
# Save PDF (Java: client.savePDF())
|
|
204
|
-
client.save_pdf("output.pdf")
|
|
205
|
-
client.save_pdf(Path("output.pdf"))
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## Exception Handling
|
|
209
|
-
|
|
210
|
-
```python
|
|
211
|
-
from pdfdancer import (
|
|
212
|
-
PdfDancerException, ValidationException,
|
|
213
|
-
FontNotFoundException, HttpClientException
|
|
214
|
-
)
|
|
215
|
-
|
|
216
|
-
try:
|
|
217
|
-
client = ClientV1(token="", pdf_data=b"pdf")
|
|
218
|
-
except ValidationException as e: # Java: IllegalArgumentException
|
|
219
|
-
print(f"Validation error: {e}")
|
|
220
|
-
|
|
221
|
-
try:
|
|
222
|
-
fonts = client.find_fonts("NonExistentFont", 12)
|
|
223
|
-
except FontNotFoundException as e: # Java: FontNotFoundException
|
|
224
|
-
print(f"Font not found: {e}")
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
## Data Models
|
|
228
|
-
|
|
229
|
-
```python
|
|
230
|
-
from pdfdancer import ObjectRef, Position, Font, Color, ObjectType
|
|
231
|
-
|
|
232
|
-
# Object reference (Java: ObjectRef)
|
|
233
|
-
obj_ref = ObjectRef(internal_id="obj-123", position=position, type=ObjectType.PARAGRAPH)
|
|
234
|
-
|
|
235
|
-
# Font (Java: Font)
|
|
236
|
-
font = Font(name="Arial", size=12.0)
|
|
237
|
-
|
|
238
|
-
# Color (Java: Color) - RGB values 0-255
|
|
239
|
-
color = Color(r=255, g=128, b=0)
|
|
240
|
-
|
|
241
|
-
# Position with bounding rectangle (Java: Position, BoundingRect)
|
|
242
|
-
position = Position.at_page_coordinates(page=0, x=100.0, y=200.0)
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
## Development
|
|
246
|
-
|
|
247
|
-
### Setup
|
|
248
|
-
```bash
|
|
249
|
-
python -m venv venv
|
|
250
|
-
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
251
|
-
pip install -e .
|
|
252
|
-
pip install -r requirements-dev.txt
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Testing
|
|
256
|
-
```bash
|
|
257
|
-
# Run all tests (77 tests)
|
|
258
|
-
python -m pytest tests/ -v
|
|
259
|
-
|
|
260
|
-
# Run specific test files
|
|
261
|
-
python -m pytest tests/test_client_v1.py -v
|
|
262
|
-
python -m pytest tests/test_paragraph_builder.py -v
|
|
263
|
-
python -m pytest tests/test_models.py -v
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### Build Package
|
|
267
|
-
```bash
|
|
268
|
-
python -m build
|
|
269
|
-
python -m twine check dist/*
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
## Java Client Mapping
|
|
273
|
-
|
|
274
|
-
| Java Method | Python Method | Description |
|
|
275
|
-
|-------------|---------------|-------------|
|
|
276
|
-
| `new Client(token, file)` | `ClientV1(token="", pdf_data="")` | Constructor |
|
|
277
|
-
| `findParagraphs(position)` | `find_paragraphs(position)` | Find paragraphs |
|
|
278
|
-
| `findImages(position)` | `find_images(position)` | Find images |
|
|
279
|
-
| `delete(objectRef)` | `delete(object_ref)` | Delete object |
|
|
280
|
-
| `move(objectRef, position)` | `move(object_ref, position)` | Move object |
|
|
281
|
-
| `addParagraph(paragraph)` | `add_paragraph(paragraph)` | Add paragraph |
|
|
282
|
-
| `getPDFFile()` | `get_pdf_file()` | Get PDF bytes |
|
|
283
|
-
| `savePDF(path)` | `save_pdf(path)` | Save to file |
|
|
284
|
-
| `paragraphBuilder()` | `paragraph_builder()` | Create builder |
|
|
285
|
-
| `findFonts(name, size)` | `find_fonts(name, size)` | Find fonts |
|
|
286
|
-
| `registerFont(ttfFile)` | `register_font(ttf_file)` | Register font |
|
|
287
|
-
|
|
288
|
-
## Architecture
|
|
289
|
-
|
|
290
|
-
- **Pure Manual Implementation** - No code generation, uses `requests` for HTTP
|
|
291
|
-
- **Session-based** - Constructor creates session, all operations use session ID
|
|
292
|
-
- **Strict Validation** - Matches Java client validation exactly
|
|
293
|
-
- **Type Safety** - Full type hints throughout
|
|
294
|
-
- **Error Handling** - Complete exception hierarchy
|
|
295
|
-
- **Python Conventions** - snake_case methods, context managers, Pathlib support
|
|
296
|
-
|
|
297
|
-
## Requirements
|
|
298
|
-
|
|
299
|
-
- Python 3.8+
|
|
300
|
-
- `requests` library for HTTP communication
|
|
301
|
-
- `pathlib` for file handling (built-in)
|
|
302
|
-
|
|
303
|
-
## License
|
|
304
|
-
|
|
305
|
-
[Add your license information here]
|
|
File without changes
|
{pdfdancer_client_python-0.2.5.dist-info → pdfdancer_client_python-0.2.6.dist-info}/top_level.txt
RENAMED
|
File without changes
|