pdfkit
Python wrapper around wkhtmltopdf that converts HTML pages, files, or strings into PDF documents in a few lines of code.
Repository Health
Technical Analysis
pdfkit is a thin Python wrapper around the wkhtmltopdf command-line utility, letting you generate PDF documents from a URL, a local HTML file, or a raw HTML string without shelling out manually. It exposes three top-level functions — from_url, from_file, and from_string — each of which builds a wkhtmltopdf command, pipes input where needed, and returns the resulting PDF bytes or writes them to disk.
Because it maps almost directly onto wkhtmltopdf’s own CLI flags, pdfkit supports the full range of page-size, margin, header/footer, cover-page, table-of-contents, and custom-CSS options that wkhtmltopdf itself offers, including per-document overrides via HTML meta tags. The project is explicitly a compatibility layer, not a rendering engine — actual PDF generation is delegated entirely to the wkhtmltopdf binary, which must be installed separately.
What You Get
- Three simple entry points —
from_url,from_file, andfrom_string— covering the common ways HTML content needs converting to PDF - A
PDFKitclass for building the raw wkhtmltopdf command yourself when you need to inspect or debug it before running - Full passthrough of wkhtmltopdf options (page size, margins, custom headers/footers, cookies, custom HTTP headers) as a plain Python dict
- Table-of-contents and cover-page support, including control over cover-before-TOC ordering
- Per-document option overrides via
<meta name="pdfkit-*">tags embedded directly in the HTML source - A
Configurationobject for pointing at a non-standard wkhtmltopdf binary path or custom environment variables
Common Use Cases
- Generating downloadable invoice or receipt PDFs from server-rendered HTML templates in a Django or Flask app
- Batch-converting a list of URLs or local report pages into PDF documents for archival or emailing
- Producing print-ready documents with a cover page and table of contents from HTML source
- Rendering HTML strings assembled at runtime (e.g. templated content) directly into PDF without touching the filesystem
Under The Hood
Architecture
pdfkit follows a thin three-layer design: api.py exposes the public from_url/from_file/from_string/configuration functions, each of which is a one-line wrapper that instantiates pdfkit.pdfkit.PDFKit and calls to_pdf(); PDFKit (pdfkit.py) owns command construction (_command/_genargs/_normalize_options) and process execution via subprocess.Popen, piping HTML into wkhtmltopdf’s stdin when the source is a string or file object and reading the PDF back from stdout; Source (source.py) is a small value object that classifies the input as url/file/string and validates file paths exist before a command is ever built. There’s no abstraction seam for swapping the rendering backend — wkhtmltopdf is assumed throughout, so the core abstraction that would break if changed is the underlying binary itself, not any internal Python interface.
Tech Stack
The package has no runtime dependencies beyond the Python standard library (subprocess, re, codecs, collections.OrderedDict) and targets Python 3.8+ per its GitHub Actions matrix (3.8–3.11). It ships as a single pdfkit package via setuptools/distutils, with no build step beyond plain .py files, and its only external requirement is the separately-installed wkhtmltopdf binary, located via which/where unless a path is given explicitly through Configuration.
Code Quality
Tests live in tests/pdfkit-tests.py, a single ~500-line unittest-based suite (TestPDFKitInitialization, plus classes covering option parsing, TOC/cover handling, and file/string/URL sources) run in CI via nosetests across four Python versions on GitHub Actions. There is no type annotation coverage and no linter or formatter configured in the repo; error handling is explicit and centralized in PDFKit.handle_error, which inspects wkhtmltopdf’s stderr for known patterns (missing X server, ‘Error’ substrings) and raises IOError with actionable messages rather than swallowing subprocess failures.
What Makes It Unique pdfkit doesn’t attempt to reimplement HTML/CSS rendering — its only real design decision is being a faithful, low-friction translation layer from Python option dicts to wkhtmltopdf CLI arguments, including a distinctive meta-tag mechanism that lets per-document options be embedded directly in the HTML being converted rather than passed programmatically. This makes it a natural fit for templated-HTML-to-PDF pipelines but ties its capabilities and longevity entirely to wkhtmltopdf, a project the README itself flags as deprecated.