Skip to main content

Ferri PDF for Python

An HTML and CSS to PDF renderer for print, written in pure Rust. No browser and no JavaScript.

pip install ferri-pdf

Wheels are prebuilt for CPython 3.10 and later on Linux, macOS and Windows.

Rendering

import ferri_pdf

output = ferri_pdf.render("<h1>Hello</h1>")
with open("hello.pdf", "wb") as file:
    file.write(output.pdf)

render takes a str, or bytes decoded by the HTML encoding rules. It returns the PDF bytes, page_count, the located headings and the diagnostics for recovered input. Invalid markup, unsupported CSS and missing resources never raise; they are recovered as the specifications say and listed in diagnostics.

The interpreter lock is released while rendering, so threads render in parallel.

Options

options = ferri_pdf.RenderOptions(
    base="templates/invoice",
    stylesheets=["@page { size: A4; margin: 2cm }"],
    serif=["Georgia"],
    jpeg_quality=85,
    image_dpi=150,
    allow_http=False,
)
output = ferri_pdf.render(html, options)
Option Effect
base Directory that relative URLs resolve against (default: the working directory)
base_url Document URL that relative URLs resolve against, instead of base
stylesheets Author stylesheets applied after the document's own
user_stylesheets User-origin stylesheets
paper Paper size (width, height) in points when CSS sets none (default: A4)
color_scheme "light" or "dark" for prefers-color-scheme
contrast "no-preference", "less", "more" or "custom" for prefers-contrast
reduced_motion "no-preference" or "reduce" for prefers-reduced-motion
serif, sans_serif, monospace Installed families for each generic font
fallback Installed families tried for missing glyphs
image_dpi Downsample raster images to this resolution
jpeg_quality Re-encode opaque photos as JPEG at this quality, 1 to 100
include_layout Return the measured layout as output.layout
allow_content_loss Return the PDF even when a resource limit left content out
allow_http Fetch HTTP(S) resources with the built-in client (default: True)
file_root Refuse local files outside this directory
fetch Callable that loads every URL other than local files and data URLs

Rendering untrusted HTML? Set allow_http=False and file_root so a document cannot reach your network or read files outside its own assets, or route requests through fetch and decide there.

Fetching resources yourself

fetch receives each absolute URL that is not a file: or data: URL: HTTP(S), and any scheme your base_url uses, such as app://. It replaces the built-in HTTP client. Return the body as bytes, a ferri_pdf.Resource to add a content type or the final URL after redirects, or None when the resource is unavailable.

import httpx
import ferri_pdf

client = httpx.Client(headers={"Authorization": f"Bearer {token}"}, timeout=10)

def fetch(url: str) -> ferri_pdf.Resource | None:
    if not url.startswith("https://assets.example.com/"):
        return None
    response = client.get(url, follow_redirects=True)
    response.raise_for_status()
    return ferri_pdf.Resource(
        response.content,
        content_type=response.headers.get("content-type"),
        url=str(response.url),
    )

output = ferri_pdf.render(html, ferri_pdf.RenderOptions(fetch=fetch))

Relative URLs inside a fetched resource resolve against its url. An Exception raised by fetch, like None, leaves that resource unavailable and is reported in diagnostics; rendering carries on. KeyboardInterrupt, SystemExit and a return value of the wrong type stop further fetches and are raised from render. Local files still load from disk, within file_root when set.

Several documents in one PDF

output = ferri_pdf.render_parts([
    ferri_pdf.Part(cover_html, base="cover"),
    ferri_pdf.Part(body_html, base="body"),
])
for part in output.parts:
    print(part.first_page, part.page_count)

Each part starts on a new page. Parts can also be plain str or bytes, which use the options' base.

Errors

ferri_pdf.RenderError is raised when rendering fails. Its subclass ferri_pdf.ContentLostError is raised when a resource limit left content out of the PDF; its diagnostics list the losses and part names the one-based part of a multipart render. Pass allow_content_loss=True to get the PDF anyway. Invalid option values raise ValueError.

Licence

MIT. The bundled fonts, hyphenation patterns and specification data keep their own licences; see the repository.

Metadata

Release files for ferri-pdf 0.1.7

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

Source distribution (sdist)

Source distribution for ferri-pdf 0.1.7
File Size Uploaded Provenance Actions
ferri_pdf-0.1.7.tar.gz 9.7 MB With provenance Details for ferri_pdf-0.1.7.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for ferri-pdf 0.1.7
File Actions
ferri_pdf-0.1.7-cp310-abi3-win_arm64.whl CPython 3.10 abi3 Windows ARM64 Details for ferri_pdf-0.1.7-cp310-abi3-win_arm64.whl
ferri_pdf-0.1.7-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details for ferri_pdf-0.1.7-cp310-abi3-win_amd64.whl
ferri_pdf-0.1.7-cp310-abi3-musllinux_1_2_x86_64.whl CPython 3.10 abi3 Linux musl 1.2+ x86-64 Details for ferri_pdf-0.1.7-cp310-abi3-musllinux_1_2_x86_64.whl
ferri_pdf-0.1.7-cp310-abi3-musllinux_1_2_aarch64.whl CPython 3.10 abi3 Linux musl 1.2+ ARM64 Details for ferri_pdf-0.1.7-cp310-abi3-musllinux_1_2_aarch64.whl
ferri_pdf-0.1.7-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details for ferri_pdf-0.1.7-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
ferri_pdf-0.1.7-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details for ferri_pdf-0.1.7-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
ferri_pdf-0.1.7-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details for ferri_pdf-0.1.7-cp310-abi3-macosx_11_0_arm64.whl
ferri_pdf-0.1.7-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details for ferri_pdf-0.1.7-cp310-abi3-macosx_10_12_x86_64.whl

Total release size: 174.3 MB

Release files / ferri_pdf-0.1.7.tar.gz

Download URL ferri_pdf-0.1.7.tar.gz
Size 9.7 MB
Tags Source
SHA-256 checksum
How to use checksums
cfbb9f3747fcb8df5138db7f9ade1c9986855f30d1a462815a83966dfc3fe7e8
BLAKE2b-256 checksum
How to use checksums
cea5b9186b24dd656435bacf0c6ba444199c4b32148ab208cf884871c6ad48af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 31, 2026.

Transparency log

Release files / ferri_pdf-0.1.7-cp310-abi3-win_arm64.whl

Download URL ferri_pdf-0.1.7-cp310-abi3-win_arm64.whl
Size 18.8 MB
Tags CPython 3.10 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
00d03b68b4c2dc057f5bc20a969fee896e11c24ce45406e3466ee6783aab8439
BLAKE2b-256 checksum
How to use checksums
6a3b68b94cc5494390f28f7d4347b01e1f30c3b7a327e75c38455b5b7d85467d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 31, 2026.

Transparency log

Release files / ferri_pdf-0.1.7-cp310-abi3-win_amd64.whl

Download URL ferri_pdf-0.1.7-cp310-abi3-win_amd64.whl
Size 19.9 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
00f513468ecf49acf0b9151622241991417ee7de17cf85d697d38dcd0c4fd788
BLAKE2b-256 checksum
How to use checksums
92a6c586599c8221f9885da7da210de8fc20c2a5d1687399c5fc8dd6c2413ba5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 31, 2026.

Transparency log

Release files / ferri_pdf-0.1.7-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL ferri_pdf-0.1.7-cp310-abi3-musllinux_1_2_x86_64.whl
Size 22.1 MB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
a5ca300881ed4d2d4afb9fef4e7088318fd35b90f5cf8a177154f8393061f129
BLAKE2b-256 checksum
How to use checksums
37218082698708e36195d6f724ab37820663fc48ae6fd6a1c06370e734ac0c1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 31, 2026.

Transparency log

Release files / ferri_pdf-0.1.7-cp310-abi3-musllinux_1_2_aarch64.whl

Download URL ferri_pdf-0.1.7-cp310-abi3-musllinux_1_2_aarch64.whl
Size 21.4 MB
Tags CPython 3.10 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
92cb26d32cb0275689477b1aa886c3b0ea085a21dc3edd1c99f9313124108dbc
BLAKE2b-256 checksum
How to use checksums
fa4650cab71dbe2a45d7465ac233c6039502fbf526888d1738c6388c6a889795
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 31, 2026.

Transparency log

Release files / ferri_pdf-0.1.7-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL ferri_pdf-0.1.7-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 21.2 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
963af5a966c5eca96cdf520fc105bc5d7f05b47aac820c2f42c4a9200d258a85
BLAKE2b-256 checksum
How to use checksums
89928b2398e3d65ac90cf048b67654efedf866cd68811e05dd17f5238e6ac1cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 31, 2026.

Transparency log

Release files / ferri_pdf-0.1.7-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl

Download URL ferri_pdf-0.1.7-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Size 21.2 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
3c6731346668241055d0d88a9b36bc37dad6cfc542be0a739f87cb15558f1a4a
BLAKE2b-256 checksum
How to use checksums
7abac8141f0f9d1e9d653c7b5649bb5af988ef9930c701a9e9d1b1a10c45e4f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 31, 2026.

Transparency log

Release files / ferri_pdf-0.1.7-cp310-abi3-macosx_11_0_arm64.whl

Download URL ferri_pdf-0.1.7-cp310-abi3-macosx_11_0_arm64.whl
Size 19.6 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
6c5a78f33a3ac07bbad6810fa38f79726111bb5c00105f1f89903d619348d7a8
BLAKE2b-256 checksum
How to use checksums
73d07b529965e2803c0a81c396f9470306e040e7cf2803cd74d003e0c71fceba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 31, 2026.

Transparency log

Release files / ferri_pdf-0.1.7-cp310-abi3-macosx_10_12_x86_64.whl

Download URL ferri_pdf-0.1.7-cp310-abi3-macosx_10_12_x86_64.whl
Size 20.4 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
bb6c1dc9cb184fbce7065310a1b1c948a976aa20104043b9d9e3fb6436ccab6d
BLAKE2b-256 checksum
How to use checksums
cd393adddb7bef0133c7a9ec0f65661b3c8dc59ab9b242b26fd38be0f7f45b0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 31, 2026.

Transparency log

Security for ferri-pdf 0.1.7

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 9 files in this release have been uploaded with provenance metadata.

Select from 9 files

Attestation for ferri_pdf-0.1.7.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 31, 2026.

Transparency log

A 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.

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