1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
4
<title>4.9 psp - Python Server Pages</title>
5
<META NAME="description" CONTENT="4.9 psp - Python Server Pages">
6
<META NAME="keywords" CONTENT="modpython">
7
<META NAME="resource-type" CONTENT="document">
8
<META NAME="distribution" CONTENT="global">
9
<link rel="STYLESHEET" href="modpython.css">
10
<link rel="first" href="modpython.html">
11
<link rel="contents" href="contents.html" title="Contents">
12
<link rel="index" href="genindex.html" title="Index">
13
<LINK REL="previous" href="pyapi-sess.html">
14
<LINK REL="up" href="pythonapi.html">
15
<LINK REL="next" href="directives.html">
18
<DIV CLASS="navigation">
19
<table align="center" width="100%" cellpadding="0" cellspacing="2">
21
<td><A href="pyapi-sess-classes.html"><img src="icons/previous.gif"
22
border="0" height="32"
23
alt="Previous Page" width="32"></A></td>
24
<td><A href="pythonapi.html"><img src="icons/up.gif"
25
border="0" height="32"
26
alt="Up One Level" width="32"></A></td>
27
<td><A href="directives.html"><img src="icons/next.gif"
28
border="0" height="32"
29
alt="Next Page" width="32"></A></td>
30
<td align="center" width="100%">Mod_python Manual</td>
31
<td><A href="contents.html"><img src="icons/contents.gif"
32
border="0" height="32"
33
alt="Contents" width="32"></A></td>
34
<td><img src="icons/blank.gif"
35
border="0" height="32"
36
alt="" width="32"></td>
37
<td><A href="genindex.html"><img src="icons/index.gif"
38
border="0" height="32"
39
alt="Index" width="32"></A></td>
41
<b class="navlabel">Previous:</b> <a class="sectref" href="pyapi-sess-classes.html">4.8.1 Classes</A>
42
<b class="navlabel">Up:</b> <a class="sectref" href="pythonapi.html">4. Python API</A>
43
<b class="navlabel">Next:</b> <a class="sectref" href="directives.html">5. Apache Configuration Directives</A>
46
<!--End of Navigation Panel-->
48
<H1><A NAME="SECTION006900000000000000000"> </A>
50
4.9 <tt class="module">psp</tt> - Python Server Pages
55
The <tt class="module">psp</tt> module provides a way to convert text documents
56
(including, but not limited to HTML documents) containing Python code
57
embedded in special brackets into pure Python code suitable for
58
execution within a mod_python handler, thereby providing a versatile
59
mechanism for delivering dynamic content in a style similar to ASP,
63
The parser used by <tt class="module">psp</tt> is written in C (generated using flex)
64
and is therefore very fast.
67
<i>See <A href="hand-psp.html#hand-psp">6.2</A> ``PSP Handler'' for additional PSP
71
Inside the document, Python <i class="dfn">code</i> needs to be surrounded by
72
"<tt class="samp"><%</tt>" and "<tt class="samp">%></tt>". Python <i class="dfn">expressions</i> are enclosed in
73
"<tt class="samp"><%=</tt>" and "<tt class="samp">%></tt>". A <i class="dfn">directive</i> can be enclosed in
74
"<tt class="samp"><%@</tt>" and "<tt class="samp">%></tt>". A comment (which will never be part of
75
the resulting code) can be enclosed in "<tt class="samp"><%-</tt>" and "<tt class="samp">-%></tt>"
77
Here is a primitive PSP page that demonstrated use of both code and
78
expression embedded in an HTML document:
81
<dl><dd><pre class="verbatim">
86
Hello world, the time is: <%=time.strftime("%Y-%m-%d, %H:%M:%S")%>
91
Internally, the PSP parser would translate the above page into the
92
following Python code:
95
<dl><dd><pre class="verbatim">
96
req.write("""<html>
100
Hello world, the time is: """); req.write(str(time.strftime("%Y-%m-%d, %H:%M:%S"))); req.write("""
106
This code, when executed inside a handler would result in a page
107
displaying words "<tt class="samp">Hello world, the time is: </tt>" followed by current time.
110
Python code can be used to output parts of the page conditionally or
111
in loops. Blocks are denoted from within Python code by
112
indentation. The last indentation in Python code (even if it is a
113
comment) will persist through the document until either end of
114
document or more Python code.
118
<dl><dd><pre class="verbatim">
122
# This indent will persist
124
<p>This paragraph will be
125
repeated 3 times.</p>
127
# This line will cause the block to end
129
This line will only be shown once.<br>
134
The above will be internally translated to the following Python code:
137
<dl><dd><pre class="verbatim">
138
req.write("""<html>
141
# This indent will persist
143
<p>This paragraph will be
144
repeated 3 times.</p>
146
# This line will cause the block to end
148
This line will only be shown once.<br>
154
The parser is also smart enough to figure out the indent if the last
155
line of Python ends with "<tt class="samp">:</tt>" (colon). Considering this, and that the
156
indent is reset when a newline is encountered inside "<tt class="samp"><% %></tt>", the
157
above page can be written as:
160
<dl><dd><pre class="verbatim">
165
<p>This paragraph will be
166
repeated 3 times.</p>
169
This line will only be shown once.<br>
174
However, the above code can be confusing, thus having descriptive
175
comments denoting blocks is highly recommended as a good practice.
178
The only directive supported at this time is <code>include</code>, here is
182
<dl><dd><pre class="verbatim">
183
<%@ include file="/file/to/include"%>
187
If the <tt class="function">parse()</tt> function was called with the <var>dir</var>
188
argument, then the file can be specified as a relative path, otherwise
189
it has to be absolute.
192
<dl><dt><b><span class="typelabel">class</span> <a name="l2h-213"><tt class="class">PSP</tt></a></b>(<var>req, </var><big>[</big><var>, filename, string, vars</var><big>]</big>)
194
This class represents a PSP object.
197
<var>req</var> is a request object; <var>filename</var> and <var>string</var> are
198
optional keyword arguments which indicate the source of the PSP
199
code. Only one of these can be specified. If neither is specified,
200
<code>req.filename</code> is used as <var>filename</var>.
203
<var>vars</var> is a dictionary of global variables. Vars passed in the
204
<tt class="method">run()</tt> method will override vars passed in here.
207
This class is used internally by the PSP handler, but can also be
208
used as a general purpose templating tool.
211
When a file is used as the source, the code object resulting from
212
the specified file is stored in a memory cache keyed on file name
213
and file modification time. The cache is global to the Python
214
interpreter. Therefore, unless the file modification time changes,
215
the file is parsed and resulting code is compiled only once per
219
The cache is limited to 512 pages, which depending on the size of
220
the pages could potentially occupy a significant amount of
221
memory. If memory is of concern, then you can switch to dbm file
222
caching. Our simple tests showed only 20% slower performance using
223
bsd db. You will need to check which implementation <tt class="module">anydbm</tt>
224
defaults to on your system as some dbm libraries impose a limit on
225
the size of the entry making them unsuitable. Dbm caching can be
226
enabled via <code>PSPDbmCache</code> Python option, e.g.:
229
<dl><dd><pre class="verbatim">
230
PythonOption PSPDbmCache ``/tmp/pspcache.dbm''
232
Note that the dbm cache file is not deleted when the server
236
Unlike with files, the code objects resulting from a string are
237
cached in memory only. There is no option to cache in a dbm file at
241
<dl><dt><b><a name="l2h-214"><tt class="method">run</tt></a></b>(<big>[</big><var>vars</var><big>]</big>)
243
This method will execute the code (produced at object
244
initialization time by parsing and compiling the PSP
245
source). Optional argument <var>vars</var> is a dictionary keyed by
246
strings that will be passed in as global variables.
249
Additionally, the PSP code will be given global variables
250
<code>req</code>, <code>psp</code>, <code>session</code> and <code>form</code>. A session
251
will be created and assigned to <code>session</code> variable only if
252
<code>session</code> is referenced in the code (the PSP handler examines
253
<code>co_names</code> of the code object to make that
254
determination). Remember that a mere mention of <code>session</code>
255
will generate cookies and turn on session locking, which may or
256
may not be what you want. Similarly, a mod_python
257
<tt class="class">FieldStorage</tt> object will be instantiated if <code>form</code> is
258
referenced in the code.
261
The object passed in <code>psp</code> is an instance of
262
<tt class="class">PSPInstance</tt>.
268
<dl><dt><b><a name="l2h-215"><tt class="method">display_code</tt></a></b>()
270
Returns an HTML-formatted string representing a side-by-side
271
listing of the original PSP code and resulting Python code
272
produced by the PSP parser.
276
Here is an example of how <tt class="class">PSP</tt> can be used as a templating
281
<dl><dd><pre class="verbatim">
283
<!-- This is a simple psp template called template.html -->
284
<h1>Hello, <%=what%>!</h1>
288
<dl><dd><pre class="verbatim">
289
from mod_python import apache, psp
292
template = psp.PSP(req, filename='template.html')
293
template.run({'what':'world'})
301
<dl><dt><b><span class="typelabel">class</span> <a name="l2h-216"><tt class="class">PSPInstance</tt></a></b>()
303
An object of this class is passed as a global variable <code>psp</code> to
304
the PSP code. Objects of this class are instantiated internally and
305
the interface to <tt class="method">__init__</tt> is purposely undocumented.
308
<dl><dt><b><a name="l2h-217"><tt class="method">set_error_page</tt></a></b>(<var>filename</var>)
310
Used to set a psp page to be processed when an exception
311
occurs. If the path is absolute, it will be appended to document
312
root, otherwise the file is assumed to exist in the same directory
313
as the current page. The error page will receive one additional
314
variable, <code>exception</code>, which is a 3-tuple returned by
315
<code>sys.exc_info()</code>.
319
<dl><dt><b><a name="l2h-218"><tt class="method">apply_data</tt></a></b>(<var>object</var><big>[</big><var>, **kw</var><big>]</big>)
321
This method will call the callable object <var>object</var>, passing form
322
data as keyword arguments, and return the result.
326
<dl><dt><b><a name="l2h-219"><tt class="method">redirect</tt></a></b>(<var>location</var><big>[</big><var>, permanent=0</var><big>]</big>)
328
This method will redirect the browser to location
329
<var>location</var>. If <var>permanent</var> is true, then
330
<tt class="constant">MOVED_PERMANENTLY</tt> will be sent (as opposed to
331
<tt class="constant">MOVED_TEMPORARILY</tt>).
334
<div class="note"><b class="label">Note:</b>
335
Redirection can only happen before any data is sent to the
336
client, therefore the Python code block calling this method must
337
be at the very beginning of the page. Otherwise an
338
<tt class="exception">IOError</tt> exception will be raised.
343
<dl><dd><pre class="verbatim">
346
# note that the '<' above is the first byte of the page!
347
psp.redirect('http://www.modpython.org')
356
Additionally, the <tt class="module">psp</tt> module provides the following low level
360
<dl><dt><b><a name="l2h-220"><tt class="function">parse</tt></a></b>(<var>filename</var><big>[</big><var>, dir</var><big>]</big>)
364
This function will open file named <var>filename</var>, read and parse its
365
content and return a string of resulting Python code.
368
If <var>dir</var> is specified, then the ultimate filename to be parsed
369
is constructed by concatenating <var>dir</var> and <var>filename</var>, and
370
the argument to <code>include</code> directive can be specified as a
371
relative path. (Note that this is a simple concatenation, no path
372
separator will be inserted if <var>dir</var> does not end with one).
376
<dl><dt><b><a name="l2h-221"><tt class="function">parsestring</tt></a></b>(<var>string</var>)
380
This function will parse contents of <var>string</var> and return a string
381
of resulting Python code.
386
<DIV CLASS="navigation">
388
<table align="center" width="100%" cellpadding="0" cellspacing="2">
390
<td><A href="pyapi-sess-classes.html"><img src="icons/previous.gif"
391
border="0" height="32"
392
alt="Previous Page" width="32"></A></td>
393
<td><A href="pythonapi.html"><img src="icons/up.gif"
394
border="0" height="32"
395
alt="Up One Level" width="32"></A></td>
396
<td><A href="directives.html"><img src="icons/next.gif"
397
border="0" height="32"
398
alt="Next Page" width="32"></A></td>
399
<td align="center" width="100%">Mod_python Manual</td>
400
<td><A href="contents.html"><img src="icons/contents.gif"
401
border="0" height="32"
402
alt="Contents" width="32"></A></td>
403
<td><img src="icons/blank.gif"
404
border="0" height="32"
405
alt="" width="32"></td>
406
<td><A href="genindex.html"><img src="icons/index.gif"
407
border="0" height="32"
408
alt="Index" width="32"></A></td>
410
<b class="navlabel">Previous:</b> <a class="sectref" href="pyapi-sess-classes.html">4.8.1 Classes</A>
411
<b class="navlabel">Up:</b> <a class="sectref" href="pythonapi.html">4. Python API</A>
412
<b class="navlabel">Next:</b> <a class="sectref" href="directives.html">5. Apache Configuration Directives</A>
414
<span class="release-info">Release 3.1.3, documentation updated on February 17, 2004.</span>
416
<!--End of Navigation Panel-->