Official Python SDK for the Doclinth PDF generation API
Project description
doclinth
Official Python SDK for the Doclinth PDF generation API. Sync and async clients, Pydantic models, automatic retries with safe idempotency, and webhook signature verification.
Install
pip install doclinth
Requires Python 3.10+.
Quickstart
from doclinth import Doclinth
client = Doclinth(
api_key="dl_live_…", # or dl_test_…
base_url="https://doclinth.com", # or set DOCLINTH_BASE_URL
)
# Binary (default) — returns the PDF bytes.
pdf = client.generate(
template_id="b1c2d3e4-…",
data={"invoice_number": "INV-1042", "total": 2592},
)
with open("invoice.pdf", "wb") as f:
f.write(pdf)
# Signed URL — returns UrlResult(url=…, expires_at=…).
result = client.generate(
template_id="b1c2d3e4-…",
data={"total": 2592},
output="url",
)
print(result.url, result.expires_at)
# Async delivery — returns QueuedGeneration; result POSTed to webhook_url.
queued = client.generate(
template_id="b1c2d3e4-…",
data={"total": 2592},
webhook_url="https://hooks.example.com/doclinth",
)
print(queued.generation_id) # poll with client.wait_for_generation(...)
Use the client as a context manager so the underlying HTTP pool is closed:
with Doclinth(api_key="…", base_url="https://doclinth.com") as client:
pdf = client.generate(template_id="…", data={})
Async
import asyncio
from doclinth import AsyncDoclinth
async def main() -> None:
async with AsyncDoclinth(
api_key="dl_live_…",
base_url="https://doclinth.com",
) as client:
pdf = await client.generate(
template_id="b1c2d3e4-…",
data={"invoice_number": "INV-1042"},
)
open("invoice.pdf", "wb").write(pdf)
asyncio.run(main())
Templates & generations
# List your templates.
templates = client.templates.list()
# Learn the data contract before you render.
detail = client.templates.get(templates[0].id)
detail.variables # ["customer.name", "items", "total", …]
detail.sample_data
# AI-author a new draft template (consumes monthly AI allowance).
created = client.templates.create(
prompt="A packing slip with order number, ship-to, and line items",
quality="fast",
)
# Generation status (by X-Request-Id / generation_id).
status = client.generations.get("req_…")
status.status # "success" | "error"
# Poll until an async generation finishes (404 generation_not_found = still pending).
status = client.wait_for_generation("gen_…", timeout=120.0)
Webhook verification
When you pass webhook_url, Doclinth POSTs the signed result with header
X-Doclinth-Signature: sha256=<hex>.
from doclinth import WEBHOOK_SIGNATURE_HEADER, verify_webhook
def handle(raw_body: bytes, headers: dict[str, str], secret: str) -> bool:
signature = headers.get(WEBHOOK_SIGNATURE_HEADER, "")
return verify_webhook(raw_body, signature, secret)
Retries & idempotency
By default the client retries 429 and 5xx responses (and network errors) up
to twice with exponential backoff, honoring Retry-After. To make those retries
safe, generate attaches an Idempotency-Key automatically — so a retried
request can never generate (or bill) a second PDF. Provide your own key to
dedupe across process restarts:
client.generate(template_id="…", data=data, idempotency_key=order_id)
Set max_retries=0 to disable retries (and the automatic key).
templates.create is non-idempotent and AI-metered, so it only retries a
pre-work 429, never a 5xx — a dropped response never risks a duplicate
(billed) template.
Errors
Non-2xx responses raise DoclinthError with a stable code and status:
from doclinth import Doclinth, DoclinthError
try:
client.generate(template_id=template_id, data=data)
except DoclinthError as e:
if e.code == "quota_exceeded":
... # prompt an upgrade
raise
wait_for_generation raises DoclinthTimeoutError (a DoclinthError subclass)
when the deadline is exceeded.
See the error reference for all codes.
License
MIT
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 doclinth-0.1.0.tar.gz.
File metadata
- Download URL: doclinth-0.1.0.tar.gz
- Upload date:
- Size: 14.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1baac6add4536cec7d1f484d9798522009b51c7f3d41307474d74556a6067f27
|
|
| MD5 |
bec34d4f78a5d871c57428d11b5fe250
|
|
| BLAKE2b-256 |
51cc5520abed27c8b32d18b46b2ebc079c7dee852a2f69d13f4dcc2734dd96cb
|
Provenance
The following attestation bundles were made for doclinth-0.1.0.tar.gz:
Publisher:
publish.yml on Doclinth/doclinth-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
doclinth-0.1.0.tar.gz -
Subject digest:
1baac6add4536cec7d1f484d9798522009b51c7f3d41307474d74556a6067f27 - Sigstore transparency entry: 2138578752
- Sigstore integration time:
-
Permalink:
Doclinth/doclinth-python@b8e0244c062dbe3337cd3304f6c94c1c1c1335a2 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Doclinth
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b8e0244c062dbe3337cd3304f6c94c1c1c1335a2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file doclinth-0.1.0-py3-none-any.whl.
File metadata
- Download URL: doclinth-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06e70cfc41924e59a0bf551b2a931ca4244ceffed75a45ac86ea435ce2d57ae4
|
|
| MD5 |
344f0cd4321a6bdd0760bcc21157a804
|
|
| BLAKE2b-256 |
a693e4495ad5543f73d6cc03ad570350b76b2682f8c835c5945059d1ab81f928
|
Provenance
The following attestation bundles were made for doclinth-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on Doclinth/doclinth-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
doclinth-0.1.0-py3-none-any.whl -
Subject digest:
06e70cfc41924e59a0bf551b2a931ca4244ceffed75a45ac86ea435ce2d57ae4 - Sigstore transparency entry: 2138578763
- Sigstore integration time:
-
Permalink:
Doclinth/doclinth-python@b8e0244c062dbe3337cd3304f6c94c1c1c1335a2 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Doclinth
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b8e0244c062dbe3337cd3304f6c94c1c1c1335a2 -
Trigger Event:
push
-
Statement type: