Common Use Cases

Include in Web Applications

Using WeasyPrint in web applications sometimes requires attention on some details.

Security Problems

First of all, rendering untrusted HTML and CSS files can lead to security problems. Please be sure to carefully follow the different proposed solutions if you allow your users to modify the source of the rendered documents in any way.

Rights Management

Another problem is rights management: you often need to render templates that can only be accessed by authenticated users, and WeasyPrint installed on the server doesn’t send the same cookies as the ones sent by the users. Extensions such as Flask-WeasyPrint (for Flask) or Django-WeasyPrint (for Django) solve this issue with a small amount of code. If you use another framework, you can read these extensions and probably find an equivalent workaround.

Server Side Requests & Self-Signed SSL Certificates

If your server is requesting data from itself, you may encounter a self-signed certificate error, even if you have a valid certificate.

You need to add yourself as a Certificate Authority, so that your self-signed SSL certificates can be requested.

# If you have not yet created a certificate.
sudo openssl req -x509 \
    -sha256 \
    -nodes \
    -newkey rsa:4096 \
    -days 365 \
    -keyout localhost.key \
    -out localhost.crt

# Follow the prompts about your certificate and the domain name.
openssl x509 -text -noout -in localhost.crt

Add your new self-signed SSL certificate to your nginx.conf, below the line server_name;:

ssl_certificate /etc/ssl/certs/localhost.crt;
ssl_certificate_key /etc/ssl/private/localhost.key;

The SSL certificate will be valid when accessing your website from the internet. However, images will not render when requesting files from the same server.

You will need to add your new self-signed certificates as trusted:

sudo cp /etc/ssl/certs/localhost.crt /usr/local/share/ca-certificates/localhost.crt
sudo cp /etc/ssl/private/localhost.key /usr/local/share/ca-certificates/localhost.key

# Update the certificate authority trusted certificates.
sudo update-ca-certificates

# Export your newly updated Certificate Authority Bundle file.
# If using Django, it will use the newly signed certificate authority as
# valid and images will load properly.
sudo tee -a /etc/environment <<< 'export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt'

Adjust Document Dimensions

WeasyPrint does not provide support for adjusting page size or document margins via command-line flags. This is best accomplished with the CSS @page at-rule. Consider the following example:

@page {
  size: Letter; /* Change from the default size of A4 */
  margin: 3cm; /* Set margin on each page */

There is much more which can be achieved with the @page at-rule, such as page numbers, headers, etc. Read more about the page at-rule.

Improve Rendering Speed and Memory Use

WeasyPrint is often slower than other web engines. Python is the usual suspect, but it’s not the main culprit here. Optimization is not the main goal of WeasyPrint and it may lead to unbearable long rendering times.

First of all: WeasyPrint’s performance gets generally better with time. You can check WeasyPerf to compare time and memory needed across versions.

Some tips may help you to get better results.

  • A high number of CSS properties with a high number of HTML tags can lead to a huge amount of time spent for the cascade. Avoiding large CSS frameworks can drastically reduce the rendering time.

  • Tables are known to be slow, especially when they are rendered on multiple pages. When possible, using a common block layout instead gives much faster layouts.

  • Optimizing images and fonts can reduce the PDF size, but increase the rendering time. Moreover, caching images gives the possibility to read and optimize images only once, and thus to save time when the same image is used multiple times. See Image Cache and Optimization.