Templating using Python and Preppy

By Andreas Schickedanz Jun 10, 2013

A few days ago I received my new Beaglebone Black. Since then I spend much time on playing around with it. I installed a Teamspeak server, connected it with my old Beaglebone and my Raspberry Pi in a grid structure and wrote a simple service to monitor some sensors connected to the Beaglebone.

During the development of the sensor service, I had to face the problem of providing the sensor data in different formats, so I could access the data from different platforms using a very basic REST interface. The simplest solution to this problem is using the Preppy library.

The Preppy preprocessor

Preppy is a simple preprocessor that is maintained by ReportLab. Using Preppy it is incredibly easy to write templates that could be filled with arbitrary data. You just create the basic structure of your document and embedd Python expressions and control structures into it.

You could think of a Preppy template like a normal Python function which is called using parameters and return the filled template as result. Thus, Preppy compiles a template to a Python module (*.pyc file), which you then call with the needed parameters.

Installing Peppy

Installing Preppy is pretty simple using pip, which is a tool for installing and managing Python packages. To install pip just run:

sudo apt-get install python-pip

Using this tool is as simple as using apt-get. Thus, you just have to run

sudo pip install preppy

to install Preppy.

A simple example

The following example shows a simple json template

{{def(members)}}
{
   "members": [
      {{last = len(members) - 1}}
      {{for key, member in enumerate(members)}}
         {{if key == last:}}
            { "name" : {{member.name}}, "email" : {{member.email}} },
         {{else:}}
            { "name" : {{member.name}}, "email" : {{member.email}} }
         {{endif}}
      {{endfor}}
   ]
}

which will be translated by Preppy to the json file below:

{
   "members": [
      { "name" : "Manu Monkey", "email" : "manu@monkey.com" },
      { "name" : "Daniel Dodo", "email" : "daniel@dodo.com" },
      { "name" : "Kim Kangaroo", "email" : "kim@kangaroo.com" }
   ]
}

This example may some of you remind of somehow similar templates using PHP:

<?php for($i = 0; $i < count($members); $i++): ?>
{
   "members": [
      <?php if($i == count($members) - 1): ?>
         { "name" : <?= $members[i]->name; ?>, "email" : <?= $members[i]->email; ?> }
      <?php else: ?>
         { "name" : <?= $members[i]->name; ?>, "email" : <?= $members[i]->email; ?> },
      <?php endif; ?>
   ]
}
<?php endfor; ?>

However, to compile the above template using preppy, you just create a module using preppy.getModule() and fetch the json content by calling the get() method of the module with the parameters defined within the template. Finally open a file handle and write the content to a new *.json file and you are done.

import preppy

# Generate the preppy module.
jsonModule = preppy.getModule('jsonMembers.prep')

# Fetch the member list from a database or an other resource.
members = db.fetchMembers()

# Generate the json code ...
json = jsonModule.get(members)

# ... and write it to a file.
with open('members.json', 'w') as jsonFile:
   jsonFile.write(json)

You see, using Preppy it is pretty easy to provide data in different formats. Using templates like the one above, I was able to implement a simple REST service, that provides the output of the sensors connected to my Beaglebone Black in JSON, YAML, XML and CSV format. And in case I would like to publish the sensor output over a web interface, I just have to add a HTML template and I’m done.

Hope you enjoyed this short introduction to Preppy. In my next posts I will cover the usage of Preppy in the context of a REST service and the automated generation of reports using ReportLab, z3c.rml and Preppy. So stay tuned and until next time, happy coding.


is a Computer Science MSc. interested in hardware hacking, embedded Linux, compilers, etc.