DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
HTML to PDF

HTML to PDF in Python: WeasyPrint, Playwright, and Production Checks

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

To turn HTML into a PDF in Python, use WeasyPrint for a Python-facing, print-oriented renderer or Playwright when you want a browser page to produce the PDF. Neither is universally best: the right choice depends on your HTML and CSS, deployment dependencies, and whether the result must match a particular browser view. Start with a small conversion, then test real documents in the same environment you plan to deploy.

Choose a renderer for the document you actually have

The key difference is the rendering path. WeasyPrint provides a direct HTML/CSS-to-PDF API with print layout controls. Playwright drives a browser and calls its PDF API; that API uses print media by default. Both can be suitable, but their output is not guaranteed to match each other or every browser feature. Render representative pages before committing to either approach.

Option Best starting point when Check before adoption
WeasyPrint You want a Python API and print-oriented page layout. Native/runtime requirements, CSS support, resource loading, and safe handling of untrusted input.
Playwright for Python You want to generate a PDF from an automated browser page. Browser runtime and deployment requirements, page readiness, and whether print CSS gives the intended result.
ReportLab You are considering a separate Python PDF-generation toolkit. It is a PDF-generation route; the available documentation does not establish it as a direct HTML converter.
wkhtmltopdf integration You are maintaining an existing legacy Django integration. The available wrapper documentation is old and does not establish current upstream maintenance or suitability.

Compare the HTML and CSS features your templates use, output fidelity on representative pages, production dependencies, treatment of remote resources and untrusted content, and PDF requirements such as page sizing or accessibility variants. The documentation considered here does not establish a neutral performance benchmark, so there is no evidence-based fastest choice for every workload.

Convert HTML to PDF with WeasyPrint

WeasyPrint’s documented Python API accepts HTML from a string, filename, URL, or readable file object. The smallest in-memory example is:

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

html = "<h1>Example</h1><p>Rendered from HTML</p>"
HTML(string=html).write_pdf("example.pdf")

Save that as make_pdf.py, install WeasyPrint following the instructions for your operating system, then run python make_pdf.py. The expected result is an example.pdf in the current directory. The documented call demonstrates a starting point, not a guarantee that an application’s full templates, fonts, images, or scripts will render correctly.

Convert a local HTML file

For a file already on disk, pass its path as the HTML input:

from weasyprint import HTML

HTML(filename="report.html").write_pdf("report.pdf")

For HTML stored in a readable file object, the API also accepts that object. For a remote page, it accepts a URL. Before using URL or file inputs with user-controlled values, review the renderer’s resource-loading behavior and security guidance; do not assume conversion is isolated from local files or network resources.

Set page size and margins in print CSS

WeasyPrint’s guidance uses CSS @page for page geometry. For example:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
@page {
  size: A4;
  margin: 2cm;
}

Put this in a stylesheet included by the HTML or in a <style> element. Choose the page size and margins to suit the document, then inspect the resulting pagination. Headers, tables, images, and long blocks can change where page breaks fall; do not infer correct pagination from a short sample.

Generate a PDF with Playwright for Python

Playwright’s page.pdf() generates using print media. The API documents switching to screen media when that is specifically the desired rendering mode. This complete example navigates to an HTML file and writes a PDF:

import asyncio
from pathlib import Path
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
        await page.goto(Path("report.html").resolve().as_uri())
        await page.pdf(path="report.pdf")
        await browser.close()

asyncio.run(main())

Install the Python Playwright package and its supported browser runtime according to the current Playwright installation instructions for your platform before running the script. The code assumes that the local file is available at report.html and that the browser can launch in the execution environment.

Choose print or screen media deliberately

Use the default print media behavior when the document’s print stylesheet should control the PDF. If the page must be rendered with screen styles instead, call await page.emulate_media(media="screen") before page.pdf(). This changes which media styles apply; it does not make screen and print layouts interchangeable. Test both against the actual page if the intended output is uncertain.

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

Validate output before putting conversion in production

A successful method call only proves that a PDF was produced. It does not prove that the document is complete, legible, correctly paginated, or suitable for its intended use. Run a test set under the same operating system and dependency or browser versions as deployment.

  • Inspect page breaks, page size, margins, and content that spans multiple pages.
  • Check that fonts and images load and that tables remain readable.
  • Verify links and any interactive or script-generated content the document depends on.
  • Test right-to-left or bidirectional text explicitly. WeasyPrint documents limitations in this area.
  • Confirm the output variant you need. WeasyPrint documents PDF/A and PDF/UA variants; check the current documentation and validate the specific archival or accessibility requirements rather than assuming a variant alone guarantees compliance.
  • Check whether output differs across the environments where the application runs.

WeasyPrint’s documentation lists Python and Pango among requirements. Verify the release-specific installation instructions for your target operating system before choosing it. Playwright requires a browser runtime in addition to the Python code, so account for that deployment component as well. The available documentation does not provide a comparable benchmark for throughput or reliability across these options; measure your own workload if those constraints determine the choice.

Handle untrusted HTML and resource access safely

WeasyPrint explicitly warns that untrusted HTML or CSS can create security problems and documents resource-loading concerns. A conversion service that accepts user-provided markup, styles, or resource references should treat the conversion process as an input-processing boundary.

  • Review the renderer’s current security documentation and URL-fetching behavior before accepting user-controlled content.
  • Constrain access to files and network resources according to the application’s requirements; do not assume a converter cannot read local files or request remote URLs without verifying the controls in use.
  • Use process permissions and isolation appropriate to the risks of the service.
  • Test resource-loading behavior with the same deployment configuration used in production.

These precautions are especially relevant when HTML comes from users or another system rather than from templates you control. A renderer choice alone does not establish that untrusted input is safe.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common conversion problems

The PDF is blank or missing content

Confirm that the input HTML is the content you expect and that referenced resources are available to the renderer. With Playwright, make sure navigation reaches the intended page before calling page.pdf(). If content is inserted after navigation, ensure your application has a reliable way to know it is ready before generating the PDF.

Styles look different from the browser

Check which media styles are active. Playwright PDFs use print media by default; use page.emulate_media(media="screen") only when screen media is required. For WeasyPrint, verify that the CSS features used by the template are supported, and test the actual page rather than assuming universal browser CSS coverage.

Installation fails on the deployment machine

For WeasyPrint, inspect the current installation guidance for the target operating system and its native/runtime requirements, including Pango. For Playwright, verify that the required browser runtime is installed and can launch in the deployment environment. A script that runs on a developer workstation may still need environment-specific setup elsewhere.

Pagination or text direction is wrong

Adjust print CSS, page size, and margins, then inspect output containing the same long text, tables, and images as real reports. For right-to-left or bidirectional text, WeasyPrint documents limitations; confirm the specific language and layout needs with rendered examples before relying on it.

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

Conversion behaves unexpectedly with external resources

Review how the selected renderer fetches URLs and handles files. If users can control markup or referenced resources, restrict access and permissions in accordance with the renderer’s current security guidance. Do not treat a PDF conversion API as a security sandbox.

Or skip the browser setup

If your goal is a screenshot or PDF of a web page rather than conversion of an HTML string you already control, ScreenshotNeo offers a website screenshot API and MCP server. Its one-request API can return PNG, JPEG, WebP, or PDF. For a Python screenshot request, the documented example is:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

See the ScreenshotNeo API documentation for request options. ScreenshotNeo removes supported cookie banners, popups, and chat widgets before capture; bot checks, blank pages, and failed loads are not billed. Its MCP server lets AI agents take screenshots, and the Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. This is a web-page capture route, not a substitute for choosing and validating a Python renderer for arbitrary HTML documents.

Sign up free for 1,000 screenshots a month, with no card required.

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

Frequently Asked Questions

Can Python convert an HTML string directly without saving a temporary file?

Yes. WeasyPrint’s documented API accepts an in-memory string through `HTML(string=…)` and writes the PDF with `write_pdf()`.

Does `page.pdf()` in Playwright use the screen stylesheet?

No. It uses print media by default. Emulate screen media before generating the PDF only when screen styling is specifically what you need.

Is wkhtmltopdf a safe choice for a new Django project?

The available evidence is an old third-party Django wrapper, not current proof of upstream maintenance or suitability. Verify the current upstream status before adopting it.

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.

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

Leave a Reply

Your email address will not be published. Required fields are marked *

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

Read next

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.