5. Programming
There are many programming styles to write programs in Karrigell :
They are are described in the documentation ; all of them share the same way of accessing the
HTTP environment and the form fields
You can also add the support for other kinds of scripts : if you want to manage
the scripts with the extension .foo , you have to write a module called
mod_foo . See the example of mod_tmpl.py to manage the Cheetah
templating system
5.1 Accessing HTTP environment
Access to the HTTP environment is provided through global variables available in the script's
namespace :
HEADERS is a dictionary with the HTTP headers : the key is the header name, the
value is the header's value. For instance HEADERS["accept-language"] will return the
value of the accept-language header
RESPONSE is a dictionary in which you'll set values for the response header that
will be sent to the server. This dictionary is insensitive to the case of the keys :
RESPONSE['Content-type'] and RESPONSE['CONTENT-type'] return the same result
AUTH_USER and AUTH_PASSWORD are values used for authentication
SET_COOKIE is a dictionary-like SimpleCookie objet (in Python Cookie
module) to which you can set values which will be stored by the user's browser as cookies
ACCEPTED_LANGUAGES is a list of languages accepted by the user's browser, ordered
by preference. The items are two-character strings identifying the language, according to the ISO
639 codification (en for English, fr for French, etc)
- For advanced use,
REQUEST_HANDLER represents the current RequestHandler instance.
It exposes attributes such as client_address , a tuple with the client IP address and
port. See the documentation for the BaseHTTPServer and SimpleHTTPServer
modules in Python standard distribution
THIS is an instance of the class Script (in Template.py) representing the current
script
5.2 Form fields
The QUERY variable is a dictionary representing the query string if the script is
called with the HTTP GET method, or the fields of a form submitted with the HTTP
POST method. QUERY keys are the name of the fields, and values are either the
value of the field as a string, or a list of values if the field name ends with [] (if
it comes from a <SELECT MULTIPLE> form field for instance)
Suppose you have an HTML form such as :
<form action="myScript.py">
Spam <input name="spam">
<br><select multiple name="animal[]">
<option value="dog">Dog
<option value="cat">Cat
<option value="frog">Frog
</select>
<br><input type="submit" value="Ok">
</form>
In myScript.py the input would be displayed with :
print "<br>Spam is ",QUERY["spam"]
if QUERY.has_key("animal"):
print "<br>Animal is ",str(QUERY["animal"])
Access to these data is available through a shortcut, consisting in the underscore _
prepended to the field name. The code above could be written in this simpler way :
print "<br>Spam is ",_spam
if QUERY.has_key("animal"):
print "<br>Animal is ",str(_animal)
The underscore is introduced to reduce the risks of naming conflicts with Python reserved words or
with the name of frequently used modules
5.3 File uploads
To upload a file from the client to the server, the input tag must have the type "file". For
instance, the html form will look like this :
<FORM ENCTYPE="multipart/form-data" ACTION="fileUpload.py" METHOD=POST>
File to process: <INPUT NAME="myfile" TYPE="file">
<INPUT TYPE="submit" VALUE="Send File">
</FORM>
The script which has to handle the file upload will use the variable
QUERY['myfile'] or _myfile , which is an instance of the
class FieldStorage in the built-in cgi module.
This object has two useful attributes :
filename : the name of the file
file : a file-like object from which you can read the file content
For instance if you want to store the file in the server's file system, with the
same name as the original file :
import os
f = _myfile.file # file-like object
dest_name = os.path.basename(_myfile.filename)
out = open(dest_name,'wb')
# copy file
import shutil
shutil.copyfileobj(f,out)
out.close()
5.4 Exceptions
In Python scripts you can raise special exceptions which are handled by Karrigell
SCRIPT_END
Use this if you want to stop sending output to the browser without having to process the end of
the file. This can be useful if you're debugging a script and want to stop its execution at some
place
in your script to see the state of some variables
myVar=10
...
print myVar
raise SCRIPT_END
... (rest of code - won't be run)
SCRIPT_ERROR
Use raise SCRIPT_ERROR,msg to stop the execution of script and write msg
HTTP_ERROR
raise HTTP_ERROR,(errorCode,errorMessage) causes Karrigell to send an HTTP error
message with the specified error code and message
HTTP_REDIRECTION
raise HTTP_REDIRECTION,uri causes Karrigell to redirect the request to the given
URI
5.5 HTMLStream
HTMLStream is a class in the HIP module which makes printing easier than
with repetitive print statements. It is the same idea as
HTML Inside Python but implemented otherwise
Create an instance of this class :
import HIP
H = HIP.HTMLStream()
Then use "+" and "-" to print data to the standard output : with "+" the string representation
of data is printed ; with "-", it is cgi-escaped
aDict={"one":"unan","two":"daou","three":"tri"}
H + aDict - type(aDict)
is the same as :
aDict={"one":"unan";"two":"daou";"three":"tri"}
print str(aDict),cgi.escape(type(aDict))
|