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

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

Built distributions (wheels)

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

Total release size: 174.2 MB

Release files / ferri_pdf-0.1.6.tar.gz

Download URL ferri_pdf-0.1.6.tar.gz
Size 9.7 MB
Tags Source
SHA-256 checksum
How to use checksums
5ce39d768ec1edd89cd874b58a6881e8d9844f493ffcc78064ea40e2cf4ab31d
BLAKE2b-256 checksum
How to use checksums
746299086e488e66f04f925b79382dce6e7a731da210379e413ae0a8d0e1b3f0
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.6-cp310-abi3-win_arm64.whl

Download URL ferri_pdf-0.1.6-cp310-abi3-win_arm64.whl
Size 18.7 MB
Tags CPython 3.10 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
4ffd596dbf29d1308424a431f503f361d5a541b2765bed821eabf5fa23feb665
BLAKE2b-256 checksum
How to use checksums
4fd28ff5898ce49740f161e13030c129fcada2845b9a2e9ff90c405be1fbd5f5
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.6-cp310-abi3-win_amd64.whl

Download URL ferri_pdf-0.1.6-cp310-abi3-win_amd64.whl
Size 19.9 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
ae1b98198b0b53284266a8048e097f481e89ed5cc42e53f04dc7adb469116deb
BLAKE2b-256 checksum
How to use checksums
bbd78a6a1f1a2547dcf4efc171a92533f78e160978a89a90656cfb91901b2a88
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.6-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL ferri_pdf-0.1.6-cp310-abi3-musllinux_1_2_x86_64.whl
Size 22.2 MB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
53586f8b69fc9a7268dc1f60bfe53c7d9c67c1adc60833bd7940aeff5840e645
BLAKE2b-256 checksum
How to use checksums
b8fc29efa006fdd58e67b3219ee6b5986f3b182ff473295364e7d41ea7ffe760
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.6-cp310-abi3-musllinux_1_2_aarch64.whl

Download URL ferri_pdf-0.1.6-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
5221d7dc94ec91fd034a85203f2e3482427f87e370574f9ef2a462ce26eefb5c
BLAKE2b-256 checksum
How to use checksums
daa88de435bbd677f80f21ee17ea7a338a6b2e288de9a87f7e4eba22ccc0cea0
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.6-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL ferri_pdf-0.1.6-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
224e4d25111455b44e8b34559ff2bdc4f123ec73b75cf8259df9138a67fc9066
BLAKE2b-256 checksum
How to use checksums
eb4d5dedf5773157aa78c490c72af38b013115327a1bf9adfc857ac190df5de0
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.6-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl

Download URL ferri_pdf-0.1.6-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
f1d3919088802ad1c291b91c5d7901cfb83c89026f5f3e268e70cd8dd2ff89e7
BLAKE2b-256 checksum
How to use checksums
97537b813e4fe20d26cb0151d79e6b45838208506d1b9e094663cec8a117bb74
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.6-cp310-abi3-macosx_11_0_arm64.whl

Download URL ferri_pdf-0.1.6-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
fa3281b2d4781543b3b74ddb9e08137d2f43535ba3bab6ab026a82dbf6d31f2c
BLAKE2b-256 checksum
How to use checksums
1d06fa527f871c3ba19d8e678b1f704a61049c5b4669241d70979cdd3567d949
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.6-cp310-abi3-macosx_10_12_x86_64.whl

Download URL ferri_pdf-0.1.6-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
375a59566edf2ad322e273364f597413cd71bc66a6e2d0519c3cef7fceae5102
BLAKE2b-256 checksum
How to use checksums
f88aad2e53e77135a3a86b45bcc70d3e2aa87e4f285acff1ba06b540f109d5d2
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.6

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