Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchFor a new Python project, start with WeasyPrint when your HTML is print-oriented and depends on modern CSS or paged-media features. Choose xhtml2pdf when a ReportLab-backed Python API and explicit PDF controls matter more. Use wkhtmltopdf only when you specifically need its older WebKit rendering path, and treat its warning about untrusted HTML and JavaScript as a deployment requirement.
The right choice depends less on the shortest API call than on CSS fidelity, JavaScript requirements, native libraries, external assets, authentication, and how much control you need over the resulting PDF.
Quick comparison
| Option | Rendering approach | Best fit | Important constraints |
|---|---|---|---|
| WeasyPrint | Python HTML/CSS-to-PDF engine | Print documents using modern CSS and paged-media rules | Python 3.10 or newer and Pango 1.44 or newer are required; the default fetcher does not handle advanced cookies or authentication |
| xhtml2pdf | Python library built on ReportLab, html5lib and pypdf | Mostly Python implementations needing metadata, encryption, signatures or resource policies | HTML5, CSS 2.1 and some CSS 3 are supported; a rendering backend such as PyCairo is needed |
| wkhtmltopdf | Standalone WebKit command-line binary | Projects that must use its WebKit rendering path | The stable 0.12.6 series was released in 2020; the project warns not to process untrusted HTML |
There is no authoritative, cross-project benchmark that establishes one universal winner for speed or visual fidelity. Test your own templates, fonts, images, page breaks and workload before committing to a production choice.
1. WeasyPrint: the default starting point for print CSS
WeasyPrint is usually the first library to evaluate for invoices, reports, statements, brochures and other documents designed for paper or PDF rather than interactive browser behavior. Its engine understands print-oriented CSS and paged-media concepts, and its documented output supports hyperlinks, bookmarks, attachments, forms, SVG, raster images and other common document features.
#1 Best Overall
- Create a mix using audio, music and voice tracks and recordings.
- Customize your tracks with amazing effects and helpful editing tools.
- Use tools like the Beat Maker and Midi Creator.
- Work efficiently by using Bookmarks and tools like Effect Chain, which allow you to apply multiple effects at a time
- Use one of the many other NCH multimedia applications that are integrated with MixPad.
Install and verify prerequisites
Create an isolated environment and install the package:
python -m venv .venv
# macOS/Linux
source .venv/bin/activate
# Windows PowerShell: .venvScriptsActivate.ps1
python -m pip install --upgrade pip
python -m pip install weasyprint
The current documentation lists Python 3.10 or newer and Pango 1.44 or newer. On systems where Pango is not already available, install the platform’s Pango package before diagnosing Python-level errors.
Minimal conversion
from weasyprint import HTML
html = """
Invoice
Paid in full.
"""
HTML(string=html).write_pdf("invoice.pdf")
For a template stored on disk, use HTML(filename="templates/invoice.html").write_pdf("invoice.pdf"). A document that references relative stylesheets or images should have a meaningful base URL:
from pathlib import Path
from weasyprint import HTML
source = Path("templates/invoice.html")
HTML(filename=str(source), base_url=str(source.parent.resolve())).write_pdf("invoice.pdf")
External resources, cookies and authentication
The default URL fetcher can read file and HTTP URLs, but it does not provide advanced cookie or authentication handling. If a PDF needs private logos, authenticated CSS or protected images, supply a controlled custom fetcher that adds credentials only to approved hosts. Do not pass arbitrary user-supplied URLs or credentials through that fetcher.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesUseful CSS for page layout
@page {
size: A4;
margin: 18mm 15mm 20mm;
@bottom-right { content: "Page " counter(page) " of " counter(pages); }
}
h1 { break-before: page; }
table { break-inside: avoid; }
tr { break-inside: avoid; }
Use print-specific styles rather than relying on a browser’s screen layout. Check font availability, long table rows, widows and orphans, links, and images at the actual paper size.
Rank #2
2. xhtml2pdf: a ReportLab-backed Python API
xhtml2pdf converts HTML through ReportLab, html5lib and pypdf. It is a practical choice when you want a Python-centered API and documented controls for PDF metadata, encryption, digital signatures, resource policies and error handling. It can write directly to a file-like object, which is useful for HTTP responses or object storage.
Install and convert to a file
python -m pip install xhtml2pdf
from pathlib import Path
from xhtml2pdf import pisa
html = Path("templates/report.html").read_text(encoding="utf-8")
with open("report.pdf", "wb") as output:
result = pisa.CreatePDF(html, dest=output)
if result.err:
raise RuntimeError(f"PDF conversion reported {result.err} error(s)")
For current releases, the project recommends using the PyCairo extra or backend for ReportLab rendering. Confirm the native rendering dependency on your operating system if installation succeeds but PDF creation fails.
Return PDF bytes from memory
from io import BytesIO
from xhtml2pdf import pisa
def html_to_pdf_bytes(html: str) -> bytes:
buffer = BytesIO()
result = pisa.CreatePDF(html, dest=buffer)
if result.err:
raise ValueError(f"Conversion failed with {result.err} error(s)")
return buffer.getvalue()
pdf_bytes = html_to_pdf_bytes("Monthly report
")
# Example web response: return Response(pdf_bytes, mimetype="application/pdf")
When diagnosing malformed markup or unsupported CSS, enable the library’s exception behavior in the version you use and inspect the returned status instead of silently serving a partial document.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →3. wkhtmltopdf: use the WebKit binary deliberately
wkhtmltopdf is not a pure Python library. It is a command-line converter based on a WebKit rendering path. Install the official platform binary, then call it directly or through a Python wrapper. Its official download page identifies version 0.12.6 as the stable series, released on 2020-06-11, so its browser behavior is substantially older than current Chromium-based engines.
Direct command
wkhtmltopdf input.html output.pdf
Calling it from Python
import subprocess
subprocess.run(
["wkhtmltopdf", "input.html", "output.pdf"],
check=True,
timeout=90,
)
Use an absolute executable path when the service account’s PATH differs from your shell. Capture standard error and exit codes so failed conversions do not produce a misleading success response.
Security boundary
The project explicitly warns: “Do not use wkhtmltopdf with any untrusted HTML.” Sanitize user-controlled HTML and JavaScript, isolate the conversion process, restrict outbound network access, and avoid exposing sensitive files or environment credentials to the converter. This warning is especially important for multi-tenant services.
How to choose
Choose WeasyPrint when
- Your templates are designed for print and use modern CSS or paged-media rules.
- You want a Python API without launching a browser process.
- Bookmarks, links, forms, attachments and SVG/raster images are part of the document.
- You can install and operate Pango and can provide a controlled fetcher for protected assets.
Choose xhtml2pdf when
- ReportLab’s document pipeline fits your application.
- You need documented metadata, encryption, signatures or resource-policy controls.
- You want file output and in-memory output through the same API.
- Your markup fits its HTML5, CSS 2.1 and partial CSS 3 support.
Choose wkhtmltopdf when
- A legacy system already depends on its WebKit rendering behavior.
- A separate binary is acceptable operationally.
- You can strictly sanitize and isolate every HTML/JavaScript input.
Testing for fidelity and production readiness
- Build a representative fixture. Include long tables, nested lists, web fonts, SVG, raster images, links, page breaks, headers, footers and right-to-left or non-Latin text if your users need them.
- Render at the target paper size. Compare A4 and Letter separately; margins and page-break behavior can change pagination.
- Inspect resources. Test missing images, slow URLs, redirects, TLS failures, protected assets and relative paths.
- Exercise failure handling. Verify that your worker reports dependency errors, converter exit codes and partial output instead of returning a corrupt PDF.
- Measure your workload. Record conversion time, memory, queue depth and output size for your actual templates. No official universal throughput or fidelity score exists.
Troubleshooting
Import or shared-library errors with WeasyPrint
Confirm Python is 3.10 or newer and that Pango 1.44 or newer is installed and discoverable. Recreate the virtual environment after changing system libraries.
Images or CSS are missing
Set a correct base_url for string or file-based HTML, use absolute paths where appropriate, and verify that the converter process can read every asset. For private HTTP resources, implement an allow-listed authenticated fetcher rather than embedding unrestricted credentials.
xhtml2pdf reports errors or creates incomplete pages
Check the returned result.err, simplify unsupported CSS, validate the HTML, and install the recommended PyCairo backend. Test complex tables and page breaks independently.
wkhtmltopdf works locally but fails in a service
Use the full binary path, ensure the service account has permission to execute it, capture stderr, and set an explicit timeout. Check sandbox, filesystem and network restrictions before loosening them.
Rank #4
- Transform audio playing via your speakers and headphones
- Improve sound quality by adjusting it with effects
- Take control over the sound playing through audio hardware
JavaScript-dependent pages are blank
These tools are not interchangeable browser automation systems. If the source page requires client-side rendering, first produce a stable HTML snapshot or select a browser-based capture workflow rather than assuming a Python HTML-to-PDF engine will run the application’s JavaScript.
Or skip the browser setup
If your goal is a PDF or image of a live URL rather than rendering a Python template, ScreenshotNeo provides a website screenshot API and MCP server. One request can return PNG, JPEG, WebP or PDF, with options for full-page capture, lazy-loaded images, CSS selectors, dark mode, device and retina settings, custom CSS and JavaScript, waits, blocked resources, headers, cookies, user agents, timezone, geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous webhooks and bulk capture.
Its cleanup step accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status. The MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.
See the complete parameter reference in the ScreenshotNeo documentation. A direct PDF request can be made with the same endpoint:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 shots each month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.
Frequently Asked Questions
Can these libraries convert a Jinja or Django template?
Yes. Render the template to a complete HTML string first, then pass that string to WeasyPrint or xhtml2pdf, or write it to a temporary file for wkhtmltopdf. Keep template rendering and PDF conversion as separate steps so missing variables are caught before conversion.
Best Value
- Full-featured professional audio and music editor that lets you record and edit music, voice and other audio recordings
- Add effects like echo, amplification, noise reduction, normalize, equalizer, envelope, reverb, echo, reverse and more
- Supports all popular audio formats including, wav, mp3, vox, gsm, wma, real audio, au, aif, flac, ogg and more
- Sound editing functions include cut, copy, paste, delete, insert, silence, auto-trim and more
- Integrated VST plugin support gives professionals access to thousands of additional tools and effects
Which option should run in a serverless function?
There is no universal answer. WeasyPrint and xhtml2pdf avoid a browser process but still need native libraries; wkhtmltopdf requires packaging a compatible executable. Build and test the exact deployment image rather than choosing from the Python API alone.
How should I handle fonts?
Install the required fonts in the conversion environment, declare them explicitly in print CSS, and test glyph coverage for every supported language. A font available on a developer laptop is not automatically available to a worker or container.
Should I use a screenshot API for HTML templates?
Use a Python converter for controlled template-to-document workflows. Use a screenshot or PDF API when the source is a live URL and you want remote browser capture, consent cleanup, URL-level waits, or an MCP workflow.
Free tools Windows power users keep installed
One-click scans. No signup required.
The Bottom Line
Evaluate WeasyPrint first for modern, print-focused CSS; choose xhtml2pdf for ReportLab-backed PDF controls; reserve wkhtmltopdf for deliberate legacy WebKit use behind a strong security boundary. Validate the decision with your own documents and deployment environment.
Quick Recap
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.

