Skip to content

Generate PDF invoices in Python without a headless browser

Native PDF compilation for FastAPI, Django, or any Python service. Design documents as Typst templates, pass JSON, and get print-ready PDFs back in milliseconds.

Python teams generating PDFs usually pick between a headless browser, HTML-to-PDF engines that fight page breaks and fonts, or low-level libraries that turn every layout into code. The abandoned wkhtmltopdf still shows up in production stacks.

Oicana compiles PDFs in process through native bindings instead. Install with pip install oicana, load a packed template once, and compile documents from JSON:

import json
from pathlib import Path
from oicana import Template
template_bytes = Path("invoice-0.1.0.zip").read_bytes()
with Template(template_bytes) as template:
pdf = template.export(
json_inputs={"invoice": json.dumps({
"number": "2026-001",
"customer": "Acme GmbH",
"total": "€1,190.00",
})},
)

A warmed up template produces a print-ready PDF in single digit milliseconds, directly in your service.

The snippet loads invoice-0.1.0.zip, a packed Oicana template. Templates are plain Typst projects: a typst.toml manifest declares a JSON input named invoice, and main.typ uses it:

main.typ
#import "@preview/oicana:0.2.0": setup
#let read-project-file(path) = read(path, encoding: none)
#let (input, oicana-image, oicana-config) = setup(read-project-file)
#set document(date: datetime.today())
= Invoice #input.invoice.number
Billed to: #input.invoice.customer
*Total: #input.invoice.total*

Running oicana pack in the template directory produces the zip. Create a Template walks through the manifest and input definitions, and the open source example templates include a complete invoice.

Load the template once at startup and compile per request. The compilation runs in native code, so a couple of milliseconds per document is the norm. Oicana releases the GIL while it compiles and exports, so multiple threads compile in parallel. For heavy load, you can combine that with multiple worker processes behind Gunicorn or another server.

The FastAPI example project shows a complete service, including blob inputs and error handling.

No headless browser

Native extensions compile PDFs inside your service. No headless Chrome to deploy, no fragile wkhtmltopdf binary to maintain.

Your data stays with you

Documents are generated inside your own service. No customer data is sent to a third party, which keeps GDPR and HIPAA compliance in your hands.

Flat price, unlimited documents

One flat license per application, no metering. A hundred invoices a month cost the same as a hundred thousand. Non-commercial use is free.