Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

WeasyPrint converts HTML and CSS into paginated PDF files from either the command line or Python. For a quick conversion, install WeasyPrint and run weasyprint input.html output.pdf; in Python, use HTML(filename="input.html").write_pdf("output.pdf"). The key details are that WeasyPrint is a print-focused renderer, not a full browser, and relative images, stylesheets, and fonts need a resolvable base URL.

What WeasyPrint does—and what it does not

WeasyPrint is a visual rendering engine for HTML and CSS that exports PDF. Its layout engine is written in Python and designed for paginated output. It is not based on a full browser engine such as WebKit or Gecko, so do not assume that a page that looks correct in a browser will render identically in a PDF. See the WeasyPrint 70.0 API reference.

This makes WeasyPrint a fit for reports, invoices, forms, and other documents where print layout matters. It supports many CSS features used for print, but CSS and interactive browser behavior are not identical. For example, the documentation describes CSS 2.1 as “pretty well supported” while listing exceptions; interactive pseudo-classes such as :hover and :focus never match in the generally non-interactive PDF output. Validate the actual rendered PDF when layout fidelity matters.

Install WeasyPrint

The current official documentation reviewed here is for WeasyPrint 70.0. Its installation instructions list Python 3.10 or newer and dependencies that include Pango and pydyf. Installing the Python package may not be sufficient on every platform; consult the official installation and project overview for the requirements relevant to your operating system.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Create and activate a virtual environment:
    python3 -m venv venv
    On macOS or Linux, activate it with source venv/bin/activate. On Windows PowerShell, use venvScriptsActivate.ps1.
  2. Install the package:
    python -m pip install weasyprint
  3. Check the installation and environment details:
    weasyprint --info

If the check or first render reports missing native libraries, install the platform packages described by the official installation guidance and run the check again. Do not treat a successful pip install as proof that all system dependencies are present.

Convert HTML to PDF from the command line

The basic command is:

weasyprint input.html output.pdf

The first argument can be a filename or URL; use - to read HTML from standard input. The output can be a filename or - for standard output. For a remote page, for example:

weasyprint https://example.com report.pdf

For a local file that references sibling assets, supply a base URL so relative paths resolve from the intended directory:

weasyprint --base-url ./ input.html output.pdf

Useful options documented in the command-line reference include:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • --stylesheet to apply an additional CSS file.
  • --media-type to select the media type; the default is print.
  • --base-url to set the base used to resolve relative resources.
  • --timeout to limit URL fetching time.
  • --allowed-protocols to restrict URL schemes the renderer may fetch.
  • --no-http-redirects to disable HTTP redirects.
  • --fail-on-http-errors to make HTTP errors fail the command rather than pass unnoticed.

Check weasyprint --help in the installed version for exact option syntax and defaults before incorporating flags into deployment scripts.

Convert HTML to PDF from Python

Use HTML and its write_pdf method. The following is runnable after installing WeasyPrint; run it from the directory containing input.html:

from weasyprint import HTML

HTML(filename="input.html").write_pdf("output.pdf")

You can also use an absolute URL as the input:

from weasyprint import HTML

HTML(url="https://example.com").write_pdf("output.pdf")

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The API accepts a filename, an absolute URL, or a file object as input. If you omit the target, write_pdf() returns PDF bytes instead of writing directly to a file:

from weasyprint import HTML

pdf_bytes = HTML(filename="input.html").write_pdf()
with open("output.pdf", "wb") as output:
    output.write(pdf_bytes)

For CSS that uses @font-face, the API reference calls for a FontConfiguration. Reuse the same configuration for the CSS objects applied to that document:

from weasyprint import CSS, HTML
from weasyprint.text.fonts import FontConfiguration

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

font_config = FontConfiguration()
stylesheet = CSS(filename="print.css", font_config=font_config)
HTML(filename="input.html").write_pdf(
    "output.pdf", stylesheets=[stylesheet], font_config=font_config
)

Make images, stylesheets, and fonts resolve correctly

Relative URLs are interpreted against a base URL. That base may come from the HTML <base> element or the API/CLI base URL setting. If a stylesheet, image, or font is missing in the PDF, first check whether its URL is relative and what directory or URL is being used as the base.

WeasyPrint supports file, HTTP, FTP, and data URLs by default. Its default HTTP client does not support cookies or authentication. If the source page or its assets require credentials, a custom URL fetcher may be needed; do not assume that passing a URL to WeasyPrint reproduces an authenticated browser session. The API reference and first-steps guide describe URL handling and fetching options.

Check CSS, fonts, and PDF features

Layout and browser behavior

WeasyPrint supports many W3C CSS features used in print, but its documentation records unsupported or exceptional behavior, including some right-to-left or bidirectional text and table-related cases. Test representative pages containing the layout patterns your documents actually use; do not infer support for every browser CSS feature from a successful basic conversion.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fonts and multilingual text

If a glyph is unavailable in the selected font, the PDF may display that font’s .notdef glyph, and WeasyPrint can issue a warning in its logs. Check that your chosen fonts include the characters needed for multilingual documents, and review logs as well as the PDF.

Links, bookmarks, attachments, and forms

Generated PDFs can include clickable hyperlinks, bookmarks, attachments, and forms. The documentation also describes PDF/A and PDF/UA generation capability, but generation does not guarantee that a file validates against either standard. If conformance is a requirement, validate the output with an appropriate validator instead of treating a successful export as certification.

SVG content

SVG image content is rendered as vectors in PDF. SVG is still content that can load external resources, so apply the same URL-fetching and security restrictions to it as to HTML and CSS.

Secure conversion of untrusted content

Do not render arbitrary user-supplied HTML, CSS, or SVG in a process with unrestricted access to your host. The official security guidance warns that untrusted markup and styles can cause long render times, high CPU or memory use, and leakage of local files accessible to the rendering process.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Run the renderer as a non-root user with limited filesystem and network access.
  • Apply memory and execution limits, and sandbox the process where appropriate.
  • Use a custom URL fetcher to restrict accessible paths or protocols when the input is not trusted.
  • Keep input files and resources isolated from secrets and sensitive local data.
  • Include embedded or referenced SVG in the threat model because it uses the URL fetcher.

WeasyPrint 70.0 was released on 2026-09-08 and is identified in the official changelog as a security update associated with CVE-2026-55073 and GHSA-r543-q48m-4c9j. The changelog recommends upgrading for deployments that embed untrusted images or rely on the URL fetcher to filter metadata or stylesheets passed as Python parameters. Review that guidance against your deployment and update accordingly.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common conversion problems

Symptom Likely cause What to check or change
Installation fails or weasyprint --info reports a dependency problem A required platform library, including Pango, is missing or incompatible. Check that Python is 3.10 or newer, install the operating-system dependencies in the official guide, then rerun weasyprint --info.
Images, fonts, or CSS disappear from the PDF A relative URL is being resolved against the wrong base, or the resource cannot be fetched. Set the correct --base-url or API base URL; verify the file path or URL and, for remote resources, check access and fetch behavior.
A page requiring login renders without its assets or content The default HTTP client does not support cookies or authentication. Use a custom URL fetcher if appropriate, or provide resources through a controlled route that the renderer can access.
A glyph appears as a box or replacement symbol The selected font may not contain that character. Use a font with the needed glyph coverage and inspect rendering logs for missing-glyph warnings.
Browser layout differs from the PDF WeasyPrint is a print renderer, not a full browser engine, and some CSS or interactive behavior differs. Review the documented CSS limits and adjust print styles; test the actual PDF for complex tables, bidirectional text, and other critical layouts.
A standards-compliant PDF is required Generating PDF/A or PDF/UA output does not itself establish conformance. Run an appropriate external validator against the generated file and address the reported issues.
Rendering time or resource use becomes excessive for submitted content Complex or hostile HTML, CSS, or SVG can consume substantial CPU or memory. Restrict the process, set operational resource limits, constrain URL fetching, and reject or isolate untrusted input.

Performance, reliability, and upgrades

The official sources reviewed do not establish a benchmark or guaranteed rendering speed, so capacity should be measured with representative documents in your own environment. Large images, complex layout, and remote resources can affect a conversion; for dependable jobs, control resource access, set appropriate timeouts, and monitor process resource use.

Rendering can change between major versions even when the API remains compatible. Before upgrading, compare representative output PDFs and review the changelog rather than relying only on successful imports or unchanged method calls. The API reference explicitly cautions that API compatibility does not guarantee identical rendering.

Or skip the browser setup

If you need a screenshot rather than a paginated PDF, ScreenshotNeo offers a one-request website screenshot API. For example, this cURL request saves a WebP screenshot of Stripe:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for API options. Before capture, it accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify page verdict and billing status. An MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, with no card required.

Frequently Asked Questions

Does WeasyPrint execute JavaScript before making a PDF?

The documented workflow describes HTML and CSS rendering rather than browser execution. Do not rely on client-side JavaScript to populate content; provide the completed HTML to the renderer.

Can WeasyPrint write the PDF to memory instead of a file?

Yes. In Python, call write_pdf() without a target to receive PDF bytes, then pass those bytes to the destination you need.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Is WeasyPrint a browser-based PDF converter?

No. It is a Python-based visual rendering engine designed for paginated HTML and CSS output, not a full browser engine.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.