Official Python SDK for the PDFBolt API.
Project description
PDFBolt Python SDK
Official Python SDK for the PDFBolt API.
PDFBolt generates PDFs from HTTPS URLs, raw HTML, and published templates. See the PDFBolt docs and OpenAPI 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.
Installation
pip install pdfbolt
Requires Python 3.11 or newer.
Quick Start
import os
from pdfbolt import PDFBolt, VERSION
pdfbolt = PDFBolt(api_key=os.environ["PDFBOLT_API_KEY"])
pdf = pdfbolt.direct.from_url(
url="https://example.com",
print_background=True,
)
pdf.save("example.pdf")
print(f"Using PDFBolt SDK {VERSION}")
print(f"Saved {pdf.size} bytes")
Python SDK options use snake_case and are mapped to PDFBolt REST API fields:
print_background->printBackgroundcustom_s3_presigned_url->customS3PresignedUrlextra_http_headers->extraHTTPHeaders
template_data keys are sent unchanged, so they continue to match your template variables exactly.
Convert a URL to PDF
Use from_url() when you want PDFBolt to load an HTTPS page and render it as a PDF.
pdf = pdfbolt.direct.from_url(
url="https://example.com",
format="A4",
print_background=True,
)
pdf.save("url.pdf")
Convert HTML to PDF
Use from_html() when you have raw HTML. The SDK automatically encodes it to Base64 for the API.
pdf = pdfbolt.direct.from_html(
html="<h1>Hello from PDFBolt</h1>",
format="A4",
)
pdf.save("hello.pdf")
If you already have a Base64-encoded HTML string, use convert() directly. It returns the same DirectConversionResult as from_html().
pdf = pdfbolt.direct.convert({
"html": "PGgxPkhlbGxvPC9oMT4="
})
pdf.save("hello.pdf")
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.
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.
See the headerTemplate and footerTemplate parameter docs for supported placeholders and examples.
pdf = pdfbolt.direct.from_html(
html="<!doctype html><html><body><h1>Invoice</h1></body></html>",
display_header_footer=True,
header_template='<div style="font-size:9px;width:100%;text-align:center;">Invoice</div>',
footer_template='<div style="font-size:9px;width:100%;text-align:center;">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>',
margin={
"top": "20mm",
"bottom": "20mm",
},
)
pdf.save("invoice.pdf")
Convert a Template to PDF
Use from_template() with a published PDFBolt template ID and the JSON data for that template.
pdf = pdfbolt.direct.from_template(
template_id="00000000-0000-0000-0000-000000000000",
template_data={
"invoiceNumber": "INV-1001",
"customerName": "Acme Inc.",
"total": "$250.00",
},
)
pdf.save("template.pdf")
template_data is sent as provided. The SDK does not rename keys inside your template data object.
Direct Results
Use pdfbolt.direct when you want the generated PDF returned in the HTTP response. Direct conversions return a DirectConversionResult.
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.
pdf = pdfbolt.direct.from_url(
url="https://example.com",
filename="example.pdf",
)
pdf.save("example.pdf")
print(pdf.buffer) # bytes with PDF content
print(pdf.base64) # string only when is_encoded=True, otherwise None
print(pdf.size)
print(pdf.content_type)
print(pdf.content_disposition)
print(pdf.filename)
print(pdf.conversion_cost)
print(pdf.rate_limit.minute.remaining)
print(pdf.headers.get("x-pdfbolt-conversion-cost"))
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.
Get a Temporary URL
Use pdfbolt.sync when you want PDFBolt to generate the document and return a temporary download URL, valid for 24 hours.
result = pdfbolt.sync.from_url(url="https://example.com")
print(result.request_id)
print(result.status)
print(result.document_url)
print(result.expires_at)
print(result.duration)
print(result.document_size_mb)
print(result.rate_limit.minute.remaining)
print(result.conversion_cost)
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.
result = pdfbolt.sync.from_html(
html="<h1>Invoice</h1>",
custom_s3_presigned_url=os.environ["PDFBOLT_CUSTOM_S3_PRESIGNED_URL"],
)
print(result.is_custom_s3_bucket) # True
print(result.document_url) # None
Presigned URLs are usually time-limited and often single-use. Generate a new one for each conversion. See Uploading to Your S3 Bucket for setup details.
Run an Async Conversion
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.
job = pdfbolt.async_conversions.from_url(
url="https://example.com",
webhook="https://your-app.com/webhooks/pdfbolt",
retry_delays=[5, 15, 60],
)
print(job.request_id)
print(job.rate_limit.minute.remaining)
retryDelays are in minutes and retry the conversion attempt itself, not webhook delivery.
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.
Verify Webhook Signatures
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.
For Flask, use request.get_data() as the raw body. For FastAPI or Starlette, use await request.body().
The secret value is your PDFBolt webhook signature key, not your API key.
import os
from pdfbolt import webhooks
event = webhooks.verify_and_parse(
raw_body=raw_body,
signature=request.headers.get("x-pdfbolt-signature"),
secret=os.environ["PDFBOLT_WEBHOOK_SECRET"],
)
print(event.request_id)
print(event.status)
print(event.error_code)
print(event.document_url)
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().
The SDK exposes webhook helpers through both PDFBolt.webhooks and the top-level webhooks export. Use whichever import style fits your codebase.
Error Handling
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.
from pdfbolt import (
PDFBoltAPIError,
PDFBoltError,
PDFBoltNetworkError,
PDFBoltValidationError,
)
try:
pdfbolt.direct.from_url(url="https://example.com")
except PDFBoltValidationError as error:
print(error)
except PDFBoltAPIError as error:
print(error.status_code)
print(error.timestamp)
print(error.error_code)
print(error.error_message)
print(error.rate_limit.minute.limit)
print(error.rate_limit.minute.remaining)
print(error.raw_body)
if error.status_code == 401:
print("Check your API key.")
if error.error_code == "TOO_MANY_REQUESTS":
print(error.rate_limit.minute.remaining)
except PDFBoltNetworkError as error:
print(error)
except PDFBoltError:
raise
PDFBoltError is the base class for all SDK errors. PDFBoltAPIError is thrown when the PDFBolt API returns an HTTP error response.
Exported error classes:
PDFBoltError
PDFBoltAPIError
PDFBoltNetworkError
PDFBoltWebhookSignatureError
PDFBoltValidationError
PDFBoltConfigurationError
See Error Handling for the full API error reference. These SDK-specific classes are worth calling out:
PDFBoltValidationErroris thrown before a request is sent when a high-level helper is called with missing or invalid SDK-side parameters.PDFBoltConfigurationErroris thrown before a request is sent, for example when the API key is missing.PDFBoltNetworkErrormeans the SDK did not receive a usable HTTP response, for example because of a network failure, timeout, or malformed success response.PDFBoltWebhookSignatureErroris thrown byverify_and_parse()when the webhook signature or payload is invalid.
Advanced Client Options
import os
import requests
from pdfbolt import PDFBolt
session = requests.Session()
pdfbolt = PDFBolt(
api_key=os.environ["PDFBOLT_API_KEY"],
base_url="https://api.pdfbolt.com",
request_timeout=120.0,
session=session,
)
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.
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.
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.
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 for the full parameter reference.
Usage
Use pdfbolt.usage.get() to read the current account plan, remaining conversion credits, and rate-limit metadata.
usage = pdfbolt.usage.get()
print(usage.plan)
print(usage.recurring)
print(usage.one_time)
print(usage.rate_limit.day.remaining)
SDK Reference
Main client methods:
pdfbolt.direct.convert(...)
pdfbolt.direct.from_url(...)
pdfbolt.direct.from_html(...)
pdfbolt.direct.from_template(...)
pdfbolt.sync.convert(...)
pdfbolt.sync.from_url(...)
pdfbolt.sync.from_html(...)
pdfbolt.sync.from_template(...)
pdfbolt.async_conversions.convert(...)
pdfbolt.async_conversions.from_url(...)
pdfbolt.async_conversions.from_html(...)
pdfbolt.async_conversions.from_template(...)
pdfbolt.usage.get(...)
Webhook helpers:
PDFBolt.webhooks.verify_signature(...)
PDFBolt.webhooks.verify_and_parse(...)
webhooks.verify_signature(...)
webhooks.verify_and_parse(...)
Common runtime exports:
PDFBolt
DirectConversionResult
VERSION
Webhooks
webhooks
PDFBoltError
PDFBoltAPIError
PDFBoltNetworkError
PDFBoltWebhookSignatureError
PDFBoltValidationError
PDFBoltConfigurationError
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pdfbolt-1.0.0.tar.gz.
File metadata
- Download URL: pdfbolt-1.0.0.tar.gz
- Upload date:
- Size: 24.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc1466d7b1eb14fbbf12b0bfe7d3b3b71a4fe2d136163daf5859614171e986a6
|
|
| MD5 |
cb0b8b5ad6c6c8ea3c45eb5aa5ef0833
|
|
| BLAKE2b-256 |
b47340b0a6e3f4d456f4fe7fd815cce95e104c8cb564df36ea5b09bd18fab506
|
File details
Details for the file pdfbolt-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pdfbolt-1.0.0-py3-none-any.whl
- Upload date:
- Size: 20.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
228ee92d38c4a7e7913b652fddd55fa57631236908fe42e645a8ecda5baa590d
|
|
| MD5 |
7c359c239d0b9b7c572b2335400ede91
|
|
| BLAKE2b-256 |
25b77df560abdeaa750dfb25e304e6a582b6c5b0368640a8038dc78455d360c2
|