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 module in your application (or anywhere else you'd like to place such things):

import csv
    from StringIO import StringIO # python 2
except ImportError:
    from io import StringIO # python 3

class CSVRenderer(object):
    def __init__(self, info):

    def __call__(self, value, system):
        """ Returns a plain CSV-encoded string with content-type
        ``text/csv``. The content-type may be overridden by
        setting ``request.response.content_type``."""

        request = system.get('request')
        if request is not None:
            response = request.response
            ct = response.content_type
            if ct == response.default_content_type:
                response.content_type = 'text/csv'

        fout = StringIO()
        writer = csv.writer(fout, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)

        writer.writerow(value.get('header', []))
        writer.writerows(value.get('rows', []))

        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:

@view_config(route_name='data', renderer='csv')
def my_view(request):
   query = DBSession.query(table).all()
   header = ['First Name', 'Last Name']
   rows = [[item.first_name, item.last_name] for item in query]

   # override attributes of response
   filename = 'report.csv'
   request.response.content_disposition = 'attachment;filename=' + filename

   return {
      'header': header,
      'rows': rows,

def main(global_config, **settings):
    config = Configurator(settings=settings)
    config.add_route('data', '/data')
    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: