Python PDF generator: Convert HTML to PDF with WeasyPrint and Nutrient API

Table of contents

    This post compares two approaches to generating PDFs from HTML using Python: WeasyPrint, a solid open-source library, and the Nutrient PDF Generator API, a tool built for reliability at scale. If you’ve struggled with inconsistent layout, missing fonts, or multi-page rendering, this will help you decide what works best and show the output differences clearly.
    Python PDF generator: Convert HTML to PDF with WeasyPrint and Nutrient API
    TL;DR

    This guide walks you through two reliable methods to convert HTML to PDF using Python. First, it covers WeasyPrint, an open source Python PDF generator ideal for small to mid-sized projects. Then, it explores the Nutrient PDF Generator API, a cloud-based solution built for scalable, fully styled, high-volume PDF generation.

    Generating PDFs from HTML is a common task, especially when building features like invoice downloads, analytics exports, or HR documents. The problem? Most tools break down once your layout gets more complex or you need consistent output at scale.

    Why Convert HTML to PDF?

    HTML is great for rendering content on the web, but there are times when you need a static, portable document format like PDF. PDFs are ideal for printing, sharing, and archiving, as they retain their layout and design across devices and operating systems. By converting HTML to PDF, you can preserve your web content’s structure and styling in a format that’s easy to distribute and consume.

    Method 1: Using WeasyPrint

    WeasyPrint(opens in a new tab) is an open source library for converting HTML and CSS documents to PDF. It is designed to be easy to use, making it a popular choice for generating reports, invoices, or any other printable documents from web content. Unlike some other solutions, WeasyPrint focuses on creating high-quality PDFs that are standards-compliant, supporting modern CSS features like flexbox, grid layout, and media queries.

    Key features of WeasyPrint

    • HTML/CSS-to-PDF conversion — WeasyPrint processes HTML and CSS directly, making it ideal for converting complex layouts into PDFs.
    • Support for modern CSS — It supports CSS3 features, including flexbox, grid, and paged media, allowing for advanced document designs.
    • Open source — WeasyPrint is free and open source, with an active community contributing to its development.
    • Multi-platform — Available on multiple operating systems, including Linux, Windows, and macOS.
    • Python integration — WeasyPrint is a Python-based tool, easily integrating with Python projects.

    Installation

    Before you start, ensure you’re working in a virtual environment or using pipx to avoid issues with an externally managed Python environment, as seen on macOS.

    1. Set up a virtual environment:

      Terminal window
      python3 -m venv venv
      source venv/bin/activate
    2. Install WeasyPrint:

      Terminal window
      python3 -m pip install weasyprint

    For more detailed installation instructions, refer to the WeasyPrint documentation(opens in a new tab).

    Generating a PDF with WeasyPrint

    Here’s an example of generating a PDF from an HTML file:

    from weasyprint import HTML
    html_content = """
    <!DOCTYPE html>
    <html>
    <head>
    <title>Sample Report</title>
    <style>
    body { font-family: Arial, sans-serif; }
    h1 { color: #333; }
    </style>
    </head>
    <body>
    <h1>Monthly Sales Report</h1>
    <p>This is a sample PDF report generated from HTML using WeasyPrint.</p>
    </body>
    </html>
    """
    HTML(string=html_content).write_pdf("report.pdf")

    In this example, WeasyPrint takes the html_content string and converts it into a PDF file named report.pdf.

    output

    Method 2: Generating PDFs at scale with Nutrient API

    HTML-to-PDF conversion is easy until you need to:

    • Handle dozens of templates
    • Deliver consistent branding across thousands of documents
    • Inject dynamic data into structured layouts
    • Support multi-page reports with headers, footers, and embedded fonts reliably

    That’s exactly where Nutrient PDF Generator API comes in.

    Rather than stitching together libraries and battling layout quirks, Nutrient lets you render pixel-perfect PDFs by sending structured instructions and assets to a single endpoint. Your HTML stays flexible. Your PDFs stay consistent.

    What it solves

    • ✅ Multi-page layouts: headers, footers, and page breaks rendered automatically
    • ✅ Fonts and images: embedded reliably without client-side hacks
    • ✅ Templates: reusable, styled HTML + CSS for receipts, reports, onboarding docs
    • ✅ Speed: ready for 1 or 10,000 PDFs per day
    • ✅ Maintainability: no environment setup or OS-specific rendering issues

    Need to generate branded reports for HR onboarding? Or pull in real-time transaction data for finance summaries? Nutrient does the heavy lifting, you just pass the content.

    With our API, you receive 200 credits with the free plan. Different operations on a document consume different amounts of credits, so the number of PDF reports you can generate may vary. To access your API key, sign up for a free account(opens in a new tab).

    Requirements

    To get started, you’ll need:

    To access your Nutrient API key, sign up for a free account(opens in a new tab). Once you’ve signed up, you can find your API key in the Dashboard > API Keys section(opens in a new tab).

    Python is a programming language, and pip is a package manager for Python, which you’ll use to install the requests library. Requests(opens in a new tab) is an HTTP library that makes it easy to make HTTP requests.

    Install the requests library with the following command:

    Terminal window
    python -m pip install requests

    How it Works

    Use your preferred HTTP client to send your index.html, CSS, fonts, and images to our /build endpoint, along with rendering instructions.

    Here’s the core idea in Python:

    import requests
    import json
    response = requests.request(
    'POST',
    'https://api.nutrient.io/build',
    headers = {
    'Authorization': 'Bearer your_api_key_here' # Replace with your actual API key
    },
    files = {
    'index.html': open('index.html', 'rb')
    },
    data = {
    'instructions': json.dumps({
    'parts': [
    {
    'html': 'index.html'
    }
    ]
    })
    },
    stream = True
    )
    if response.ok:
    with open('result.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
    fd.write(chunk)
    else:
    print(response.text)
    exit()

    No rendering engines to configure. No missing fonts. No layout drift between systems.

    Use Our Templates or Bring Your Own

    We provide production-grade templates; cleanly styled, multi-page HTML + CSS files with headers, page numbers, font embedding, and logos. Use them as-is or customize them to match your branding and layout needs.

    Want to preview what your HTML looks like in Nutrient? Start with this free report template and run it through the API.

    Try It Free

    The free plan includes 100 credits per month, which covers dozens of PDF renders depending on document complexity. Just sign up(opens in a new tab), grab your API key from the dashboard, and start converting.

    WeasyPrint vs. Nutrient API: Choosing the Right Python PDF Generator

    1. Flexibility and rendering accuracy

    • WeasyPrint — Converts HTML/CSS to PDF with good CSS3 support. Best for single-use exports or templated documents that don’t change often. It may require workarounds for advanced layout features.
    • Nutrient API — Designed to render complex, multi-page documents accurately and consistently. Handles embedded fonts, page breaks, reusable templates, and dynamic assets with minimal configuration.

    2. When you’d use each tool

    • WeasyPrint — Ideal for internal reports, simple page exports, or prototyping locally in Python.
    • Nutrient API — Built for product teams automating document generation: receipts, HR files, invoices, statements. Works especially well when layout consistency and brand styling are critical.

    3. Performance and scale

    • WeasyPrint — Fine for a few documents at a time. Performance may degrade as complexity or volume increases.
    • Nutrient API — Handles thousands of PDFs per day without local processing. Especially useful in workflows where PDF generation is triggered automatically (e.g. via form submissions or scheduled jobs).

    4. Integration and workflow fit

    • WeasyPrint — Python-only, rendered locally. Requires environment setup and filesystem access.
    • Nutrient API — Language-agnostic HTTP API with structured payloads. Works across serverless environments, CI pipelines, and anywhere Python can make a POST request.

    Conclusion

    WeasyPrint is a strong open-source option for basic HTML-to-PDF needs in Python. If you’re generating a few reports a day from static templates, it’ll likely get the job done.

    But when documents become more complex; multi-page layouts, fonts, logos, dynamic sections or your workflow moves from "run it locally" to "generate thousands per week," the limitations start to show.

    That’s where Nutrient offers real leverage. It removes the rendering guesswork, handles styling and scale out of the box, and turns document generation into a repeatable, dependable part of your product or automation pipeline.

    If you’re ready to take your PDF generation to the next level, try the Nutrient PDF Generator API(opens in a new tab) today. Sign up for a free account, grab your API key, and start converting HTML to PDF with ease.

    FAQ

    What is WeasyPrint and how does it work?

    WeasyPrint is an open source Python library that converts HTML and CSS documents into PDF. It processes web content to produce high-quality, standards-compliant PDF files supporting modern CSS features.

    What features does Nutrient API offer?

    Nutrient API provides a comprehensive set of features, including PDF generation, annotations, form filling, digital signatures, and OCR. It’s designed for advanced PDF manipulation and high-volume processing.

    Can I integrate WeasyPrint with existing Python projects?

    Yes, WeasyPrint can be easily integrated into Python projects. It’s installed via pip and used within your Python code to convert HTML content into PDF format.

    Are there any costs associated with Nutrient API?

    Nutrient API offers a free tier that allows for up to 100 PDF documents per month. For higher usage or additional features, you’ll need to subscribe to a paid plan.

    How can I customize the PDF templates in Nutrient API?

    You can customize Nutrient API PDF templates by editing the HTML, CSS, and assets. Download the provided templates and modify them according to your design needs and branding requirements.

    Hulya Masharipov

    Hulya Masharipov

    Technical Writer

    Hulya is a frontend web developer and technical writer at Nutrient who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

    Explore related topics

    FREE TRIAL Ready to get started?