pdfdancer-client-python 0.3.13__py3-none-any.whl → 3.0.0__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.
@@ -0,0 +1,521 @@
1
+ Metadata-Version: 2.4
2
+ Name: pdfdancer-client-python
3
+ Version: 3.0.0
4
+ Summary: Python client for PDFDancer API
5
+ Author-email: "The Famous Cat Ltd." <hi@thefamouscat.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://www.pdfdancer.com/
8
+ Project-URL: Documentation, https://www.pdfdancer.com/
9
+ Project-URL: Source, https://github.com/MenschMachine/pdfdancer-client-python
10
+ Project-URL: Issues, https://github.com/MenschMachine/pdfdancer-client-python/issues
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ License-File: NOTICE
21
+ Requires-Dist: httpx[http2]>=0.27.0
22
+ Requires-Dist: pydantic>=1.8.0
23
+ Requires-Dist: typing-extensions>=4.0.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=7.0; extra == "dev"
26
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
27
+ Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
28
+ Requires-Dist: pypdf>=5.0.0; extra == "dev"
29
+ Requires-Dist: black>=22.0; extra == "dev"
30
+ Requires-Dist: flake8>=5.0; extra == "dev"
31
+ Requires-Dist: mypy>=1.0; extra == "dev"
32
+ Requires-Dist: isort>=5.10.0; extra == "dev"
33
+ Requires-Dist: build>=0.8.0; extra == "dev"
34
+ Requires-Dist: twine>=4.0.0; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # PDFDancer Python Client
38
+
39
+ This README documents `pdfdancer-client-python` version `3.0.0`.
40
+
41
+ ![PDFDancer logo](media/logo-silver-60h.webp)
42
+
43
+ ## Overview
44
+
45
+ ### PDF used to be read-only. We fixed that.
46
+
47
+ Edit text in real-world PDFs—even ones you didn't create. Move images, reposition headers, and change fonts with
48
+ pixel-perfect control from Python. The same API is also available for TypeScript and Java.
49
+
50
+ ### What Makes PDFDancer Different
51
+
52
+ - **Edit text in real-world PDFs**: Work with documents from customers, governments, or vendors—even ones you didn't create.
53
+ - **Pixel-perfect positioning**: Move or add elements at exact coordinates and keep the original layout intact.
54
+ - **Selector-based text editing**: Apply literal or regular-expression replacements with page scoping and explicit layout policy.
55
+ - **Form manipulation**: Inspect, fill, and update AcroForm fields programmatically.
56
+ - **Coordinate-based selection**: Select objects by position, bounding box, or text patterns.
57
+ - **Vector graphics**: Draw lines, rectangles, and Bezier curves with full control over stroke and fill properties.
58
+ - **Real PDF editing**: Modify the underlying PDF structure instead of merely stamping overlays.
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
+
69
+ ## Installation
70
+
71
+ ```bash
72
+ pip install pdfdancer-client-python==3.0.0
73
+
74
+ # Editable install for local development
75
+ pip install -e .
76
+ ```
77
+
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`.
83
+
84
+ ## Quick Start
85
+
86
+ ### Edit an Existing PDF
87
+
88
+ ```python
89
+ from pathlib import Path
90
+ from pdfdancer import PDFDancer, PdfColorRequest, TextReplaceRequest, TextStyleRequest
91
+
92
+ with PDFDancer.open(
93
+ pdf_data=Path("input.pdf"),
94
+ token="your-api-token", # optional when PDFDANCER_API_TOKEN is set
95
+ base_url="https://api.pdfdancer.com",
96
+ ) as pdf:
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
+ )
107
+
108
+ # Persist the modified document
109
+ pdf.save("output.pdf")
110
+ # or keep it in memory
111
+ pdf_bytes = pdf.get_bytes()
112
+ ```
113
+
114
+ ## Create a Blank PDF
115
+
116
+ ```python
117
+ from pathlib import Path
118
+ from pdfdancer import PDFDancer
119
+
120
+ with PDFDancer.new(token="your-api-token") as pdf:
121
+ pdf.new_image() \
122
+ .from_file(Path("logo.png")) \
123
+ .at(page=1, x=420, y=710) \
124
+ .add()
125
+
126
+ pdf.save("summary.pdf")
127
+ ```
128
+
129
+ ## Page API
130
+
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.
133
+
134
+ ```python
135
+ first_page = pdf.page(1)
136
+ pages = pdf.pages()
137
+ snapshot = first_page.get_snapshot()
138
+ ```
139
+
140
+ Page-scoped selectors, text editing, and builders automatically restrict the operation to that page.
141
+
142
+ ## Selection
143
+
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.
147
+
148
+ ```python
149
+ document_images = pdf.select_images()
150
+ logo = pdf.page(1).select_image_at(72, 680)
151
+ page_paths = pdf.page(1).select_paths()
152
+ ```
153
+
154
+ Document and page snapshots provide read-only text-line data. Use the selector-based text API for mutations.
155
+
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:
160
+
161
+ ```python
162
+ from pdfdancer import PDFDancer, Color, Point
163
+
164
+ with PDFDancer.open("document.pdf") as pdf:
165
+ page = pdf.page(1)
166
+
167
+ # Draw a simple line
168
+ page.new_line() \
169
+ .from_point(100, 700) \
170
+ .to_point(500, 700) \
171
+ .stroke_color(Color(0, 0, 255)) \
172
+ .stroke_width(2.0) \
173
+ .add()
174
+
175
+ # Draw a rectangle
176
+ page.new_rectangle() \
177
+ .at_coordinates(100, 500) \
178
+ .with_size(200, 100) \
179
+ .stroke_color(Color(0, 0, 0)) \
180
+ .fill_color(Color(255, 255, 200)) \
181
+ .add()
182
+
183
+ # Draw a bezier curve
184
+ page.new_bezier() \
185
+ .from_point(100, 400) \
186
+ .control_point_1(150, 450) \
187
+ .control_point_2(250, 350) \
188
+ .to_point(300, 400) \
189
+ .stroke_width(1.5) \
190
+ .add()
191
+
192
+ # Build complex paths with multiple segments
193
+ page.new_path() \
194
+ .stroke_color(Color(255, 0, 0)) \
195
+ .add_line(Point(50, 200), Point(150, 200)) \
196
+ .add_line(Point(150, 200), Point(100, 280)) \
197
+ .add_line(Point(100, 280), Point(50, 200)) \
198
+ .add()
199
+
200
+ pdf.save("annotated.pdf")
201
+ ```
202
+
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
208
+
209
+ Create images at document scope with an explicit page or directly from a page client:
210
+
211
+ ```python
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
+ ```
217
+
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`.
222
+
223
+ ## Form Fields
224
+
225
+ Form-field selection uses the same names at document and page scope. Mutate a selected field directly with
226
+ `set_value(...)`:
227
+
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
+ )
260
+ ```
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
+
276
+ ## Configuration
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.
280
+ - Set `PDFDANCER_API_TOKEN` for authentication (preferred). `PDFDANCER_TOKEN` is also supported for backwards compatibility.
281
+ - Override the API host with `PDFDANCER_BASE_URL` (e.g., sandbox or local environments). Defaults to `https://api.pdfdancer.com`.
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.
284
+ - For testing against self-signed certificates, call `pdfdancer.set_ssl_verify(False)` to temporarily disable TLS verification.
285
+
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`.
292
+
293
+ Operations raise subclasses of `PdfDancerException`:
294
+
295
+ - `ValidationException`: input validation problems (missing token, invalid coordinates, etc.).
296
+ - `FontNotFoundException`: requested font unavailable on the service.
297
+ - `HttpClientException`: transport or server errors with detailed context.
298
+ - `SessionException`: session creation and lifecycle failures.
299
+ - `RateLimitException`: API rate limit exceeded; includes retry-after timing.
300
+
301
+ Wrap automated workflows in `try/except` blocks to surface actionable errors to your users.
302
+
303
+ ## Development and Testing
304
+
305
+ ### Prerequisites
306
+
307
+ - **Python 3.10 or higher** (Python 3.9 has SSL issues with large file uploads)
308
+ - **Git** for cloning the repository
309
+ - **PDFDancer API token** for running end-to-end tests
310
+
311
+ ### Step-by-Step Setup
312
+
313
+ #### 1. Clone the Repository
314
+
315
+ ```bash
316
+ git clone https://github.com/MenschMachine/pdfdancer-client-python.git
317
+ cd pdfdancer-client-python
318
+ ```
319
+
320
+ #### 2. Create a Virtual Environment and Install Dependencies
321
+
322
+ ```bash
323
+ # Create `venv` and install the package with development dependencies
324
+ make install-dev
325
+ ```
326
+
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:
329
+
330
+ ```bash
331
+ # macOS/Linux
332
+ source venv/bin/activate
333
+
334
+ # Windows
335
+ venv\Scripts\activate
336
+ ```
337
+
338
+ This installs:
339
+ - The `pdfdancer` package in editable mode (changes reflect immediately)
340
+ - Development tooling including `pytest`, `pytest-cov`, `pytest-mock`, `black`, `isort`, `flake8`, `mypy`, `build`, and `twine`.
341
+
342
+ To install runtime dependencies without development tools, use `make install`.
343
+
344
+ #### 3. Configure API Token
345
+
346
+ Set your PDFDancer API token as an environment variable:
347
+
348
+ ```bash
349
+ # On macOS/Linux:
350
+ export PDFDANCER_API_TOKEN="your-api-token-here"
351
+
352
+ # On Windows (Command Prompt):
353
+ set PDFDANCER_API_TOKEN=your-api-token-here
354
+
355
+ # On Windows (PowerShell):
356
+ $env:PDFDANCER_API_TOKEN="your-api-token-here"
357
+ ```
358
+
359
+ For permanent configuration, add this to your shell profile (`~/.bashrc`, `~/.zshrc`, etc.).
360
+
361
+ #### 4. Verify Installation
362
+
363
+ ```bash
364
+ # Run the test suite
365
+ pytest tests/ -v
366
+
367
+ # Run only unit tests (faster)
368
+ pytest tests/test_models.py -v
369
+
370
+ # Run end-to-end tests (requires API token)
371
+ pytest tests/e2e/ -v
372
+ ```
373
+
374
+ All tests should pass if everything is set up correctly.
375
+
376
+ ### Common Development Tasks
377
+
378
+ Run `make help` to list all developer targets and their configurable variables.
379
+
380
+ #### Running Tests
381
+
382
+ ```bash
383
+ # Run all tests with verbose output
384
+ make test
385
+
386
+ # Run tests that do not require API access
387
+ make test-unit
388
+
389
+ # Run end-to-end tests only
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"
395
+
396
+ # Run all tests with a coverage report
397
+ make coverage
398
+ ```
399
+
400
+ #### Building Distribution Packages
401
+
402
+ ```bash
403
+ # Clean, build, and verify the wheel and source distribution
404
+ make package
405
+ ```
406
+
407
+ Artifacts will be created in the `dist/` directory. Package versions are derived from Git tags via `setuptools-scm`.
408
+
409
+ #### Publishing to PyPI
410
+
411
+ Releases are published automatically to PyPI when a `v*` tag is pushed to GitHub (via GitHub Actions with Trusted Publishers).
412
+
413
+ ```bash
414
+ # Create and push a release tag — GitHub Actions handles the rest
415
+ git tag v2.0.0
416
+ git push origin v2.0.0
417
+ ```
418
+
419
+ #### Code Quality
420
+
421
+ ```bash
422
+ # Format code
423
+ make format
424
+
425
+ # Check formatting without changing files
426
+ make format-check
427
+
428
+ # Lint
429
+ make lint
430
+
431
+ # Type-check
432
+ make typecheck
433
+
434
+ # Run formatting checks, linting, type checking, and non-E2E tests
435
+ make check
436
+ ```
437
+
438
+ ### Project Structure
439
+
440
+ ```
441
+ pdfdancer-client-python/
442
+ ├── src/pdfdancer/ # Main package source
443
+ │ ├── __init__.py # Package exports
444
+ │ ├── pdfdancer_v2.py # Core PDFDancer and PageClient classes
445
+ │ ├── text_editing.py # Selector-based v2 text request builders
446
+ │ ├── image_builder.py # Fluent image builders
447
+ │ ├── path_builder.py # Vector path builders (lines, beziers, rectangles)
448
+ │ ├── page_builder.py # Page creation builder
449
+ │ ├── models.py # Data models (Position, Font, Color, etc.)
450
+ │ ├── types.py # Live object-reference wrappers
451
+ │ └── exceptions.py # Exception hierarchy
452
+ ├── tests/ # Test suite
453
+ │ ├── test_models.py # Model unit tests
454
+ │ ├── e2e/ # End-to-end integration tests
455
+ │ └── fixtures/ # Test fixtures and sample PDFs
456
+ ├── docs/ # Documentation
457
+ ├── dist/ # Build artifacts (created after packaging)
458
+ ├── pyproject.toml # Project metadata and dependencies
459
+ └── README.md # This file
460
+ ```
461
+
462
+ ## Troubleshooting
463
+
464
+ #### Virtual Environment Issues
465
+
466
+ If `python -m venv venv` fails, ensure you have the `venv` module:
467
+
468
+ ```bash
469
+ # On Ubuntu/Debian
470
+ sudo apt-get install python3-venv
471
+
472
+ # On macOS (using Homebrew)
473
+ brew install python@3.10
474
+ ```
475
+
476
+ #### SSL Errors with Large Files
477
+
478
+ Upgrade to Python 3.10+ if you encounter SSL errors during large file uploads.
479
+
480
+ #### Import Errors
481
+
482
+ Ensure the virtual environment is activated and the package is installed in editable mode:
483
+
484
+ ```bash
485
+ source venv/bin/activate # or venv\Scripts\activate on Windows
486
+ pip install -e .
487
+ ```
488
+
489
+ #### Test Failures
490
+
491
+ - Ensure `PDFDANCER_API_TOKEN` is set for e2e tests
492
+ - Check network connectivity to the PDFDancer API
493
+ - Verify you're using Python 3.10 or higher
494
+
495
+ ## Contributing
496
+
497
+ Contributions are welcome via pull request. Please:
498
+
499
+ 1. Create a feature branch from `main`
500
+ 2. Add tests for new functionality
501
+ 3. Ensure all tests pass: `pytest tests/ -v`
502
+ 4. Follow existing code style and patterns
503
+ 5. Update documentation as needed
504
+
505
+ ## Helpful Links
506
+
507
+ - [API documentation](https://docs.pdfdancer.com?utm_source=github&utm_medium=readme&utm_campaign=pdfdancer-python)
508
+ - [Product overview](https://www.pdfdancer.com?utm_source=github&utm_medium=readme&utm_campaign=pdfdancer-python)
509
+ - [PyPI](https://pypi.org/project/pdfdancer-client-python/)
510
+ - [Changelog](https://www.pdfdancer.com/changelog/?utm_source=github&utm_medium=readme&utm_campaign=pdfdancer-python)
511
+ - [Status](https://status.pdfdancer.com?utm_source=github&utm_medium=readme&utm_campaign=pdfdancer-python)
512
+ - [Issue tracker](https://github.com/MenschMachine/pdfdancer)
513
+
514
+ ## Related SDKs
515
+
516
+ - TypeScript client: https://github.com/MenschMachine/pdfdancer-client-typescript
517
+ - Java client: https://github.com/MenschMachine/pdfdancer-client-java
518
+
519
+ ## License
520
+
521
+ Apache License 2.0 © 2025 The Famous Cat Ltd. See `LICENSE` and `NOTICE` for details.
@@ -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=Q5KDuzxagP6DhS0ZWCmUUKtPbVMNBgYpVtHVHkQdyPQ,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.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
14
+ pdfdancer_client_python-3.0.0.dist-info/licenses/NOTICE,sha256=xaC4l-IChAmtViNDie8ZWzUk0O6XRMyzOl0zLmVZ2HE,232
15
+ pdfdancer_client_python-3.0.0.dist-info/METADATA,sha256=TcvRgCLXAywFJ4GMBMtzI4DqWSD1CWytHHctQN7TD4E,17618
16
+ pdfdancer_client_python-3.0.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
17
+ pdfdancer_client_python-3.0.0.dist-info/top_level.txt,sha256=ICwSVRpcCKrdBF9QlaX9Y0e_N3Nk1p7QVxadGOnbxeY,10
18
+ pdfdancer_client_python-3.0.0.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