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
system_fonts Let documents and the options above use the operating system's installed fonts (default: False)
font_dirs Folders whose fonts are installed families too
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.9

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.9
File Size Uploaded Provenance Actions
ferri_pdf-0.1.9.tar.gz 9.7 MB With provenance Details for ferri_pdf-0.1.9.tar.gz

Built distributions (wheels)

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

Total release size: 175.6 MB

Release files / ferri_pdf-0.1.9.tar.gz

Download URL ferri_pdf-0.1.9.tar.gz
Size 9.7 MB
Tags Source
SHA-256 checksum
How to use checksums
f4975d22b6aa80fdbadc4cc801c095842e6a2377d636d8bc61e64624b3ddb5dc
BLAKE2b-256 checksum
How to use checksums
01e950affad25554ca74c15167ad2a50018298bd822cc699ed49d42dd7e31f51
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 Nov 1, 2026.

Transparency log

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

Download URL ferri_pdf-0.1.9-cp310-abi3-win_arm64.whl
Size 18.8 MB
Tags CPython 3.10 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
459ac369bddb037b6a278521792ce3a4544c6e630a625ee8352db11dccc2abf5
BLAKE2b-256 checksum
How to use checksums
752cd93c06ded3c6546e84cec63bb11ad0f84b445c6c28cdaa2d31998a515ee6
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 Nov 1, 2026.

Transparency log

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

Download URL ferri_pdf-0.1.9-cp310-abi3-win_amd64.whl
Size 20.0 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
c1ab3c7bb3c068fd3625d741ea6fbbb57769f5de80fb507d43ddd96895870fbd
BLAKE2b-256 checksum
How to use checksums
588420054f9c0915e1a20fea9696b67a88fc95d5f37f5fdb5f2a3c45afb8171c
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 Nov 1, 2026.

Transparency log

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

Download URL ferri_pdf-0.1.9-cp310-abi3-musllinux_1_2_x86_64.whl
Size 22.4 MB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
ec11a8e171a6c525fa1145a9780dc49a0d2b9a12767341829935cd4d0915c724
BLAKE2b-256 checksum
How to use checksums
09d3e0792ac7289aef513af343ac3af39f7f39334df2199d6440e6fd646c1a8f
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 Nov 1, 2026.

Transparency log

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

Download URL ferri_pdf-0.1.9-cp310-abi3-musllinux_1_2_aarch64.whl
Size 21.6 MB
Tags CPython 3.10 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
de41e3988d7487917fe576df773024329a6c549a8747bc763ad14e1a20d14419
BLAKE2b-256 checksum
How to use checksums
7fdddde3ccf2f95b024c73b9f1f3f0a0b37f067dafa8b3c3d03232bd899862cd
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 Nov 1, 2026.

Transparency log

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

Download URL ferri_pdf-0.1.9-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 21.4 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
cd2e93e793196925fb530d40da346f3b99a6cb6f771156f345fe187666fd9bf4
BLAKE2b-256 checksum
How to use checksums
4d6d72f39d4941b407e9ff527ce2524d41647abd7f0a85109d9f10b31b746939
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 Nov 1, 2026.

Transparency log

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

Download URL ferri_pdf-0.1.9-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Size 21.4 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
e8cc6ee518a0bda1e689749bac37844bb55166a6219caae3a86592507311d0b2
BLAKE2b-256 checksum
How to use checksums
33278bc5bba7785cd77fb8352eb29bc283ce8bfbee45a89b8e31d838f6c8e660
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 Nov 1, 2026.

Transparency log

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

Download URL ferri_pdf-0.1.9-cp310-abi3-macosx_11_0_arm64.whl
Size 19.7 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
d236d37853e5be046fb6697e78a684ad8e4b7fc79dfec79331c958599f34ba03
BLAKE2b-256 checksum
How to use checksums
3fdfbd93ed733d54e283cfac152a510150e88b0aa7e3a44fb8146fd4a3379c70
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 Nov 1, 2026.

Transparency log

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

Download URL ferri_pdf-0.1.9-cp310-abi3-macosx_10_12_x86_64.whl
Size 20.5 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
52cff8b964c77fbbd291ec4f4d1ecef0d14baf7003d04e5a0de612f616d35dc6
BLAKE2b-256 checksum
How to use checksums
a826d14292a405dc89190df91d1060f8d855a691b5c3ec4b7a138f16b8aadd59
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 Nov 1, 2026.

Transparency log

Security for ferri-pdf 0.1.9

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.9.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 Nov 1, 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