typefold-client
Python client for the Typefold API. Needs Python 3.10 or later; its only dependency is
httpx. It has a blocking TypefoldClient and an asyncio AsyncTypefoldClient with the
same methods.
pip install typefold-client
Create one client per API key and reuse it. The key needs render:create, render:read and
template:read, and render:cancel to cancel renders.
from typefold import TypefoldClient
client = TypefoldClient("https://pdf.example.com", api_key)
Close it with client.close() when your application stops, or use it as a context manager.
Render a report
render_report renders a published report or saved template by name or ID and returns the PDF
or XLSX bytes:
from typefold import (
Orientation,
PageSize,
PdfMetadata,
RenderReportRequest,
ReportFormat,
ReportPdfOptions,
TemplateRef,
)
pdf = client.render_report(
RenderReportRequest(
template=TemplateRef.by_name("SoldGoodsForWarehouseReportPdf"),
data={"Data": {"reportRows": report_rows, "summaryRows": summary_rows}},
pdf=ReportPdfOptions(
page_size=PageSize.A4,
orientation=Orientation.LANDSCAPE,
metadata=PdfMetadata(title="Sold goods, week 39"),
),
)
)
xlsx = client.render_report(
RenderReportRequest(
format=ReportFormat.XLSX,
template=TemplateRef.by_name("SoldGoodsForWarehouseReportXlsx"),
data=data,
)
)
data is sent as written: dictionary keys keep their names, and dates, decimals, UUIDs and
dataclasses are written as JSON.
Templates imported from jsreport keep their shortids, so stored shortids still work:
TemplateRef.by_shortid("rkJTnK2ce"). list_reports returns each template's shortid.
A retry with the same idempotency_key returns the render the key already created.
get_report_data_schema returns the JSON Schema of a report's data; list_reports lists
templates and the formats each renders.
Render notification text
render_string renders a template string synchronously, without a PDF, for email bodies,
subjects, SMS and push messages. The Handlebars engine runs #if, #each and your helpers:
from typefold import RenderStringRequest, StringEngine, StringFormat
body = client.render_string(
RenderStringRequest(
template="{{#if (isEqual Status 'paid')}}Paid{{else}}Due{{/if}}: {{Booking.Code}}",
data=model,
engine=StringEngine.HANDLEBARS,
helpers="function isEqual(a, b) { return a === b; }",
format=StringFormat.HTML,
)
)
StringFormat.HTML escapes values; StringFormat.TEXT (the default) writes them as they are.
Without engine, only {{path}} placeholders are replaced.
Render HTML or a template version
render creates a render, waits for it and downloads the PDF:
from typefold import DirectRenderRequest, HtmlDocument, PageSize, RenderSettings, TemplateVersionRenderRequest
pdf = client.render(
DirectRenderRequest(
document=HtmlDocument(html="<h1>Invoice 42</h1>"),
settings=RenderSettings(page_size=PageSize.A4),
)
)
ticket = client.render(
TemplateVersionRenderRequest(template_version_id=version_id, data={"ticket": {"number": "TK-1"}})
)
It gives up after two minutes unless you pass a timeout in seconds. To render in the
background, use create_render, then wait_for_render, download or cancel_render, or the
API's render webhooks.
Render a batch
create_batch creates up to 100 renders in one request; if any item is invalid, none is created.
Items are DirectRenderRequest or TemplateVersionRenderRequest; their wait_ms is not sent.
wait_for_batch polls until no item is queued or processing (10 minutes unless you pass a
timeout), and download_batch returns one PDF of every item in order:
batch = client.create_batch(
[TemplateVersionRenderRequest(template_version_id=version_id, data=ticket) for ticket in tickets],
idempotency_key="tickets-2026-10-12",
)
batch = client.wait_for_batch(batch)
if batch.counts.succeeded == batch.total:
pdf = client.download_batch(batch.id)
A failed item does not stop the others; batch.items gives each render's id and state, to
read, download or cancel it as a single render. get_batch reads a batch again.
Async
AsyncTypefoldClient has the same methods as coroutines:
from typefold import AsyncTypefoldClient
async with AsyncTypefoldClient("https://pdf.example.com", api_key) as client:
pdf = await client.render_report(request)
Errors
A request the API refuses with 429 RATE_LIMITED, such as a burst of parallel renders, is sent
again after its Retry-After up to max_rate_limit_retries times (3 by default; pass 0 to turn
this off). Other failures raise TypefoldError. error.code is the API's code, such as
NOT_FOUND, RATE_LIMITED or RENDER_TIMEOUT, and error.retryable says whether a retry can
help. When a render was created but failed or timed out, error.error.render_id names it.
Versions
Use a client no newer than your server: older clients keep working because /v1 only grows,
but a newer client's fields or endpoints answer 400 or 404 on an older server.
httpx client
To share an httpx.Client (or httpx.AsyncClient), pass it as http_client with a timeout
above 95 seconds, the longest a report PDF can take. The API key goes on each request, not the
client, and never to download URLs. A client you pass in is not closed with the
TypefoldClient.
Development
cd clients/python
python -m venv .venv && .venv/bin/pip install -e '.[test]'
.venv/bin/pytest && .venv/bin/mypy src tests && .venv/bin/ruff check . && .venv/bin/ruff format --check .
Metadata
Release files for typefold-client 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| typefold_client-0.2.1.tar.gz | 19.7 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| typefold_client-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.2 kB
Release files / typefold_client-0.2.1.tar.gz
| Download URL | typefold_client-0.2.1.tar.gz |
|---|---|
| Size | 19.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c8aee1ec9ed5dc0460bace1e22f25cf6ed5ebad8f31c9ee94c7fbb1cf0a9f297
|
|
BLAKE2b-256 checksum How to use checksums |
c5259a09991805f26e4fd9fc1bbcff1b3a41863a2c465a673152cf781f9c2432
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / typefold_client-0.2.1-py3-none-any.whl
| Download URL | typefold_client-0.2.1-py3-none-any.whl |
|---|---|
| Size | 16.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1a571412dbc37bca1973d40865d4a80bf980bb895a57020a53ab0121c8a5c809
|
|
BLAKE2b-256 checksum How to use checksums |
01b0b0508eaee065bfac1d5e698e578906b9f6c5f693a751ab9fc66ca26949d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logSecurity for typefold-client 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for typefold_client-0.2.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.