Skip to content
Browse files

Moar docs

  • Loading branch information...
SimonSapin committed Jul 19, 2012
1 parent b458f16 commit f42c8634d36eb51deaaa700bf20746fbecfd5d6f
Showing with 73 additions and 19 deletions.
  1. +1 −1 README.rst
  2. +53 −12 docs/index.rst
  3. +1 −0 flask_weasyprint/
  4. +17 −5 flask_weasyprint/
  5. +1 −1
@@ -1,7 +1,7 @@

Make PDF in your Flask_ app with WeasyPrint_.
Make PDF with WeasyPrint_ in your Flask_ app.

* BSD licensed
* Python 2.6 or 2.7 only
@@ -12,16 +12,46 @@ and working, just install the extension with pip::
$ pip install Flask-WeasyPrint


Let’s assume you have a Flask application serving an HTML document at with a print-ready CSS stylesheet. WeasyPrint
can render this document to PDF:

.. code-block:: python
from weasyprint import HTML
pdf = HTML('').write_pdf()
WeasyPrint will fetch the stylesheet, the images as well as the document itself
over HTTP, just like a web browser would. Of course, going through the network
is a bit silly if WeasyPrint is running on the same server as the application.
Flask-WeasyPrint can help:

.. code-block:: python
from my_flask_application import app
from flask_weasyprint import HTML
with app.test_request_context(base_url=''):
# /hello/ is resolved relative to the context’s URL.
pdf = HTML('/hello/').write_pdf()
Just import :func:`~flask_weasyprint.HTML` and :func:`~flask_weasyprint.CSS`
Just import :func:`~flask_weasyprint.HTML` or :func:`~flask_weasyprint.CSS`
from ``flask_weasyprint`` rather than ``weasyprint``, and use them from
within a Flask :ref:`request context <flask:request-context>`.
:func:`render_pdf` is a helper function to make a :class:`~flask.Response`
with the correct MIME type.
For URLs below the application’s root URL, Flask-WeasyPrint will short-circuit
the network and make the request at the WSGI level, without leaving the
Python process.

```` is a simple Flask application:
Note that from a Flask view function you already are in a request context and
thus do not need :meth:`~flask.Flask.test_request_context`.

An example app

Here is a simple *hello world* application that uses Flask-WeasyPrint:

.. code-block:: python
@@ -30,7 +60,7 @@ with the correct MIME type.
app = Flask(__name__)
@app.route('/', defaults={'name': 'World'):
@app.route('/hello/', defaults={'name': 'World'}):
def hello_html(name):
return render_template('hello.html', name=name)
@@ -48,9 +78,7 @@ with the correct MIME type.
html = render_template('hello.html', name=name)
return render_pdf(HTML(string=html))
In ``templates/hello.html``, the stylesheet is within the same app.
Flask-WeasyPrint will fetch at the Python level it without going through
the network. The same would apply to images that could even by dynamic:

.. code-block:: html+jinja

@@ -61,8 +89,7 @@ the network. The same would apply to images that could even by dynamic:
<p>Hello, {{ name }}!</p>
<nav><a href="{{ url_for('hello_pdf', name=name) }}">Get as PDF</a></nav>

In ``static/style.css``, web browsers ignore the parts in ``@page`` and
``@media print`` when rendering to screen:

.. code-block:: css
@@ -75,6 +102,20 @@ In ``static/style.css``, web browsers ignore the parts in ``@page`` and
:func:`render_pdf` helps making a :class:`~flask.Response` with the correct
MIME type. You can give it an URL or an ``HTML`` object.

In the HTML you can use :func:`~flask.url_for` or relative URLs.
Flask-WeasyPrint will do the right thing to fetch resources and make
hyperlinks absolute in the PDF output.

In CSS, ``@page`` and ``@media print`` can be used to have print-specific
styles. Here the "Get as PDF" link is not displayed in the PDF itself,
although it still exists in the HTML.

.. autofunction::


@@ -73,6 +73,7 @@ def _wrapper(class_, *args, **kwargs):
# Assume a (possibly relative) URL
guess = urlparse.urljoin(request.url, guess)
if 'string' in kwargs and 'base_url' not in kwargs:
# Strings do not have an "intrinsic" base URL, use the request context.
kwargs['base_url'] = request.url
kwargs['url_fetcher'] = make_url_fetcher()
return class_(guess, *args, **kwargs)
@@ -13,6 +13,18 @@
from flask import (Flask, render_template, request, abort, redirect, url_for,

def run():
"""A more involved application, with a dynamic SVG graph.
Run it with ``python -m flask_weasyprint.test_app`` or have a look
at the source code.
# This function exits mostly to make a "view source" link in the docs.

# Disable the Flask’s default static file handling. (See below.)
app = Flask(__name__, static_folder=None)

@@ -51,7 +63,7 @@ def graph():
return svg, 200, {'Content-Type': 'image/svg+xml'}

### The Flask-WeasyPrint specific code follows. Pretty simple, eh?
### The code specific to Flask-WeasyPrint follows. Pretty simple, eh?

from flask_weasyprint import render_pdf, HTML

@@ -63,12 +75,12 @@ def document_pdf():

def document_png():
# We didn’t bother with helpers for the PNG output,
# but you can of course still use it.
# We didn’t bother to make a ``render_png`` helper
# but of course you can still use WeasyPrint’s PNG output.
return Response(HTML('/').write_png(), mimetype='image/png')

### End of Flask-WeasyPrint specific code.
### End of code specific to Flask-WeasyPrint.

### The templates and static files are inlined here and served from memory.
@@ -135,4 +147,4 @@ def static(filename):

if __name__ == '__main__':
@@ -30,7 +30,7 @@
'Environment :: Web Environment',

0 comments on commit f42c863

Please sign in to comment.
You can’t perform that action at this time.