WeasyPrint
Turns HTML and CSS into pixel-perfect PDFs using a pure-Python rendering engine built for print.
Repository Health
Technical Analysis
WeasyPrint is a Python library that renders HTML and CSS documents into PDF files without relying on a browser engine like WebKit or Chromium. It implements its own CSS layout engine in pure Python, purpose-built for pagination and print media, so page breaks, running headers/footers, and generated content behave the way the CSS Paged Media specification describes rather than approximating what a screen browser does.
Teams use it to turn HTML templates into invoices, reports, tickets, and other print-ready documents directly from application code, calling HTML(...).write_pdf() with no headless-browser process, GPU, or JavaScript runtime required. It builds on cffi bindings to Pango and HarfBuzz for text shaping and font handling, and supports advanced PDF output including PDF/A, PDF/UA, tagged (accessible) PDFs, and embedded fonts and attachments.
What You Get
- A Python API (
HTML,CSS,Document) for converting HTML/CSS into PDF bytes or files - A
weasyprintcommand-line tool for one-off conversions without writing code - Support for CSS Paged Media features: page breaks, running headers/footers, page counters, and named pages
- PDF/A, PDF/UA, and tagged (accessible) PDF output, plus custom metadata and file attachments
- A pluggable URL fetcher for controlling how external images, fonts, and stylesheets are resolved
Common Use Cases
- Invoice and receipt generation - SaaS billing systems render HTML invoice templates to PDF at checkout or on a schedule
- Reporting pipelines - backend services turn HTML dashboards or data summaries into downloadable PDF reports
- Ticket and badge printing - event platforms generate print-ready tickets or badges from HTML templates
- Static site to PDF export - documentation or content sites offer a print/PDF version of a page without a headless browser
Under The Hood
Architecture
WeasyPrint’s public API in weasyprint/__init__.py exposes HTML and CSS classes that parse a document with tinyhtml5/tinycss2 and cssselect2, then hand off to document.py’s Document._render, which drives the pipeline through formatting_structure/ (building the box tree from parsed HTML+CSS), layout/ (a large module set — block.py, flex.py, grid.py, table.py, page.py — that lays out boxes into paginated pages), and finally draw/ and pdf/ (rasterizing boxes and streaming PDF objects via the pydyf library). This is a classic multi-stage rendering pipeline (parse → box tree → layout → paint → PDF stream) with each stage in its own subpackage; changing the core box/layout abstraction in formatting_structure/boxes.py would ripple through every layout module and the drawing stage.
Tech Stack
WeasyPrint is pure Python (3.10+) with cffi bindings (see weasyprint/text/ffi.py) to native HarfBuzz and Pango libraries for text shaping and font handling, tinyhtml5/tinycss2/cssselect2 for parsing and CSS selector matching, Pyphen for hyphenation, Pillow for image decoding, fonttools for font subsetting/embedding, and its sibling library pydyf for low-level PDF object writing. It ships a CLI entry point (weasyprint.__main__:main) built on the same public API, and CI (GitHub Actions, tests.yml) runs the test suite across Ubuntu, macOS, and Windows plus CPython 3.10–3.14 and PyPy.
Code Quality
The project has an extensive tests/ suite covering the public API (test_api.py), CSS parsing, box construction, layout, drawing, fonts, and Unicode handling, using pytest with a custom PNG-rendering fixture (conftest.py, built on Ghostscript) for visual regression comparisons. Linting is enforced via ruff with an extensive rule set configured in pyproject.toml. Naming and typing follow standard Python conventions without extensive type hints; error handling favors explicit logger warnings (LOGGER/PROGRESS_LOGGER) over silent failure for malformed CSS/HTML input.
API Design
The public surface is deliberately small: HTML(...), optional CSS(...) stylesheets, and .write_pdf()/.render() methods, with a single DEFAULT_OPTIONS dict documented inline covering PDF variant, metadata, image optimization, and accessibility options. Getting started requires almost no boilerplate — one HTML(string=...).write_pdf('out.pdf') call — while advanced needs (custom URL fetching, font configuration, PDF finishers) are opt-in via keyword arguments rather than subclassing, keeping the common path simple and the advanced path discoverable through the docstrings and Sphinx documentation.
Used by 2 apps in this directory
GPT Researcher
Productivity · AI Assistants
The pioneering open-source autonomous AI agent that conducts deep, multi-source research and produces citation-backed reports exceeding 2,000 words — faster and more reliably than any human researcher.
Morphik
AI Development · Search · Databases
Morphik is an AI-native ingestion and retrieval engine that lets developers store, search, and reason over visually rich documents — scanned PDFs, manuals, slides, and video — without duct-taping together OCR, an embedding model, and a vector database.