Convert HTML and CSS to PDFs using WeasyPrint from within your Python app

, a 4-minute piece by Dev Mukherjee Dev Mukherjee

My last post was a call to aid the maintainers of infrastructure software projects. Generating PDFs in code is a difficult task and our last couple of projects have demanded just that. One of them producing reports averaging sixty pages in length, with complex constructs like nested tables, headers and footers.

These reports are dynamically generated from records collected during an accreditation cycle. The length of the content is completely unpredictable and so are the number of reports.

WeasyPrint is an absolute gem of a library. Accessible completely via its Python API, it turns anything represented in HTML and CSS into a PDF. Follow their comprehensive installation instructions and you can turn your first HTML into a PDF via their handy command line utility:

lucille:anomaly devraj$weasyprint 
CSS21-intro.pdf -s

or from within Python:

>>> from weasyprint import HTML
>>> HTML('').write_pdf('/tmp/weasyprint-website.pdf')

We encouraged users of our application to use Markdown to curate portions of the report content that's inserted into the template. It's subsequently processed by the Markdown package to turn it into markup, while a Jinja2 template puts it all together to pass onto WeasyPrint to process.

Most of our scripts will either upload the output to a cloud service like Amazon S3 or push it down to a web browser to download. WeasyPrint can conveniently write to a StringIO and let you decide what you want to do with the generated binary content.

report_css = os.path.join(
    os.path.dirname(__file__), "..", "..", "templates", "report", "report.css")

output = StringIO.StringIO()

report_html = weasyprint.HTML(string=self.render_template())


I highly recommend using WeasyPrint for generating PDFs from within your Python apps and supporting their development efforts.

Next Up: a 4-minute piece by Brad Mclain Brad Mclain

Announcing Vishnu: Sessions for the Google App Engine Python Runtime

Read more