Skip to main content

formepdf

Python SDK for Forme — a page-native PDF rendering engine. Build documents from a component DSL and render them to PDF locally, in-process, with no browser, no headless Chromium, and no system libraries — the engine ships as a single WebAssembly module and runs anywhere Python runs (including serverless).

  • Local rendering via wasmtime — no API key, no network calls.
  • Real print features — flexbox layout, tables with headers that repeat across pages, fixed headers/footers, page breaks, watermarks.
  • Accessible & archival — tagged PDF, PDF/UA-1, and PDF/A produced locally, the same conformance the engine gives everywhere.
  • Charts, QR codes, barcodes, and fillable form fields built in.
  • Local digital signing (PKCS#7 / X.509).

Installation

pip install formepdf[local]

The [local] extra adds wasmtime; the engine WASM is bundled in the wheel. That's all you need — no cairo, no pango, no fonts to install.

Quick start

from formepdf import Document, Page, View, Text

doc = Document(
    Page(
        View(
            Text("Invoice #001", font_size=24, font_weight="bold"),
            Text("Acme Corp", font_size=14, color="#666"),
            flex_direction="column", gap=8,
        ),
    ),
    title="Invoice #001",
)

pdf = doc.render()               # -> bytes

with open("invoice.pdf", "wb") as f:
    f.write(pdf)

Accessible & archival output

The conformance options live on Document — no extra pipeline, no external validator step to produce them:

doc = Document(
    Page(Text("Annual Report 2026", font_size=20)),
    title="Annual Report 2026",
    lang="en",
    tagged=True,     # structure tree (BDC/EMC marked content)
    pdf_ua=True,     # PDF/UA-1 (accessibility)
    pdfa="2b",       # PDF/A-2b (archival); also "2u", "2a", "3b", "3u", "3a"
)
pdf = doc.render()

Document options: title, author, subject, lang, tagged, pdf_ua, pdfa, flatten_forms.

Components

Component Description
Document(*children) Root container. .render() returns PDF bytes. Options: title, author, subject, lang, tagged, pdf_ua, pdfa, flatten_forms
Page(*children) Page container. Options: size (e.g. "A4", "Letter"), margin
View(*children) Flex/grid container. Options: all style kwargs (flex_direction, gap, padding, etc.)
Text(content) Text element. Options: font_size, font_weight, color, text_align, etc.
Image(src) Image (file path, URL, or data URI). Options: width, height, alt
Table(*rows) Table with auto-repeating headers. Options: columns
Row(*cells) Table row. Options: header=True for repeat-on-page-break
Cell(*children) Table cell. Options: col_span, row_span
Svg(content) Inline SVG. Options: width, height
QrCode(data) Vector QR code. Options: size, color
Barcode(data) 1D barcode. Options: format ("Code128", "Code39", "EAN13", etc.), width, height
BarChart(data) Bar chart. Options: width, height, color, title
LineChart(series, labels) Line chart. Options: width, height, show_points, title
PieChart(data) Pie/donut chart. Options: width, height, donut, title
AreaChart(series, labels) Area chart. Options: width, height, title
DotPlot(groups) Scatter plot. Options: width, height, title
TextField(name) Fillable text field. Options: value, placeholder, multiline
Checkbox(name) Fillable checkbox. Options: checked
Dropdown(name, options) Fillable dropdown. Options: value
RadioButton(name, value) Radio button. Options: checked
Watermark(text) Rotated watermark. Options: font_size, color, angle
PageBreak() Force a page break
Fixed(*children) Fixed-position element. Options: position ("header", "footer")

Local digital signing

Apply a PKCS#7 / X.509 signature to an existing PDF, offline:

import json
from formepdf.wasm import certify_pdf

with open("document.pdf", "rb") as f:
    pdf = f.read()

config = json.dumps({
    "certificate_pem": open("cert.pem").read(),
    "private_key_pem": open("key.pem").read(),
    "reason": "Approved",
})

certified = certify_pdf(pdf, config)

Self-hosted render server (optional)

The package also ships a thin HTTP client, Forme, for a self-hosted Forme render server — the public hosted API has been retired, so point base_url at your own deployment. It exposes server-side operations the local WASM engine doesn't: render stored templates by slug (render / render_async / get_job), true redaction (redact), merge, rasterize, and extract.

from formepdf import Forme

client = Forme("forme_sk_...", base_url="https://pdf.your-company.com")
pdf = client.render("invoice", {"customer": "Acme", "total": 245})

Requirements

  • Python 3.8+
  • wasmtime for local rendering (pip install formepdf[local])
  • No system libraries, no browser.

Metadata

Release files for formepdf 0.25.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for formepdf 0.25.0
File Size Uploaded
formepdf-0.25.0.tar.gz 2.9 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for formepdf 0.25.0
File Interpreter ABI Platform
formepdf-0.25.0-py3-none-any.whl Python 3 none any Details

Total release size: 5.8 MB

Release files / formepdf-0.25.0.tar.gz

Download URL formepdf-0.25.0.tar.gz
Size 2.9 MB
Tags Source
SHA-256 checksum
How to use checksums
cda1f397112a3bc960486f4d4c1898e27de21229a14fc53e1603aa1438c53667
BLAKE2b-256 checksum
How to use checksums
5ccfc157026b285a6d120f6408fd6b93a5bd5516c7122f87ccc7b68ebe4569be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.12

Release files / formepdf-0.25.0-py3-none-any.whl

Download URL formepdf-0.25.0-py3-none-any.whl
Size 2.9 MB
Tags Python 3
SHA-256 checksum
How to use checksums
ee2916b8dc520193237431ddbe89c60c11a261ca2d3c9dee42dabc68f2fd2f41
BLAKE2b-256 checksum
How to use checksums
7bd20beb292352f77074031710049e7809a0ab22b3dcc65b1c5d04fdc35fe7f0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.12

Release history Release notifications | RSS feed

This release

0.25.0 This release

2 release files

0.24.0

2 release files

0.23.0

2 release files

0.22.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.10.3

2 release files

0.10.2

2 release files

0.10.0

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.13

2 release files

0.7.12

2 release files

0.7.11

2 release files

0.7.10

2 release files

0.7.9

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page