1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>3.2 So what Exactly does Mod-python do?</title>
<META NAME="description" CONTENT="3.2 So what Exactly does Mod-python do?">
<META NAME="keywords" CONTENT="modpython">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<link rel="STYLESHEET" href="modpython.css">
<link rel="first" href="modpython.html">
<link rel="contents" href="contents.html" title="Contents">
<link rel="index" href="genindex.html" title="Index">
<LINK REL="next" href="tut-more-complicated.html">
<LINK REL="previous" href="tut-overview.html">
<LINK REL="up" href="tutorial.html">
<LINK REL="next" href="tut-more-complicated.html">
</head>
<body>
<DIV CLASS="navigation">
<table align="center" width="100%" cellpadding="0" cellspacing="2">
<tr>
<td><A href="tut-overview.html"><img src="icons/previous.gif"
border="0" height="32"
alt="Previous Page" width="32"></A></td>
<td><A href="tutorial.html"><img src="icons/up.gif"
border="0" height="32"
alt="Up One Level" width="32"></A></td>
<td><A href="tut-more-complicated.html"><img src="icons/next.gif"
border="0" height="32"
alt="Next Page" width="32"></A></td>
<td align="center" width="100%">Mod_python Manual</td>
<td><A href="contents.html"><img src="icons/contents.gif"
border="0" height="32"
alt="Contents" width="32"></A></td>
<td><img src="icons/blank.gif"
border="0" height="32"
alt="" width="32"></td>
<td><A href="genindex.html"><img src="icons/index.gif"
border="0" height="32"
alt="Index" width="32"></A></td>
</tr></table>
<b class="navlabel">Previous:</b> <a class="sectref" href="tut-overview.html">3.1 Quick Overview of</A>
<b class="navlabel">Up:</b> <a class="sectref" href="tutorial.html">3. Tutorial</A>
<b class="navlabel">Next:</b> <a class="sectref" href="tut-more-complicated.html">3.3 Now something More</A>
<br><hr>
</DIV>
<!--End of Navigation Panel-->
<H1><A NAME="SECTION005200000000000000000"> </A>
<BR>
3.2 So what Exactly does Mod-python do?
</H1>
<P>
Let's pretend we have the following configuration:
<dl><dd><pre class="verbatim">
<Directory /mywebdir>
AddHandler python-program .py
PythonHandler myscript
</Directory>
</pre></dl>
<P>
<b>NB:</b> <span class="file">/mywebdir</span> is an absolute physical path.
<P>
And let's say that we have a python program (windows users: substitute
forward slashes for backslashes) <span class="file">/mywedir/myscript.py</span> that looks like
this:
<P>
<dl><dd><pre class="verbatim">
from mod_python import apache
def handler(req):
req.content_type = "text/plain"
req.send_http_header()
req.write("Hello World!")
return apache.OK
</pre></dl>
<P>
Here is what's going to happen: The <code>AddHandler</code> directive tells
Apache that any request for any file ending with <span class="file">.py</span> in the
<span class="file">/mywebdir</span> directory or a subdirectory thereof needs to be
processed by mod_python.
<P>
When such a request comes in, Apache starts stepping through its
request processing phases calling handlers in mod_python. The
mod_python handlers check if a directive for that handler was
specified in the configuration. (Remember, it acts as a dispatcher.)
In our example, no action will be taken by mod_python for
all handlers except for the generic handler. When we get to the
generic handler, mod_python will notice "<tt class="samp">PythonHandler
myscript</tt>" directive and do the following:
<P>
<OL>
<LI>If not already done, prepend the directory in which the
<code>PythonHandler</code> directive was found to <code>sys.path</code>.
<P>
</LI>
<LI>Attempt to import a module by name <code>myscript</code>. (Note that if
<code>myscript</code> was in a subdirectory of the directory where
<code>PythonHandler</code> was specified, then the import would not work
because said subdirectory would not be in the <code>sys.path</code>. One way
around this is to use package notation, e.g. "<tt class="samp">PythonHandler
subdir.myscript</tt>".)
<P>
</LI>
<LI>Look for a function called <code>handler</code> in <code>myscript</code>.
<P>
</LI>
<LI>Call the function, passing it a <tt class="class">Request</tt> object. (More on what a
<tt class="class">Request</tt> object is later)
<P>
</LI>
<LI>At this point we're inside the script:
<P>
<UL>
<LI><dl><dd><pre class="verbatim">
from mod_python import apache
</pre></dl>
<P>
This imports the apache module which provides us the interface to
Apache. With a few rare exceptions, every mod_python program will have
this line.
<P>
</LI>
<LI><dl><dd><pre class="verbatim">
def handler(req):
</pre></dl>
<P>
<a name="l2h-14"> </a>This is our <i class="dfn">handler</i> function declaration. It is called
<code>"handler"</code> because mod_python takes the name of the directive,
converts it to lower case and removes the word <code>"python"</code>. Thus
<code>"PythonHandler"</code> becomes <code>"handler"</code>. You could name it
something else, and specify it explicitly in the directive using the
special "<tt class="samp">::</tt>" notation. For example, if the handler function was
called "<tt class="samp">spam</tt>", then the directive would be
"<tt class="samp">PythonHandler myscript::spam</tt>".
<P>
Note that a handler must take one argument - the mysterious
<tt class="class">Request</tt> object. There is really no mystery about it though. The
<tt class="class">Request</tt> object is an object that provides all of the information
about this particular request - such as the IP of client, the headers,
the URI, etc. The communication back to the client is also done via
the <tt class="class">Request</tt> object, i.e. there is no "response" object.
<P>
</LI>
<LI><dl><dd><pre class="verbatim">
req.content_type = "text/plain"
</pre></dl>
<P>
This sets the content type to <code>"text/plain"</code>. The default is usually
<code>"text/html"</code>, but since our handler doesn't produce any html,
<code>"text/plain"</code> is more appropriate.
<P>
</LI>
<LI><dl><dd><pre class="verbatim">
req.send_http_header()
</pre></dl>
<P>
This function sends the HTTP headers to the client. You can't really
start writing to the client without sending the headers first. Note
that one of the headers is <code>"Content-Type"</code>. So if you want to set
custom content-types, you better do it before you call
<code>req.send_http_header()</code>.
<P>
</LI>
<LI><dl><dd><pre class="verbatim">
req.write("Hello Wordl!")
</pre></dl>
<P>
This writes the <code>"Hello World!"</code> string to the client. (Did I really
have to explain this one?)
<P>
</LI>
<LI><dl><dd><pre class="verbatim">
return apache.OK
</pre></dl>
<P>
This tells Apache that everything went OK and that the request has
been processed. If things did not go OK, that line could be return
<tt class="constant">apache.HTTP_INTERNAL_SERVER_ERROR</tt> or return
<tt class="constant">apache.HTTP_FORBIDDEN</tt>. When things do not go OK, Apache
will log the error and generate an error message for the client.
</LI>
</UL>
</LI>
</OL>
<P>
<b>Some food for thought:</b> If you were paying attention, you noticed that
nowhere did it say that in order for all of the above to happen, the
URL needs to refer to <span class="file">myscript.py</span>. The only requirement was
that it refers to a <span class="file">.py</span> file. In fact the name of the file doesn't
matter, and the file referred to in the URL doesn't have to exist. So,
given the above configuration,
"<tt class="samp">http://myserver/mywebdir/myscript.py</tt>" and
"<tt class="samp">http://myserver/mywebdir/montypython.py</tt>" would give the exact same
result.
<P>
<i>At this point, if you didn't understand the above paragraph, go back and read it again, until you do.</i>
<P>
<DIV CLASS="navigation">
<p><hr>
<table align="center" width="100%" cellpadding="0" cellspacing="2">
<tr>
<td><A href="tut-overview.html"><img src="icons/previous.gif"
border="0" height="32"
alt="Previous Page" width="32"></A></td>
<td><A href="tutorial.html"><img src="icons/up.gif"
border="0" height="32"
alt="Up One Level" width="32"></A></td>
<td><A href="tut-more-complicated.html"><img src="icons/next.gif"
border="0" height="32"
alt="Next Page" width="32"></A></td>
<td align="center" width="100%">Mod_python Manual</td>
<td><A href="contents.html"><img src="icons/contents.gif"
border="0" height="32"
alt="Contents" width="32"></A></td>
<td><img src="icons/blank.gif"
border="0" height="32"
alt="" width="32"></td>
<td><A href="genindex.html"><img src="icons/index.gif"
border="0" height="32"
alt="Index" width="32"></A></td>
</tr></table>
<b class="navlabel">Previous:</b> <a class="sectref" href="tut-overview.html">3.1 Quick Overview of</A>
<b class="navlabel">Up:</b> <a class="sectref" href="tutorial.html">3. Tutorial</A>
<b class="navlabel">Next:</b> <a class="sectref" href="tut-more-complicated.html">3.3 Now something More</A>
<hr>
<span class="release-info">Release 2.7.10, documentation updated on December 07, 2003.</span>
</DIV>
<!--End of Navigation Panel-->
</BODY>
</HTML>
|