Low level API and other recipes
simplejson
web2py includes gluon.contrib.simplejson, developed by Bob Ippolito. This module provides the most standard Python-JSON encoder-decoder.
SimpleJSON consists of two functions:
gluon.contrib.simplesjson.dumps(a)
encodes a Python objecta
into JSON.gluon.contrib.simplejson.loads(b)
decodes the JSON data inb
into a Python object.
Object types that can be serialized include primitive types, lists, and dictionaries. Compound objects can be serialized with the exception of user defined classes.
Here is a sample action (for example in controller “default.py”) that serializes the Python list containing weekdays using this low level API:
def weekdays():
names=['Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday']
import gluon.contrib.simplejson
return gluon.contrib.simplejson.dumps(names)
Below is a sample HTML page that sends an Ajax request to the above action, receives the JSON message and stores the list in a corresponding JavaScript variable:
{{extend 'layout.html'}}
<script>
$.getJSON('/application/default/weekdays',
function(data){ alert(data); });
</script>
The code uses the jQuery function $.getJSON
, which performs the Ajax call and, on response, stores the weekdays names in a local JavaScript variable data
and passes the variable to the callback function. In the example the callback function simply alerts the visitor that the data has been received.
PyRTF
Another common need of web sites is that of generating Word-readable text documents. The simplest way to do so is using the Rich Text Format (RTF) document format. This format was invented by Microsoft and it has since become a standard.
web2py includes gluon.contrib.pyrtf, developed by Simon Cusack and revised by Grant Edwards. This module allows you to generate RTF documents programmatically, including colored formatted text and pictures.
In the following example we initiate two basic RTF classes, Document and Section, append the latter to the former and insert some dummy text in the latter:
def makertf():
import gluon.contrib.pyrtf as q
doc = q.Document()
section = q.Section()
doc.Sections.append(section)
section.append('Section Title')
section.append('web2py is great. ' * 100)
response.headers['Content-Type'] = 'text/rtf'
return q.dumps(doc)
In the end the Document is serialized by q.dumps(doc)
. Notice that before returning an RTF document it is necessary to specify the content-type in the header else the browser does not know how to handle the file.
Depending on the configuration, the browser may ask you whether to save this file or open it using a text editor.
ReportLab and PDF
web2py can also generate PDF documents, with an additional library called “ReportLab”[ReportLab] .
If you are running web2py from source, it is sufficient to have ReportLab installed. If you are running the Windows binary distribution, you need to unzip ReportLab in the “web2py/“ folder. If you are running the Mac binary distribution, you need to unzip ReportLab in the folder:
web2py.app/Contents/Resources/
From now on we assume ReportLab is installed and that web2py can find it. We will create a simple action called “get_me_a_pdf” that generates a PDF document.
from reportlab.platypus import *
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize
from reportlab.lib.units import inch, mm
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.lib import colors
from uuid import uuid4
from cgi import escape
import os
def get_me_a_pdf():
title = "This The Doc Title"
heading = "First Paragraph"
text = 'bla ' * 10000
styles = getSampleStyleSheet()
tmpfilename = os.path.join(request.folder, 'private', str(uuid4()))
doc = SimpleDocTemplate(tmpfilename)
story = []
story.append(Paragraph(escape(title), styles["Title"]))
story.append(Paragraph(escape(heading), styles["Heading2"]))
story.append(Paragraph(escape(text), styles["Normal"]))
story.append(Spacer(1,2 * inch))
doc.build(story)
data = open(tmpfilename, "rb").read()
os.unlink(tmpfilename)
response.headers['Content-Type'] = 'application/pdf'
return data
Notice how we generate the PDF into a unique temporary file, tmpfilename
, we read the generated PDF from the file, then we deleted the file.
For more information about the ReportLab API, refer to the ReportLab documentation. We strongly recommend using the Platypus API of ReportLab, such as Paragraph
, Spacer
, etc.