Skip to main content

formepdf

Python SDK for Forme — the page-native PDF rendering engine. Two ways to use it:

  1. API client — calls the hosted API at api.formepdf.com (requires API key)
  2. Local rendering — runs the WASM engine locally via wasmtime (no API key needed)

Installation

# API client only (zero dependencies)
pip install formepdf

# Local rendering with component DSL (adds wasmtime)
pip install formepdf[local]

API Client

Setup

from formepdf import Forme

client = Forme("forme_sk_...")

Render

Render a template (created in the dashboard) with data:

pdf = client.render("invoice", {"customer": "Acme", "total": 245})

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

Async render

job = client.render_async("report", data, webhook_url="https://example.com/hook")

result = client.get_job(job["jobId"])
if result["status"] == "complete":
    pdf_b64 = result["pdfBase64"]

Certify

Apply a PKCS#7 digital signature to an existing PDF:

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

certified = client.certify(
    pdf,
    certificate=open("cert.pem").read(),
    private_key=open("key.pem").read(),
    reason="Approved",
    location="New York",
)

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

Or use a saved certificate on the hosted API:

certified = client.certify(pdf, certificate_id="cert_abc123")

Redact

Remove sensitive content from a PDF — true redaction (text operators removed, not just covered):

# By text pattern
redacted = client.redact(pdf, patterns=[
    {"pattern": "Jane Doe", "pattern_type": "Literal"},
    {"pattern": r"\d{3}-\d{2}-\d{4}", "pattern_type": "Regex"},
])

# By built-in presets
redacted = client.redact(pdf, presets=["ssn", "email", "phone"])

# By coordinate regions
redacted = client.redact(pdf, redactions=[
    {"page": 0, "x": 100, "y": 200, "width": 150, "height": 20},
])

# By saved redaction template
redacted = client.redact(pdf, template="hipaa-patient-record")

Merge

Combine multiple PDFs into one:

merged = client.merge([pdf1_bytes, pdf2_bytes, pdf3_bytes])

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

Extract embedded data

data = client.extract(pdf)  # returns dict or None

Error handling

from formepdf import Forme, FormeError

try:
    pdf = client.render("invoice", data)
except FormeError as e:
    print(f"Error {e.status}: {e.message}")

Local Rendering (WASM)

Build PDF documents in Python with a component DSL that mirrors the JSX API. Renders locally via the WASM engine — no API key or network calls needed.

Basic example

from formepdf import Document, Page, View, Text, Image

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()

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

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")

Certify locally

from formepdf.wasm import certify_pdf

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

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

certified = certify_pdf(pdf, config)

Requirements

  • Python 3.8+
  • No external dependencies for the API client (stdlib only)
  • wasmtime for local rendering (pip install formepdf[local])

Metadata

Release files for formepdf 0.15.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.15.0
File Size Uploaded
formepdf-0.15.0.tar.gz 2.6 MB Details

Built distribution (wheel)

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

Total release size: 5.3 MB

Release files / formepdf-0.15.0.tar.gz

Download URL formepdf-0.15.0.tar.gz
Size 2.6 MB
Tags Source
SHA-256 checksum
How to use checksums
04429617ba63932a89eb123cc9aae7ac201a6e5459994ab8018d18673b05776b
BLAKE2b-256 checksum
How to use checksums
0433d93cfb2ce5eff84e3cbf3428f91d2052357740b8857a02f5dc1aaab67589
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.15.0-py3-none-any.whl

Download URL formepdf-0.15.0-py3-none-any.whl
Size 2.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
a9339f3b694f3a246c6735ad5a8606f34424ec0092af01ed3242f3aecff741fd
BLAKE2b-256 checksum
How to use checksums
b78ddb748cab366bd141b6b17c519efbedf5a3fdbaa455a14bdcf83cc465cb2d
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

0.25.0

2 release files

0.24.0

2 release files

0.23.0

2 release files

0.22.0

2 release files

This release

0.15.0 This release

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