Custom Renderers

Pyramid supports custom renderers, alongside the default renderers shipped with Pyramid.

Here's a basic comma-separated value (CSV) renderer to output a CSV file to the browser. Add the following to a renderers.py module in your application (or anywhere else you'd like to place such things):

 1import csv
 2try:
 3    from StringIO import StringIO # python 2
 4except ImportError:
 5    from io import StringIO # python 3
 6
 7class CSVRenderer(object):
 8    def __init__(self, info):
 9        pass
10
11    def __call__(self, value, system):
12        """ Returns a plain CSV-encoded string with content-type
13        ``text/csv``. The content-type may be overridden by
14        setting ``request.response.content_type``."""
15
16        request = system.get('request')
17        if request is not None:
18            response = request.response
19            ct = response.content_type
20            if ct == response.default_content_type:
21                response.content_type = 'text/csv'
22
23        fout = StringIO()
24        writer = csv.writer(fout, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
25
26        writer.writerow(value.get('header', []))
27        writer.writerows(value.get('rows', []))
28
29        return fout.getvalue()

Now you have a renderer. Let's register with our application's Configurator:

config.add_renderer('csv', 'myapp.renderers.CSVRenderer')

Of course, modify the dotted-string to point to the module location you decided upon. To use the renderer, create a view:

 1@view_config(route_name='data', renderer='csv')
 2def my_view(request):
 3   query = DBSession.query(table).all()
 4   header = ['First Name', 'Last Name']
 5   rows = [[item.first_name, item.last_name] for item in query]
 6
 7   # override attributes of response
 8   filename = 'report.csv'
 9   request.response.content_disposition = 'attachment;filename=' + filename
10
11   return {
12      'header': header,
13      'rows': rows,
14   }
15
16def main(global_config, **settings):
17    config = Configurator(settings=settings)
18    config.add_route('data', '/data')
19    config.scan()
20    return config.make_wsgi_app()

Query your database in your query variable, establish your headers and initialize rows.

Override attributes of response as required by your use case. We implement this aspect in view code to keep our custom renderer code focused to the task.

Lastly, we pass headers and rows to the CSV renderer.

For more information on how to add custom Renderers, see the following sections of the Pyramid documentation: