6. Programming
There are many programming styles to write programs in Karrigell :
They are are described in the documentation. You can also add the support for other
kinds of scripts : if you want to manage 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
The principle of programming with Karrigell is simple :
All the necessary
data are available in the namespace where the script is run
This namespace is prepared by Karrigell before the script is executed. For instance,
the script can use the built-in name HEADERS to get the HTTP header values
6.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 sent by the server :
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
Role() is a function that returns the user's role, as defined in the
built-in user management framework (see the chapter on authentication)
COOKIE is a dictionary-like SimpleCookie objet (in Python Cookie
module) that stores the cookies sent by the web browser with the HTTP request
SET_COOKIE is another SimpleCookie objet to which you can set keys and values
which will be stored by the web 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
6.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
6.3 Smart urls
The normal way to pass parameters to a script is to use query strings in the url, or
post data. An alternative is to pass parameters as a part of the url, like in
http://host/path/script.py/foo/bar ; here the parameters to the script are
foo and bar
In the script you can access these parameters as a list ; it is an attribute of THIS,
THIS.subpath :
print "The parameters are %s" %THIS.subpath
A problem with these urls is that if you want to use Include or write a relative link
or insert an image or a JavaScript, the url must be different if the script was called
without a subpath or with any number of parameters in the subpath
For instance if you write this relative url in the script :
print '<IMG SRC="images/pic.png">'
and you call the script with http://host/path/script.py/foo/bar, the browser
will compute the absolute url http://host/path/script.py/foo/images/pic.png,
and execute the same script with the parameters foo,images,pic.png - not what you
want !
So if you plan to pass parameters in a subpath, you must write the relative url this way :
print '<IMG SRC="%s">' %THIS.rel("images/pic.png")
THIS.rel prepends to the relative url provided as argument as many
'../' as the number of parameters
6.4 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()
6.5 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
6.6 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))
|