Skip to main content

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 -> printBackground
  • custom_s3_presigned_url -> customS3PresignedUrl
  • extra_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:

  • PDFBoltValidationError is thrown before a request is sent when a high-level helper is called with missing or invalid SDK-side parameters.
  • PDFBoltConfigurationError is thrown before a request is sent, for example when the API key is missing.
  • PDFBoltNetworkError means the SDK did not receive a usable HTTP response, for example because of a network failure, timeout, or malformed success response.
  • PDFBoltWebhookSignatureError is thrown by verify_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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pdfbolt-1.0.0.tar.gz (24.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pdfbolt-1.0.0-py3-none-any.whl (20.9 kB view details)

Uploaded Python 3

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

Hashes for pdfbolt-1.0.0.tar.gz
Algorithm Hash digest
SHA256 cc1466d7b1eb14fbbf12b0bfe7d3b3b71a4fe2d136163daf5859614171e986a6
MD5 cb0b8b5ad6c6c8ea3c45eb5aa5ef0833
BLAKE2b-256 b47340b0a6e3f4d456f4fe7fd815cce95e104c8cb564df36ea5b09bd18fab506

See more details on using hashes here.

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

Hashes for pdfbolt-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 228ee92d38c4a7e7913b652fddd55fa57631236908fe42e645a8ecda5baa590d
MD5 7c359c239d0b9b7c572b2335400ede91
BLAKE2b-256 25b77df560abdeaa750dfb25e304e6a582b6c5b0368640a8038dc78455d360c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page