~ubuntu-branches/ubuntu/karmic/libapache2-mod-python/karmic-updates

« back to all changes in this revision

Viewing changes to doc-html/pyapi-psp.html

  • Committer: Bazaar Package Importer
  • Author(s): Thom May
  • Date: 2004-09-06 20:27:57 UTC
  • Revision ID: james.westby@ubuntu.com-20040906202757-yzpyu1bcabgpjtiu
Tags: upstream-3.1.3
ImportĀ upstreamĀ versionĀ 3.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 
2
<html>
 
3
<head>
 
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">
 
16
</head>
 
17
<body>
 
18
<DIV CLASS="navigation">
 
19
<table align="center" width="100%" cellpadding="0" cellspacing="2">
 
20
<tr>
 
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>
 
40
</tr></table>
 
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>
 
44
<br><hr>
 
45
</DIV>
 
46
<!--End of Navigation Panel-->
 
47
 
 
48
<H1><A NAME="SECTION006900000000000000000">&nbsp;</A>
 
49
<BR>
 
50
4.9 <tt class="module">psp</tt> - Python Server Pages
 
51
</H1>
 
52
 
 
53
 
 
54
<P>
 
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,
 
60
JSP and others.
 
61
 
 
62
<P>
 
63
The parser used by <tt class="module">psp</tt> is written in C (generated using flex)
 
64
and is therefore very fast.
 
65
 
 
66
<P>
 
67
<i>See <A href="hand-psp.html#hand-psp">6.2</A> ``PSP Handler'' for additional PSP
 
68
information.</i>
 
69
 
 
70
<P>
 
71
Inside the document, Python <i class="dfn">code</i> needs to be surrounded by
 
72
"<tt class="samp">&lt;%</tt>" and "<tt class="samp">%&gt;</tt>". Python <i class="dfn">expressions</i> are enclosed in
 
73
"<tt class="samp">&lt;%=</tt>" and "<tt class="samp">%&gt;</tt>". A <i class="dfn">directive</i> can be enclosed in
 
74
"<tt class="samp">&lt;%@</tt>" and "<tt class="samp">%&gt;</tt>". A comment (which will never be part of
 
75
the resulting code) can be enclosed in "<tt class="samp">&lt;%-</tt>" and "<tt class="samp">-%&gt;</tt>"
 
76
<P>
 
77
Here is a primitive PSP page that demonstrated use of both code and
 
78
expression embedded in an HTML document:
 
79
 
 
80
<P>
 
81
<dl><dd><pre class="verbatim">
 
82
  &lt;html&gt;
 
83
  &lt;%
 
84
  import time
 
85
  %&gt;
 
86
  Hello world, the time is: &lt;%=time.strftime("%Y-%m-%d, %H:%M:%S")%&gt;
 
87
  &lt;/html&gt;
 
88
</pre></dl>
 
89
 
 
90
<P>
 
91
Internally, the PSP parser would translate the above page into the
 
92
following Python code:
 
93
 
 
94
<P>
 
95
<dl><dd><pre class="verbatim">
 
96
  req.write("""&lt;html&gt;
 
97
  """)
 
98
  import time
 
99
  req.write("""
 
100
  Hello world, the time is: """); req.write(str(time.strftime("%Y-%m-%d, %H:%M:%S"))); req.write("""
 
101
  &lt;/html&gt;
 
102
  """)
 
103
</pre></dl>
 
104
 
 
105
<P>
 
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.
 
108
 
 
109
<P>
 
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.
 
115
 
 
116
<P>
 
117
Here is an example:
 
118
<dl><dd><pre class="verbatim">
 
119
  &lt;html&gt;
 
120
  &lt;%
 
121
  for n in range(3):
 
122
      # This indent will persist
 
123
  %&gt;
 
124
  &lt;p&gt;This paragraph will be 
 
125
  repeated 3 times.&lt;/p&gt;
 
126
  &lt;%
 
127
  # This line will cause the block to end
 
128
  %&gt;
 
129
  This line will only be shown once.&lt;br&gt;
 
130
  &lt;/html&gt;
 
131
</pre></dl>
 
132
 
 
133
<P>
 
134
The above will be internally translated to the following Python code:
 
135
 
 
136
<P>
 
137
<dl><dd><pre class="verbatim">
 
138
  req.write("""&lt;html&gt;
 
139
  """)
 
140
  for n in range(3):
 
141
      # This indent will persist
 
142
      req.write("""
 
143
  &lt;p&gt;This paragraph will be
 
144
  repeated 3 times.&lt;/p&gt;
 
145
  """)
 
146
  # This line will cause the block to end
 
147
  req.write("""
 
148
  This line will only be shown once.&lt;br&gt;
 
149
  &lt;/html&gt;
 
150
  """)
 
151
</pre></dl>
 
152
 
 
153
<P>
 
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">&lt;% %&gt;</tt>", the
 
157
above page can be written as:
 
158
 
 
159
<P>
 
160
<dl><dd><pre class="verbatim">
 
161
  &lt;html&gt;
 
162
  &lt;%
 
163
  for n in range(3):
 
164
  %&gt;
 
165
  &lt;p&gt;This paragraph will be 
 
166
  repeated 3 times.&lt;/p&gt;
 
167
  &lt;%
 
168
  %&gt;
 
169
  This line will only be shown once.&lt;br&gt;
 
170
  &lt;/html&gt;
 
171
</pre></dl>
 
172
 
 
173
<P>
 
174
However, the above code can be confusing, thus having descriptive
 
175
comments denoting blocks is highly recommended as a good practice.
 
176
 
 
177
<P>
 
178
The only directive supported at this time is <code>include</code>, here is
 
179
how it can be used:
 
180
 
 
181
<P>
 
182
<dl><dd><pre class="verbatim">
 
183
&lt;%@ include file="/file/to/include"%&gt;
 
184
</pre></dl>
 
185
 
 
186
<P>
 
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.
 
190
 
 
191
<P>
 
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>)
 
193
<dd>
 
194
  This class represents a PSP object.
 
195
 
 
196
<P>
 
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>.
 
201
 
 
202
<P>
 
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.
 
205
 
 
206
<P>
 
207
This class is used internally by the PSP handler, but can also be
 
208
  used as a general purpose templating tool.
 
209
 
 
210
<P>
 
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
 
216
  interpreter.
 
217
 
 
218
<P>
 
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.:
 
227
 
 
228
<P>
 
229
<dl><dd><pre class="verbatim">
 
230
PythonOption PSPDbmCache ``/tmp/pspcache.dbm''
 
231
</pre></dl>
 
232
  Note that the dbm cache file is not deleted when the server
 
233
  restarts.
 
234
 
 
235
<P>
 
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
 
238
  this time.
 
239
 
 
240
<P>
 
241
<dl><dt><b><a name="l2h-214"><tt class="method">run</tt></a></b>(<big>[</big><var>vars</var><big>]</big>)
 
242
<dd>
 
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.
 
247
 
 
248
<P>
 
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.
 
259
 
 
260
<P>
 
261
The object passed in <code>psp</code> is an instance of
 
262
    <tt class="class">PSPInstance</tt>.
 
263
 
 
264
<P>
 
265
</dl>
 
266
 
 
267
<P>
 
268
<dl><dt><b><a name="l2h-215"><tt class="method">display_code</tt></a></b>()
 
269
<dd>
 
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. 
 
273
  </dl>
 
274
 
 
275
<P>
 
276
Here is an example of how <tt class="class">PSP</tt> can be used as a templating
 
277
  mechanism:
 
278
 
 
279
<P>
 
280
The template file:
 
281
  <dl><dd><pre class="verbatim">
 
282
&lt;html&gt;
 
283
  &lt;!-- This is a simple psp template called template.html --&gt;
 
284
  &lt;h1&gt;Hello, &lt;%=what%&gt;!&lt;/h1&gt;
 
285
&lt;/html&gt;
 
286
</pre></dl>
 
287
  The handler code:
 
288
  <dl><dd><pre class="verbatim">
 
289
from mod_python import apache, psp
 
290
 
 
291
def handler(req):
 
292
    template = psp.PSP(req, filename='template.html')
 
293
    template.run({'what':'world'})
 
294
    return apache.OK
 
295
</pre></dl>
 
296
 
 
297
<P>
 
298
</dl>
 
299
 
 
300
<P>
 
301
<dl><dt><b><span class="typelabel">class</span> <a name="l2h-216"><tt class="class">PSPInstance</tt></a></b>()
 
302
<dd>
 
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.
 
306
 
 
307
<P>
 
308
<dl><dt><b><a name="l2h-217"><tt class="method">set_error_page</tt></a></b>(<var>filename</var>)
 
309
<dd>
 
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>.
 
316
  </dl>
 
317
 
 
318
<P>
 
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>)
 
320
<dd>
 
321
    This method will call the callable object <var>object</var>, passing form
 
322
    data as keyword arguments, and return the result.
 
323
  </dl>
 
324
 
 
325
<P>
 
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>)
 
327
<dd>
 
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>).
 
332
 
 
333
<P>
 
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.
 
339
    </div>
 
340
 
 
341
<P>
 
342
Example:
 
343
    <dl><dd><pre class="verbatim">
 
344
&lt;%
 
345
 
 
346
# note that the '&lt;' above is the first byte of the page!
 
347
psp.redirect('http://www.modpython.org')
 
348
%&gt;
 
349
    </pre></dl>
 
350
  </dl>
 
351
 
 
352
<P>
 
353
</dl>
 
354
 
 
355
<P>
 
356
Additionally, the <tt class="module">psp</tt> module provides the following low level
 
357
functions:
 
358
 
 
359
<P>
 
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>)
 
361
<dd>
 
362
 
 
363
<P>
 
364
This function will open file named <var>filename</var>, read and parse its
 
365
  content and return a string of resulting Python code.
 
366
 
 
367
<P>
 
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).
 
373
</dl>
 
374
 
 
375
<P>
 
376
<dl><dt><b><a name="l2h-221"><tt class="function">parsestring</tt></a></b>(<var>string</var>)
 
377
<dd>
 
378
 
 
379
<P>
 
380
This function will parse contents of <var>string</var> and return a string
 
381
  of resulting Python code.
 
382
 
 
383
<P>
 
384
</dl>
 
385
 
 
386
<DIV CLASS="navigation">
 
387
<p><hr>
 
388
<table align="center" width="100%" cellpadding="0" cellspacing="2">
 
389
<tr>
 
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>
 
409
</tr></table>
 
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>
 
413
<hr>
 
414
<span class="release-info">Release 3.1.3, documentation updated on February 17, 2004.</span>
 
415
</DIV>
 
416
<!--End of Navigation Panel-->
 
417
 
 
418
</BODY>
 
419
</HTML>