pdfbolt 1.0.0__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.
Files changed (38) hide show
  1. pdfbolt-1.0.0/.github/workflows/ci.yml +50 -0
  2. pdfbolt-1.0.0/.gitignore +14 -0
  3. pdfbolt-1.0.0/CHANGELOG.md +18 -0
  4. pdfbolt-1.0.0/LICENSE +21 -0
  5. pdfbolt-1.0.0/PKG-INFO +405 -0
  6. pdfbolt-1.0.0/README.md +370 -0
  7. pdfbolt-1.0.0/examples/__init__.py +1 -0
  8. pdfbolt-1.0.0/examples/_common.py +37 -0
  9. pdfbolt-1.0.0/examples/async_job.py +36 -0
  10. pdfbolt-1.0.0/examples/convert_html.py +48 -0
  11. pdfbolt-1.0.0/examples/direct_base64.py +23 -0
  12. pdfbolt-1.0.0/examples/error_classes.py +41 -0
  13. pdfbolt-1.0.0/examples/quick_start.py +25 -0
  14. pdfbolt-1.0.0/examples/sync.py +36 -0
  15. pdfbolt-1.0.0/examples/template.py +34 -0
  16. pdfbolt-1.0.0/examples/webhook_server.py +132 -0
  17. pdfbolt-1.0.0/pyproject.toml +67 -0
  18. pdfbolt-1.0.0/scripts/test_pack.py +121 -0
  19. pdfbolt-1.0.0/src/pdfbolt/__init__.py +114 -0
  20. pdfbolt-1.0.0/src/pdfbolt/_utils.py +107 -0
  21. pdfbolt-1.0.0/src/pdfbolt/_version.py +1 -0
  22. pdfbolt-1.0.0/src/pdfbolt/client.py +34 -0
  23. pdfbolt-1.0.0/src/pdfbolt/direct_result.py +68 -0
  24. pdfbolt-1.0.0/src/pdfbolt/errors.py +50 -0
  25. pdfbolt-1.0.0/src/pdfbolt/http.py +156 -0
  26. pdfbolt-1.0.0/src/pdfbolt/models.py +305 -0
  27. pdfbolt-1.0.0/src/pdfbolt/py.typed +1 -0
  28. pdfbolt-1.0.0/src/pdfbolt/rate_limit.py +45 -0
  29. pdfbolt-1.0.0/src/pdfbolt/resources/__init__.py +1 -0
  30. pdfbolt-1.0.0/src/pdfbolt/resources/async_conversions.py +94 -0
  31. pdfbolt-1.0.0/src/pdfbolt/resources/direct.py +70 -0
  32. pdfbolt-1.0.0/src/pdfbolt/resources/sync.py +81 -0
  33. pdfbolt-1.0.0/src/pdfbolt/resources/usage.py +22 -0
  34. pdfbolt-1.0.0/src/pdfbolt/types.py +202 -0
  35. pdfbolt-1.0.0/src/pdfbolt/webhooks.py +91 -0
  36. pdfbolt-1.0.0/tests/live/test_integration.py +177 -0
  37. pdfbolt-1.0.0/tests/test_client.py +748 -0
  38. pdfbolt-1.0.0/tests/typecheck_usage.py +55 -0
@@ -0,0 +1,50 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ name: Python ${{ matrix.python-version }}
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
17
+
18
+ steps:
19
+ - name: Check out repository
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Set up Python
23
+ uses: actions/setup-python@v5
24
+ with:
25
+ python-version: ${{ matrix.python-version }}
26
+ allow-prereleases: true
27
+ cache: pip
28
+
29
+ - name: Install dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ python -m pip install -e ".[dev]"
33
+
34
+ - name: Lint
35
+ run: ruff check .
36
+
37
+ - name: Typecheck
38
+ run: mypy src tests/typecheck_usage.py
39
+
40
+ - name: Test
41
+ run: pytest
42
+
43
+ - name: Build package
44
+ run: python -m build
45
+
46
+ - name: Check package metadata
47
+ run: twine check dist/*
48
+
49
+ - name: Smoke test package
50
+ run: python scripts/test_pack.py
@@ -0,0 +1,14 @@
1
+ .venv/
2
+ .idea/
3
+ __pycache__/
4
+ *.py[cod]
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+ .mypy_cache/
8
+ dist/
9
+ build/
10
+ *.egg-info/
11
+ .env
12
+ .env.*
13
+ *.pdf
14
+ examples/output/
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0 - 2026-06-16
4
+
5
+ Initial release of the official PDFBolt Python SDK.
6
+
7
+ ### Added
8
+
9
+ - Direct PDF generation from HTTPS URLs, raw HTML, and published templates.
10
+ - Sync conversion jobs returning temporary PDF URLs.
11
+ - Async conversion jobs with webhook delivery.
12
+ - Custom S3 presigned URL support for sync and async conversions.
13
+ - Usage API support.
14
+ - Webhook signature verification helpers.
15
+ - Typed result models for direct, sync, async, webhook, usage, and rate-limit responses.
16
+ - SDK error classes for API, network, validation, configuration, and webhook signature failures.
17
+ - Typed Python package metadata with `py.typed` for type-aware users and tools.
18
+ - Local unit tests, optional live integration tests, examples, and GitHub CI.
pdfbolt-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PDFBolt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
pdfbolt-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,405 @@
1
+ Metadata-Version: 2.4
2
+ Name: pdfbolt
3
+ Version: 1.0.0
4
+ Summary: Official Python SDK for the PDFBolt API.
5
+ Project-URL: Homepage, https://pdfbolt.com/docs/sdks/python
6
+ Project-URL: Documentation, https://pdfbolt.com/docs
7
+ Project-URL: Website, https://pdfbolt.com
8
+ Project-URL: Repository, https://github.com/pdfbolt/pdfbolt-python
9
+ Project-URL: Issues, https://github.com/pdfbolt/pdfbolt-python/issues
10
+ Project-URL: Changelog, https://github.com/pdfbolt/pdfbolt-python/blob/main/CHANGELOG.md
11
+ Author: PDFBolt
12
+ License-Expression: MIT
13
+ License-File: LICENSE
14
+ Keywords: html-to-pdf,pdf,pdfbolt,sdk
15
+ Classifier: Development Status :: 5 - Production/Stable
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: requests<3,>=2.31
26
+ Provides-Extra: dev
27
+ Requires-Dist: build<2,>=1.2; extra == 'dev'
28
+ Requires-Dist: mypy<2,>=1.13; extra == 'dev'
29
+ Requires-Dist: pytest<10,>=9.0.3; extra == 'dev'
30
+ Requires-Dist: responses<1,>=0.25; extra == 'dev'
31
+ Requires-Dist: ruff<1,>=0.8; extra == 'dev'
32
+ Requires-Dist: twine<7,>=5; extra == 'dev'
33
+ Requires-Dist: types-requests<3,>=2.32; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # PDFBolt Python SDK
37
+
38
+ Official Python SDK for the PDFBolt API.
39
+
40
+ PDFBolt generates PDFs from HTTPS URLs, raw HTML, and published templates. See the [PDFBolt docs](https://pdfbolt.com/docs) and [OpenAPI reference](https://pdfbolt.com/docs/api-reference) for the full REST API. The SDK is typed, uses `requests`, and is intended for server-side Python applications. Typed request dictionaries and keyword options are exported for type-aware editors and static checkers.
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ pip install pdfbolt
46
+ ```
47
+
48
+ Requires Python 3.11 or newer.
49
+
50
+ ## Quick Start
51
+
52
+ ```python
53
+ import os
54
+
55
+ from pdfbolt import PDFBolt, VERSION
56
+
57
+ pdfbolt = PDFBolt(api_key=os.environ["PDFBOLT_API_KEY"])
58
+
59
+ pdf = pdfbolt.direct.from_url(
60
+ url="https://example.com",
61
+ print_background=True,
62
+ )
63
+
64
+ pdf.save("example.pdf")
65
+
66
+ print(f"Using PDFBolt SDK {VERSION}")
67
+ print(f"Saved {pdf.size} bytes")
68
+ ```
69
+
70
+ Python SDK options use `snake_case` and are mapped to PDFBolt REST API fields:
71
+
72
+ - `print_background` -> `printBackground`
73
+ - `custom_s3_presigned_url` -> `customS3PresignedUrl`
74
+ - `extra_http_headers` -> `extraHTTPHeaders`
75
+
76
+ `template_data` keys are sent unchanged, so they continue to match your template variables exactly.
77
+
78
+ ## Convert a URL to PDF
79
+
80
+ Use `from_url()` when you want PDFBolt to load an HTTPS page and render it as a PDF.
81
+
82
+ ```python
83
+ pdf = pdfbolt.direct.from_url(
84
+ url="https://example.com",
85
+ format="A4",
86
+ print_background=True,
87
+ )
88
+
89
+ pdf.save("url.pdf")
90
+ ```
91
+
92
+ ## Convert HTML to PDF
93
+
94
+ Use `from_html()` when you have raw HTML. The SDK automatically encodes it to Base64 for the API.
95
+
96
+ ```python
97
+ pdf = pdfbolt.direct.from_html(
98
+ html="<h1>Hello from PDFBolt</h1>",
99
+ format="A4",
100
+ )
101
+
102
+ pdf.save("hello.pdf")
103
+ ```
104
+
105
+ If you already have a Base64-encoded HTML string, use `convert()` directly. It returns the same `DirectConversionResult` as `from_html()`.
106
+
107
+ ```python
108
+ pdf = pdfbolt.direct.convert({
109
+ "html": "PGgxPkhlbGxvPC9oMT4="
110
+ })
111
+
112
+ pdf.save("hello.pdf")
113
+ ```
114
+
115
+ Header and footer templates work the same way: `from_url()`, `from_html()`, and `from_template()` accept raw HTML templates and automatically encode them to Base64, while `convert()` expects Base64-encoded template values.
116
+
117
+ This rule applies to all low-level `convert()` methods: `direct.convert()`, `sync.convert()`, and `async_conversions.convert()` send HTML and header/footer template values as provided.
118
+
119
+ See the [`headerTemplate`](https://pdfbolt.com/docs/parameters#headertemplate) and [`footerTemplate`](https://pdfbolt.com/docs/parameters#footertemplate) parameter docs for supported placeholders and examples.
120
+
121
+ ```python
122
+ pdf = pdfbolt.direct.from_html(
123
+ html="<!doctype html><html><body><h1>Invoice</h1></body></html>",
124
+ display_header_footer=True,
125
+ header_template='<div style="font-size:9px;width:100%;text-align:center;">Invoice</div>',
126
+ footer_template='<div style="font-size:9px;width:100%;text-align:center;">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>',
127
+ margin={
128
+ "top": "20mm",
129
+ "bottom": "20mm",
130
+ },
131
+ )
132
+
133
+ pdf.save("invoice.pdf")
134
+ ```
135
+
136
+ ## Convert a Template to PDF
137
+
138
+ Use `from_template()` with a published PDFBolt template ID and the JSON data for that template.
139
+
140
+ ```python
141
+ pdf = pdfbolt.direct.from_template(
142
+ template_id="00000000-0000-0000-0000-000000000000",
143
+ template_data={
144
+ "invoiceNumber": "INV-1001",
145
+ "customerName": "Acme Inc.",
146
+ "total": "$250.00",
147
+ },
148
+ )
149
+
150
+ pdf.save("template.pdf")
151
+ ```
152
+
153
+ `template_data` is sent as provided. The SDK does not rename keys inside your template data object.
154
+
155
+ ## Direct Results
156
+
157
+ Use `pdfbolt.direct` when you want the generated PDF returned in the HTTP response. Direct conversions return a `DirectConversionResult`.
158
+
159
+ `DirectConversionResult.buffer` always contains PDF bytes. When you pass `is_encoded=True`, PDFBolt returns Base64 text and the SDK exposes it as `DirectConversionResult.base64`. `DirectConversionResult.buffer` still contains decoded PDF bytes, so `save()` works the same way.
160
+
161
+ ```python
162
+ pdf = pdfbolt.direct.from_url(
163
+ url="https://example.com",
164
+ filename="example.pdf",
165
+ )
166
+
167
+ pdf.save("example.pdf")
168
+
169
+ print(pdf.buffer) # bytes with PDF content
170
+ print(pdf.base64) # string only when is_encoded=True, otherwise None
171
+ print(pdf.size)
172
+ print(pdf.content_type)
173
+ print(pdf.content_disposition)
174
+ print(pdf.filename)
175
+ print(pdf.conversion_cost)
176
+ print(pdf.rate_limit.minute.remaining)
177
+ print(pdf.headers.get("x-pdfbolt-conversion-cost"))
178
+ ```
179
+
180
+ Direct, Sync, Async job, and Usage results expose parsed rate-limit values through `rate_limit`. Rate-limit fields can be `None` when a response does not include the matching header. Direct results also expose raw HTTP headers through `pdf.headers`.
181
+
182
+ ## Get a Temporary URL
183
+
184
+ Use `pdfbolt.sync` when you want PDFBolt to generate the document and return a temporary download URL, valid for 24 hours.
185
+
186
+ ```python
187
+ result = pdfbolt.sync.from_url(url="https://example.com")
188
+
189
+ print(result.request_id)
190
+ print(result.status)
191
+ print(result.document_url)
192
+ print(result.expires_at)
193
+ print(result.duration)
194
+ print(result.document_size_mb)
195
+ print(result.rate_limit.minute.remaining)
196
+ print(result.conversion_cost)
197
+ ```
198
+
199
+ For custom S3 uploads, pass a valid presigned URL. PDFBolt uploads the generated PDF to your S3-compatible bucket, so `document_url` and `expires_at` are `None`. Custom S3 uploads are available on paid plans.
200
+
201
+ ```python
202
+ result = pdfbolt.sync.from_html(
203
+ html="<h1>Invoice</h1>",
204
+ custom_s3_presigned_url=os.environ["PDFBOLT_CUSTOM_S3_PRESIGNED_URL"],
205
+ )
206
+
207
+ print(result.is_custom_s3_bucket) # True
208
+ print(result.document_url) # None
209
+ ```
210
+
211
+ Presigned URLs are usually time-limited and often single-use. Generate a new one for each conversion. See [Uploading to Your S3 Bucket](https://pdfbolt.com/docs/s3-bucket-upload) for setup details.
212
+
213
+ ## Run an Async Conversion
214
+
215
+ Use `pdfbolt.async_conversions` when the conversion should run in the background. The request returns an accepted job with a `request_id` immediately, and PDFBolt sends the final success or failure payload to your HTTPS webhook later.
216
+
217
+ ```python
218
+ job = pdfbolt.async_conversions.from_url(
219
+ url="https://example.com",
220
+ webhook="https://your-app.com/webhooks/pdfbolt",
221
+ retry_delays=[5, 15, 60],
222
+ )
223
+
224
+ print(job.request_id)
225
+ print(job.rate_limit.minute.remaining)
226
+ ```
227
+
228
+ [`retryDelays`](https://pdfbolt.com/docs/api-endpoints/async#retrydelays) are in minutes and retry the conversion attempt itself, not webhook delivery.
229
+
230
+ For async custom S3 uploads, pass a valid `custom_s3_presigned_url` in the async request. After a successful upload, the final webhook has `is_custom_s3_bucket=True`, `document_url=None`, and `expires_at=None`.
231
+
232
+ ## Verify Webhook Signatures
233
+
234
+ Use the exact raw request body received from your framework. Do not parse and re-serialize JSON before verification. Supported raw body types are `str`, `bytes`, `bytearray`, and `memoryview`.
235
+
236
+ For Flask, use `request.get_data()` as the raw body. For FastAPI or Starlette, use `await request.body()`.
237
+
238
+ The `secret` value is your PDFBolt webhook signature key, not your API key.
239
+
240
+ ```python
241
+ import os
242
+
243
+ from pdfbolt import webhooks
244
+
245
+ event = webhooks.verify_and_parse(
246
+ raw_body=raw_body,
247
+ signature=request.headers.get("x-pdfbolt-signature"),
248
+ secret=os.environ["PDFBOLT_WEBHOOK_SECRET"],
249
+ )
250
+
251
+ print(event.request_id)
252
+ print(event.status)
253
+ print(event.error_code)
254
+ print(event.document_url)
255
+ ```
256
+
257
+ `verify_and_parse()` verifies the HMAC signature first and parses JSON only after the signature is valid. If you only need a boolean result, use `webhooks.verify_signature()`.
258
+
259
+ The SDK exposes webhook helpers through both `PDFBolt.webhooks` and the top-level `webhooks` export. Use whichever import style fits your codebase.
260
+
261
+ ## Error Handling
262
+
263
+ The PDFBolt API returns one common error response shape. The SDK represents API error responses with one class: `PDFBoltAPIError`. Check `status_code` for HTTP-level handling and `error_code` for PDFBolt-specific causes.
264
+
265
+ ```python
266
+ from pdfbolt import (
267
+ PDFBoltAPIError,
268
+ PDFBoltError,
269
+ PDFBoltNetworkError,
270
+ PDFBoltValidationError,
271
+ )
272
+
273
+ try:
274
+ pdfbolt.direct.from_url(url="https://example.com")
275
+ except PDFBoltValidationError as error:
276
+ print(error)
277
+ except PDFBoltAPIError as error:
278
+ print(error.status_code)
279
+ print(error.timestamp)
280
+ print(error.error_code)
281
+ print(error.error_message)
282
+ print(error.rate_limit.minute.limit)
283
+ print(error.rate_limit.minute.remaining)
284
+ print(error.raw_body)
285
+
286
+ if error.status_code == 401:
287
+ print("Check your API key.")
288
+
289
+ if error.error_code == "TOO_MANY_REQUESTS":
290
+ print(error.rate_limit.minute.remaining)
291
+ except PDFBoltNetworkError as error:
292
+ print(error)
293
+ except PDFBoltError:
294
+ raise
295
+ ```
296
+
297
+ `PDFBoltError` is the base class for all SDK errors. `PDFBoltAPIError` is thrown when the PDFBolt API returns an HTTP error response.
298
+
299
+ Exported error classes:
300
+
301
+ ```python
302
+ PDFBoltError
303
+ PDFBoltAPIError
304
+ PDFBoltNetworkError
305
+ PDFBoltWebhookSignatureError
306
+ PDFBoltValidationError
307
+ PDFBoltConfigurationError
308
+ ```
309
+
310
+ See [Error Handling](https://pdfbolt.com/docs/error-handling) for the full API error reference. These SDK-specific classes are worth calling out:
311
+
312
+ - `PDFBoltValidationError` is thrown before a request is sent when a high-level helper is called with missing or invalid SDK-side parameters.
313
+ - `PDFBoltConfigurationError` is thrown before a request is sent, for example when the API key is missing.
314
+ - `PDFBoltNetworkError` means the SDK did not receive a usable HTTP response, for example because of a network failure, timeout, or malformed success response.
315
+ - `PDFBoltWebhookSignatureError` is thrown by `verify_and_parse()` when the webhook signature or payload is invalid.
316
+
317
+ ## Advanced Client Options
318
+
319
+ ```python
320
+ import os
321
+ import requests
322
+
323
+ from pdfbolt import PDFBolt
324
+
325
+ session = requests.Session()
326
+
327
+ pdfbolt = PDFBolt(
328
+ api_key=os.environ["PDFBOLT_API_KEY"],
329
+ base_url="https://api.pdfbolt.com",
330
+ request_timeout=120.0,
331
+ session=session,
332
+ )
333
+ ```
334
+
335
+ The SDK does not automatically retry failed requests. One SDK method call sends at most one HTTP request. For async conversion retries handled by PDFBolt, use the `retry_delays` conversion parameter.
336
+
337
+ `request_timeout` is the SDK HTTP timeout in seconds. The default is `120.0`. The conversion `timeout` option is different: it is sent to the PDFBolt API in milliseconds and controls the browser render timeout for the PDF conversion, for example `timeout=30000`.
338
+
339
+ The SDK sends `User-Agent: pdfbolt-python/<version>` on requests to the PDFBolt API. This helps identify SDK traffic for support and debugging. To set headers for the page being rendered by Chromium, use the conversion `extra_http_headers` parameter.
340
+
341
+ Common conversion options such as `format`, `margin`, `print_background`, `content_disposition`, `filename`, and `compression` use Pythonic snake_case names and are mapped to the REST API request fields. See [Conversion Parameters](https://pdfbolt.com/docs/parameters) for the full parameter reference.
342
+
343
+ ## Usage
344
+
345
+ Use `pdfbolt.usage.get()` to read the current account plan, remaining conversion credits, and rate-limit metadata.
346
+
347
+ ```python
348
+ usage = pdfbolt.usage.get()
349
+
350
+ print(usage.plan)
351
+ print(usage.recurring)
352
+ print(usage.one_time)
353
+ print(usage.rate_limit.day.remaining)
354
+ ```
355
+
356
+ ## SDK Reference
357
+
358
+ Main client methods:
359
+
360
+ ```python
361
+ pdfbolt.direct.convert(...)
362
+ pdfbolt.direct.from_url(...)
363
+ pdfbolt.direct.from_html(...)
364
+ pdfbolt.direct.from_template(...)
365
+
366
+ pdfbolt.sync.convert(...)
367
+ pdfbolt.sync.from_url(...)
368
+ pdfbolt.sync.from_html(...)
369
+ pdfbolt.sync.from_template(...)
370
+
371
+ pdfbolt.async_conversions.convert(...)
372
+ pdfbolt.async_conversions.from_url(...)
373
+ pdfbolt.async_conversions.from_html(...)
374
+ pdfbolt.async_conversions.from_template(...)
375
+
376
+ pdfbolt.usage.get(...)
377
+ ```
378
+
379
+ Webhook helpers:
380
+
381
+ ```python
382
+ PDFBolt.webhooks.verify_signature(...)
383
+ PDFBolt.webhooks.verify_and_parse(...)
384
+
385
+ webhooks.verify_signature(...)
386
+ webhooks.verify_and_parse(...)
387
+ ```
388
+
389
+ Common runtime exports:
390
+
391
+ ```python
392
+ PDFBolt
393
+ DirectConversionResult
394
+ VERSION
395
+ Webhooks
396
+ webhooks
397
+ PDFBoltError
398
+ PDFBoltAPIError
399
+ PDFBoltNetworkError
400
+ PDFBoltWebhookSignatureError
401
+ PDFBoltValidationError
402
+ PDFBoltConfigurationError
403
+ ```
404
+
405
+ Typed exports are available for request dictionaries, conversion options, webhook events, result models, rate-limit metadata, cookies, margins, dimensions, and other PDFBolt API parameter types.