Karrigell Documentation

Version 2.3.1 02 09 06

Français

6. 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

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 : 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
  • 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 Subpath

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="%simages/pic.png">' %THIS.up

where THIS.up is a string with 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))