pdfdancer-client-python 0.3.14__py3-none-any.whl → 3.0.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pdfdancer-client-python
3
- Version: 0.3.14
3
+ Version: 3.0.1
4
4
  Summary: Python client for PDFDancer API
5
5
  Author-email: "The Famous Cat Ltd." <hi@thefamouscat.com>
6
6
  License-Expression: Apache-2.0
@@ -21,11 +21,11 @@ License-File: NOTICE
21
21
  Requires-Dist: httpx[http2]>=0.27.0
22
22
  Requires-Dist: pydantic>=1.8.0
23
23
  Requires-Dist: typing-extensions>=4.0.0
24
- Requires-Dist: python-dotenv>=0.19.0
25
24
  Provides-Extra: dev
26
25
  Requires-Dist: pytest>=7.0; extra == "dev"
27
26
  Requires-Dist: pytest-cov>=4.0; extra == "dev"
28
27
  Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
28
+ Requires-Dist: pypdf>=5.0.0; extra == "dev"
29
29
  Requires-Dist: black>=22.0; extra == "dev"
30
30
  Requires-Dist: flake8>=5.0; extra == "dev"
31
31
  Requires-Dist: mypy>=1.0; extra == "dev"
@@ -36,73 +36,74 @@ Dynamic: license-file
36
36
 
37
37
  # PDFDancer Python Client
38
38
 
39
+ This README documents `pdfdancer-client-python` version `3.0.0`.
40
+
39
41
  ![PDFDancer logo](media/logo-silver-60h.webp)
40
42
 
41
- ## PDF used to be read-only. We fixed that.
43
+ ## Overview
44
+
45
+ ### PDF used to be read-only. We fixed that.
42
46
 
43
47
  Edit text in real-world PDFs—even ones you didn't create. Move images, reposition headers, and change fonts with
44
48
  pixel-perfect control from Python. The same API is also available for TypeScript and Java.
45
49
 
46
- > Need the raw API schema? The latest OpenAPI description lives in `docs/openapi.yml` and is published at
47
- > https://bucket.pdfdancer.com/api-doc/development-0.0.yml.
48
-
49
- ## Highlights
50
-
51
- - Locate paragraphs, text lines, images, vector paths, form fields, and pages by page number, coordinates, or text patterns.
52
- - Edit existing content in place with fluent editors and context managers that apply changes safely.
53
- - Programmatically control third-party PDFs—modify invoices, contracts, and reports you did not author.
54
- - Add content with precise XY positioning using paragraph, image, and vector path builders with custom fonts and colors.
55
- - Draw lines, rectangles, and Bezier curves with configurable stroke width, dash patterns, and fill colors.
56
- - Redact sensitive content—replace text, images, or form fields with customizable placeholders.
57
- - Export results as bytes for downstream processing or save directly to disk with one call.
58
-
59
- ## What Makes PDFDancer Different
50
+ ### What Makes PDFDancer Different
60
51
 
61
52
  - **Edit text in real-world PDFs**: Work with documents from customers, governments, or vendors—even ones you didn't create.
62
53
  - **Pixel-perfect positioning**: Move or add elements at exact coordinates and keep the original layout intact.
63
- - **Surgical text replacement**: Swap or rewrite paragraphs without reflowing the rest of the page.
54
+ - **Selector-based text editing**: Apply literal or regular-expression replacements with page scoping and explicit layout policy.
64
55
  - **Form manipulation**: Inspect, fill, and update AcroForm fields programmatically.
65
56
  - **Coordinate-based selection**: Select objects by position, bounding box, or text patterns.
66
57
  - **Vector graphics**: Draw lines, rectangles, and Bezier curves with full control over stroke and fill properties.
67
- - **Secure redaction**: Permanently remove sensitive content and replace with customizable markers.
68
58
  - **Real PDF editing**: Modify the underlying PDF structure instead of merely stamping overlays.
69
59
 
60
+ ## Highlights
61
+
62
+ - Replace, insert, delete, and style text with selector-based v2 operations.
63
+ - Locate images, vector paths, form fields, and pages by page number or coordinates; inspect text-line data through snapshots.
64
+ - Programmatically control third-party PDFs—modify invoices, contracts, and reports you did not author.
65
+ - Add images and vector paths with precise XY positioning.
66
+ - Draw lines, rectangles, and Bezier curves with configurable stroke width, dash patterns, and fill colors.
67
+ - Export results as bytes for downstream processing or save directly to disk with one call.
68
+
70
69
  ## Installation
71
70
 
72
71
  ```bash
73
- pip install pdfdancer-client-python
72
+ pip install pdfdancer-client-python==3.0.0
74
73
 
75
74
  # Editable install for local development
76
75
  pip install -e .
77
76
  ```
78
77
 
79
- Requires Python 3.10+ and a PDFDancer API token.
78
+ ## Requirements
79
+
80
+ - Python 3.10 or newer.
81
+ - A PDFDancer API token, supplied explicitly or through `PDFDANCER_API_TOKEN` or `PDFDANCER_TOKEN`.
82
+ - Access to the PDFDancer API host. The default is `https://api.pdfdancer.com`.
80
83
 
81
- ## Quick Start — Edit an Existing PDF
84
+ ## Quick Start
85
+
86
+ ### Edit an Existing PDF
82
87
 
83
88
  ```python
84
89
  from pathlib import Path
85
- from pdfdancer import Color, PDFDancer, StandardFonts
90
+ from pdfdancer import PDFDancer, PdfColorRequest, TextReplaceRequest, TextStyleRequest
86
91
 
87
92
  with PDFDancer.open(
88
93
  pdf_data=Path("input.pdf"),
89
94
  token="your-api-token", # optional when PDFDANCER_API_TOKEN is set
90
95
  base_url="https://api.pdfdancer.com",
91
96
  ) as pdf:
92
- # Locate and update an existing paragraph
93
- heading = pdf.page(0).select_paragraphs_starting_with("Executive Summary")[0]
94
- heading.move_to(72, 680)
95
- with heading.edit() as editor:
96
- editor.replace("Overview")
97
-
98
- # Add a new paragraph with precise placement
99
- pdf.new_paragraph() \
100
- .text("Generated with PDFDancer") \
101
- .font(StandardFonts.HELVETICA, 12) \
102
- .color(Color(70, 70, 70)) \
103
- .line_spacing(1.4) \
104
- .at(page_number=1, x=72, y=520) \
105
- .add()
97
+ result = pdf.page(1).text().replace(
98
+ TextReplaceRequest.literal("Executive Summary", "Overview").build()
99
+ )
100
+ assert result.changed == 1
101
+
102
+ pdf.text().style(
103
+ TextStyleRequest.literal("Overview")
104
+ .fill_color(PdfColorRequest.rgb(0.2, 0.2, 0.6))
105
+ .build()
106
+ )
106
107
 
107
108
  # Persist the modified document
108
109
  pdf.save("output.pdf")
@@ -114,68 +115,54 @@ with PDFDancer.open(
114
115
 
115
116
  ```python
116
117
  from pathlib import Path
117
- from pdfdancer import Color, PDFDancer, StandardFonts
118
+ from pdfdancer import PDFDancer
118
119
 
119
120
  with PDFDancer.new(token="your-api-token") as pdf:
120
- pdf.new_paragraph() \
121
- .text("Quarterly Summary") \
122
- .font(StandardFonts.TIMES_BOLD, 18) \
123
- .color(Color(10, 10, 80)) \
124
- .line_spacing(1.2) \
125
- .at(page_number=1, x=72, y=730) \
126
- .add()
127
-
128
121
  pdf.new_image() \
129
122
  .from_file(Path("logo.png")) \
130
- .at(page=0, x=420, y=710) \
123
+ .at(page=1, x=420, y=710) \
131
124
  .add()
132
125
 
133
126
  pdf.save("summary.pdf")
134
127
  ```
135
128
 
136
- ## Work with Forms and Layout
129
+ ## Page API
137
130
 
138
- ```python
139
- from pdfdancer import PDFDancer
131
+ Page numbers are 1-based. `pdf.page(1)` returns a page-scoped client, while `pdf.pages()` returns page clients for the
132
+ document. Use `get_snapshot()` on a page client for a read-only page snapshot.
140
133
 
141
- with PDFDancer.open("contract.pdf") as pdf:
142
- # Inspect global document structure
143
- pages = pdf.pages()
144
- print("Total pages:", len(pages))
145
-
146
- # Update form fields
147
- signature = pdf.select_form_fields_by_name("signature")[0]
148
- signature.edit().value("Signed by Jane Doe").apply()
149
-
150
- # Trim or move content at specific coordinates
151
- images = pdf.page(1).select_images()
152
- for image in images:
153
- x = image.position.x()
154
- if x is not None and x < 100:
155
- image.delete()
134
+ ```python
135
+ first_page = pdf.page(1)
136
+ pages = pdf.pages()
137
+ snapshot = first_page.get_snapshot()
156
138
  ```
157
139
 
158
- Selectors return typed objects (`ParagraphObject`, `TextLineObject`, `ImageObject`, `FormFieldObject`, `PageClient`, …)
159
- with helpers such as `delete()`, `move_to(x, y)`, `clear_clipping()`, `redact()`, or `edit()` depending on the object type.
140
+ Page-scoped selectors, text editing, and builders automatically restrict the operation to that page.
141
+
142
+ ## Selection
160
143
 
161
- **Singular selection methods** return the first match (or `None`) for convenience:
144
+ Document- and page-scoped selectors return typed objects for images, paths, form XObjects, and form fields. Position
145
+ selectors use PDF coordinates and a default tolerance of `0.01` point. Singular selectors return the first match or
146
+ `None`; plural selectors return lists.
162
147
 
163
148
  ```python
164
- # Instead of: paragraphs = page.select_paragraphs_starting_with("Invoice")[0]
165
- paragraph = page.select_paragraph_starting_with("Invoice") # Returns first match or None
166
- image = page.select_image_at(100, 200) # Returns first match or None
167
- field = pdf.select_form_field_by_name("email") # Returns first match or None
149
+ document_images = pdf.select_images()
150
+ logo = pdf.page(1).select_image_at(72, 680)
151
+ page_paths = pdf.page(1).select_paths()
168
152
  ```
169
153
 
170
- ## Draw Vector Paths
154
+ Document and page snapshots provide read-only text-line data. Use the selector-based text API for mutations.
171
155
 
172
- Add lines, curves, and shapes to your PDFs with fluent builders:
156
+ ## Builders and Vector Paths
157
+
158
+ All five dedicated builders are available at document and page scope: image, path, line, Bezier, and rectangle. Add
159
+ lines, curves, and shapes with fluent builders:
173
160
 
174
161
  ```python
175
162
  from pdfdancer import PDFDancer, Color, Point
176
163
 
177
164
  with PDFDancer.open("document.pdf") as pdf:
178
- page = pdf.page(0)
165
+ page = pdf.page(1)
179
166
 
180
167
  # Draw a simple line
181
168
  page.new_line() \
@@ -213,39 +200,95 @@ with PDFDancer.open("document.pdf") as pdf:
213
200
  pdf.save("annotated.pdf")
214
201
  ```
215
202
 
216
- ## Redact Sensitive Content
203
+ `PathBuilder` also provides cursor-based `move_to(...)`, `line_to(...)`, and `bezier_to(...)` operations plus
204
+ `close_path()`, `rectangle(...)`, `circle(...)`, and `solid()` conveniences. A circle is a `PathBuilder` convenience,
205
+ not a separate builder type.
206
+
207
+ ## Images
217
208
 
218
- Remove text, images, or form fields and replace them with redaction markers:
209
+ Create images at document scope with an explicit page or directly from a page client:
219
210
 
220
211
  ```python
221
- from pdfdancer import PDFDancer, Color
212
+ from pathlib import Path
213
+
214
+ pdf.new_image().from_file(Path("logo.png")).at(page=1, x=72, y=700).add()
215
+ pdf.page(1).new_image().from_file(Path("stamp.png")).at(x=300, y=700).add()
216
+ ```
222
217
 
223
- with PDFDancer.open("confidential.pdf") as pdf:
224
- # Redact paragraphs containing sensitive patterns
225
- for para in pdf.select_paragraphs():
226
- if "SSN:" in para.text or "Password:" in para.text:
227
- para.redact("[REDACTED]")
218
+ `ImageObject` exposes `width`, `height`, and `aspect_ratio`. It supports replacement from a filesystem path or `Image`,
219
+ proportional or explicit scaling, cropping, opacity, horizontal and vertical flips, region filling, and rotation.
220
+ Positive rotation angles are clockwise. Image transformations return `CommandResult`, which exposes `success`,
221
+ `message`, `warning`, and `element_id`.
228
222
 
229
- # Redact all images on a specific page
230
- for image in pdf.page(0).select_images():
231
- image.redact()
223
+ ## Form Fields
232
224
 
233
- # Bulk redact multiple objects with custom placeholder color
234
- form_fields = pdf.select_form_fields_by_name("credit_card")
235
- result = pdf.redact(form_fields, replacement="[REMOVED]", placeholder_color=Color(0, 0, 0))
236
- print(f"Redacted {result.count} items")
225
+ Form-field selection uses the same names at document and page scope. Mutate a selected field directly with
226
+ `set_value(...)`:
237
227
 
238
- pdf.save("redacted.pdf")
228
+ ```python
229
+ signature = pdf.select_form_fields_by_name("signature")[0]
230
+ changed = signature.set_value("Signed by Jane Doe")
231
+ ```
232
+
233
+ Selectors return typed objects (`ImageObject`, `FormFieldObject`, `PathObject`, `PageClient`, …) with generic helpers
234
+ such as `delete()`, `move_to(x, y)`, and `clear_clipping()` where supported by the selected object type.
235
+
236
+ ## Text Editing
237
+
238
+ Text editing is selector-based and is available through `pdf.text()` and `pdf.page(page_number).text()`. It supports
239
+ replace, delete, insert, and style operations:
240
+
241
+ ```python
242
+ from pdfdancer import TextDeleteRequest, TextInsertRequest, TextReplaceRequest
243
+
244
+ pdf.text().replace(
245
+ TextReplaceRequest.literal("Old product", "New product")
246
+ .whole_words(True)
247
+ .max_matches(5)
248
+ .build()
249
+ )
250
+
251
+ pdf.page(2).text().delete(
252
+ TextDeleteRequest.regex(r"Confidential\s+draft")
253
+ .case_sensitive(False)
254
+ .build()
255
+ )
256
+
257
+ pdf.text().insert(
258
+ TextInsertRequest.before("Terms", "Updated ").whole_words(True).build()
259
+ )
239
260
  ```
240
261
 
262
+ Each mutation returns `TextEditResponse`, including match and change counts, changed page numbers, per-change
263
+ diagnostics, warnings, and errors.
264
+
265
+ ## Shared Models
266
+
267
+ `Color` requires integral RGBA components in the inclusive range 0–255. Alpha defaults to 255; `BLACK`, `WHITE`, and
268
+ `RED` are provided as constants.
269
+
270
+ `PageSize` provides A0–A6, B4–B5, Letter, Legal, Tabloid, Executive, Postcard, and 3×5 Index sizes.
271
+ `PageSize.from_dimensions(...)` recognizes both portrait and rotated standard dimensions; custom dimensions must be
272
+ finite and positive.
273
+
274
+ The exported `ObjectType` enum covers every object type returned by the v2 snapshot and selection APIs.
275
+
241
276
  ## Configuration
242
277
 
278
+ - The SDK reads the process environment but does not load `.env` files. Applications that use `.env` files must load
279
+ them before calling the SDK.
243
280
  - Set `PDFDANCER_API_TOKEN` for authentication (preferred). `PDFDANCER_TOKEN` is also supported for backwards compatibility.
244
281
  - Override the API host with `PDFDANCER_BASE_URL` (e.g., sandbox or local environments). Defaults to `https://api.pdfdancer.com`.
245
282
  - Tune HTTP read timeouts via the `timeout` argument on `PDFDancer.open()` and `PDFDancer.new()` (default: 30 seconds).
283
+ - Configure total request attempts with `max_attempts` or `PDFDANCER_MAX_ATTEMPTS`; the initial request counts as one attempt.
246
284
  - For testing against self-signed certificates, call `pdfdancer.set_ssl_verify(False)` to temporarily disable TLS verification.
247
285
 
248
- ## Error Handling
286
+ ## Retry and Error Handling
287
+
288
+ The default HTTP policy makes three total attempts, including the initial request. It uses exponential backoff starting
289
+ at one second, a multiplier of two, and a five-second delay cap. Statuses 408, 429, 500, 502, 503, 504, and 520 are
290
+ retryable, as are timeout and connection failures. `Retry-After` is honored only for HTTP 429; retry delays do not use
291
+ jitter. Configure the total attempt count with `max_attempts` and the multiplier with `retry_backoff_factor`.
249
292
 
250
293
  Operations raise subclasses of `PdfDancerException`:
251
294
 
@@ -257,7 +300,7 @@ Operations raise subclasses of `PdfDancerException`:
257
300
 
258
301
  Wrap automated workflows in `try/except` blocks to surface actionable errors to your users.
259
302
 
260
- ## Development Setup
303
+ ## Development and Testing
261
304
 
262
305
  ### Prerequisites
263
306
 
@@ -274,37 +317,31 @@ git clone https://github.com/MenschMachine/pdfdancer-client-python.git
274
317
  cd pdfdancer-client-python
275
318
  ```
276
319
 
277
- #### 2. Create a Virtual Environment
320
+ #### 2. Create a Virtual Environment and Install Dependencies
278
321
 
279
322
  ```bash
280
- # Create virtual environment
281
- python -m venv venv
282
-
283
- # Activate the virtual environment
284
- # On macOS/Linux:
285
- source venv/bin/activate
286
-
287
- # On Windows:
288
- venv\Scripts\activate
323
+ # Create `venv` and install the package with development dependencies
324
+ make install-dev
289
325
  ```
290
326
 
291
- You should see `(venv)` in your terminal prompt indicating the virtual environment is active.
292
-
293
- #### 3. Install Dependencies
327
+ The Makefile creates the local `venv` when needed and runs all developer targets with its Python interpreter. Activating
328
+ the environment is optional; activate it if you also want to run commands directly:
294
329
 
295
330
  ```bash
296
- # Install the package in editable mode with development dependencies
297
- pip install -e ".[dev]"
331
+ # macOS/Linux
332
+ source venv/bin/activate
298
333
 
299
- # Alternatively, install runtime dependencies only:
300
- # pip install -e .
334
+ # Windows
335
+ venv\Scripts\activate
301
336
  ```
302
337
 
303
338
  This installs:
304
339
  - The `pdfdancer` package in editable mode (changes reflect immediately)
305
340
  - Development tooling including `pytest`, `pytest-cov`, `pytest-mock`, `black`, `isort`, `flake8`, `mypy`, `build`, and `twine`.
306
341
 
307
- #### 4. Configure API Token
342
+ To install runtime dependencies without development tools, use `make install`.
343
+
344
+ #### 3. Configure API Token
308
345
 
309
346
  Set your PDFDancer API token as an environment variable:
310
347
 
@@ -321,7 +358,7 @@ $env:PDFDANCER_API_TOKEN="your-api-token-here"
321
358
 
322
359
  For permanent configuration, add this to your shell profile (`~/.bashrc`, `~/.zshrc`, etc.).
323
360
 
324
- #### 5. Verify Installation
361
+ #### 4. Verify Installation
325
362
 
326
363
  ```bash
327
364
  # Run the test suite
@@ -338,30 +375,33 @@ All tests should pass if everything is set up correctly.
338
375
 
339
376
  ### Common Development Tasks
340
377
 
378
+ Run `make help` to list all developer targets and their configurable variables.
379
+
341
380
  #### Running Tests
342
381
 
343
382
  ```bash
344
383
  # Run all tests with verbose output
345
- pytest tests/ -v
384
+ make test
346
385
 
347
- # Run specific test file
348
- pytest tests/test_models.py -v
386
+ # Run tests that do not require API access
387
+ make test-unit
349
388
 
350
389
  # Run end-to-end tests only
351
- pytest tests/e2e/ -v
390
+ make test-e2e
391
+
392
+ # Run a specific test file or pass additional pytest arguments
393
+ make test TEST_PATH=tests/test_models.py
394
+ make test PYTEST_ARGS="-v -x"
352
395
 
353
- # Run with coverage report
354
- pytest tests/ --cov=pdfdancer --cov-report=term-missing
396
+ # Run all tests with a coverage report
397
+ make coverage
355
398
  ```
356
399
 
357
400
  #### Building Distribution Packages
358
401
 
359
402
  ```bash
360
- # Build wheel and source distribution
361
- python -m build
362
-
363
- # Verify the built packages
364
- python -m twine check dist/*
403
+ # Clean, build, and verify the wheel and source distribution
404
+ make package
365
405
  ```
366
406
 
367
407
  Artifacts will be created in the `dist/` directory. Package versions are derived from Git tags via `setuptools-scm`.
@@ -372,22 +412,27 @@ Releases are published automatically to PyPI when a `v*` tag is pushed to GitHub
372
412
 
373
413
  ```bash
374
414
  # Create and push a release tag — GitHub Actions handles the rest
375
- git tag v1.1.0
376
- git push origin v1.1.0
415
+ git tag v2.0.0
416
+ git push origin v2.0.0
377
417
  ```
378
418
 
379
419
  #### Code Quality
380
420
 
381
421
  ```bash
382
422
  # Format code
383
- black src tests
384
- isort src tests
423
+ make format
424
+
425
+ # Check formatting without changing files
426
+ make format-check
385
427
 
386
428
  # Lint
387
- flake8 src tests
429
+ make lint
430
+
431
+ # Type-check
432
+ make typecheck
388
433
 
389
- # Type checking
390
- mypy src/pdfdancer/
434
+ # Run formatting checks, linting, type checking, and non-E2E tests
435
+ make check
391
436
  ```
392
437
 
393
438
  ### Project Structure
@@ -396,14 +441,13 @@ mypy src/pdfdancer/
396
441
  pdfdancer-client-python/
397
442
  ├── src/pdfdancer/ # Main package source
398
443
  │ ├── __init__.py # Package exports
399
- │ ├── pdfdancer_v1.py # Core PDFDancer and PageClient classes
400
- │ ├── paragraph_builder.py # Fluent paragraph builders
401
- │ ├── text_line_builder.py # Fluent text line builders
444
+ │ ├── pdfdancer_v2.py # Core PDFDancer and PageClient classes
445
+ │ ├── text_editing.py # Selector-based v2 text request builders
402
446
  │ ├── image_builder.py # Fluent image builders
403
447
  │ ├── path_builder.py # Vector path builders (lines, beziers, rectangles)
404
448
  │ ├── page_builder.py # Page creation builder
405
449
  │ ├── models.py # Data models (Position, Font, Color, etc.)
406
- │ ├── types.py # Object wrappers (ParagraphObject, etc.)
450
+ │ ├── types.py # Live object-reference wrappers
407
451
  │ └── exceptions.py # Exception hierarchy
408
452
  ├── tests/ # Test suite
409
453
  │ ├── test_models.py # Model unit tests
@@ -415,7 +459,7 @@ pdfdancer-client-python/
415
459
  └── README.md # This file
416
460
  ```
417
461
 
418
- ### Troubleshooting
462
+ ## Troubleshooting
419
463
 
420
464
  #### Virtual Environment Issues
421
465
 
@@ -448,7 +492,7 @@ pip install -e .
448
492
  - Check network connectivity to the PDFDancer API
449
493
  - Verify you're using Python 3.10 or higher
450
494
 
451
- ### Contributing
495
+ ## Contributing
452
496
 
453
497
  Contributions are welcome via pull request. Please:
454
498
 
@@ -458,7 +502,7 @@ Contributions are welcome via pull request. Please:
458
502
  4. Follow existing code style and patterns
459
503
  5. Update documentation as needed
460
504
 
461
- ## Helpful links
505
+ ## Helpful Links
462
506
 
463
507
  - [API documentation](https://docs.pdfdancer.com?utm_source=github&utm_medium=readme&utm_campaign=pdfdancer-python)
464
508
  - [Product overview](https://www.pdfdancer.com?utm_source=github&utm_medium=readme&utm_campaign=pdfdancer-python)
@@ -0,0 +1,18 @@
1
+ pdfdancer/__init__.py,sha256=iD0IWfpLFrPoFQhsZ_fGUpv9fH21QNJchM_23pTtdds,4419
2
+ pdfdancer/_runtime_version.py,sha256=UIId9w7Jk97tPVOppEJeq4HKVEt3BIMc6jeThKU31k4,825
3
+ pdfdancer/_version.py,sha256=DQj8PXaBgkooJVvjTVd86hfQE03x_PUMKRF3guh3670,520
4
+ pdfdancer/exceptions.py,sha256=U6kD3NvcdNt05_OU11Tml5dXGtlodEtYC9zcV4fHXkc,2270
5
+ pdfdancer/fingerprint.py,sha256=eL3PHPgv-knMya7s95RXg3qzzpkAA1aevxqb6tuOb34,3061
6
+ pdfdancer/image_builder.py,sha256=R4ik7ZN-iGWUsy7UHoMvpAEzc_MHquPY9Q27g_zuEtI,2987
7
+ pdfdancer/models.py,sha256=6N-rybJnXo2Y3KrWcBxN0uVq5HxyrVDqMO52lcvW_G4,51558
8
+ pdfdancer/page_builder.py,sha256=2Ll98fkNen7dtlQe_uhYDJPKqqnqMMeOTYlymeWtaII,3528
9
+ pdfdancer/path_builder.py,sha256=znQD3zgBs7u--pQ3OdUJOSvBhBLCm80pdH6Kg0_T-io,28502
10
+ pdfdancer/pdfdancer_v2.py,sha256=8YiMMDeaybPNBpybf9kESwnE48wscdOlk1AcJrDCBSc,120419
11
+ pdfdancer/text_editing.py,sha256=iA3n-yWca95ilNJSHMxFirGKhXpl_SGgg2NuuAUVGOQ,51768
12
+ pdfdancer/types.py,sha256=Mwr4d1C-pS7kSctgXH0F6LEOu8Q0EFaFAOMjiGlrRaQ,16961
13
+ pdfdancer_client_python-3.0.1.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
14
+ pdfdancer_client_python-3.0.1.dist-info/licenses/NOTICE,sha256=xaC4l-IChAmtViNDie8ZWzUk0O6XRMyzOl0zLmVZ2HE,232
15
+ pdfdancer_client_python-3.0.1.dist-info/METADATA,sha256=oiYBb7IxHTiNZL3ZyIo30Ht0Q9xpzMV_rVrB3_GI-vw,17618
16
+ pdfdancer_client_python-3.0.1.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
17
+ pdfdancer_client_python-3.0.1.dist-info/top_level.txt,sha256=ICwSVRpcCKrdBF9QlaX9Y0e_N3Nk1p7QVxadGOnbxeY,10
18
+ pdfdancer_client_python-3.0.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (82.0.1)
2
+ Generator: setuptools (83.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5