Introduction to programming with Karrigell
To install Karrigell,
download the package, then either unzip it and run python Karrigell.py,
or if you are on Windows, install it with the Windows installer. In both cases, you will
have the built-in server running on port 80, and you can create programs with a text
editor, saving them in the directory www of the distribution
1. Hello,world !
We start with the Python script which prints the message "Hello world !"
To create this program, use a text editor, save the above code in a file called hello.py in the www folder of your Karrigell distribution. Then enter http://localhost/hello.py in your web browser to see the result
Note that the script is exactly the same as the "Hello, world" program in the Python interpreter ; you don't have to import any module to start writing programs
2. The execution namespace
Now we want to print the message "Hello world" as plain text instead of HTML.
For this the Content-type header must be set to
text/plain instead of the default text/html
The difference with the first script is the line where the value
text/plain is set for the key Content-Type of the variable
RESPONSE. You may wonder where this variable comes from ? Well,
Karrigell prepares an execution namespace before running the scripts ;
RESPONSE is one of the built-in variables in this namespace, its
function is to receive the values for the HTTP response header
3. User input
Here is a simple form where the user can enter a value and send it to a script on the server
You can see the result in the frame below
In the Python script you see that user data can be retrieved using a dictionary called REQUEST, prepared by Karrigell to be present in the execution namespace. It maps field names to their value. Additionaly, a shortcut can be used : the field name with a leading undercore (_)
Now let's see how we would manage a form with the POST method instead of GET :
The script is exactly the same as for GET requests : Karrigell manages transparently the acquisition of user data with GET and POST requests
4. Request headers - using HTMLTags
Now we want to print the request headers. They are available in the
built-in variable HEADERS. If we want to display them in an
HTML table, we can of course print the HTML code directly with statements
like
print "<tr><td>%s</td><td>%s</td></tr>" %(key,value)
but the code rapidly becomes difficult to read if there are many lines
like this
Karrigell provides a built-in module, HTMLTags, which
simplifies the preparation of HTML output. Let's see this in the example
below
All HTML tags have an equivalent as a class in the HTMLTags module,
which has the same name as the tag in uppercase letters. For instance,
the expression print TD(value) produces the code to
generate a cell with the specified value :
<TD>value</TD>
TD(value,align="left")
5. Environment data
The environment data, as defined in the CGI specification, are available
in the built-in dictionary ENVIRON :
6. Session management
The usual way to keep track of a user while he is browsing a web application is to use sessions. The server manages a session object which holds all useful information ; this session object is identified by a session identifier, a string which is stored as a cookie in the user's browser
Karrigell manages sessions using a built-in function called
Session(), which returns the session object. Lets' see how it
works in the examples below
The session object is initialized the first time the Session()
function is called by the script for a particular user ; this is done in the
first Python script above. In the next one, the information stored in the
session object is retrieved very easily as an attribute of the session object
returned by the function Session()
7. Karrigell services
A web application typically consists of a set of pages ; the user navigates from a page to another following links or clicking on button to submit forms to the server
Instead of having one script per page, Karrigell provides a format to manage a whole web application in a single script : they are called "Karrigell services" and have the extension ".ks" instead of ".py" for pure Python scripts
The example below shows a simple application to edit a value
When the script is called by its url (for instance
http://host/folder/script.ks) the frameworks looks for a function
index() in the script, and if so redirects to the url
http://host/folder/script.ks/index
The function is executed in a namespace which includes the values defined
at the global level of the script, here the variable so
The links in index() are given as relative urls ; the browser
resolves them in absolute urls, like
http://host/folder/script.ks/increment. When this url is called,
the function increment is executed, then an HTTP redirection is
performed to the index() function
8. Redirection
In the Karrigell service above, you have noticed the way HTTP redirections
are managed : once the value is set, the built-in exception
HTTP_REDIRECTION is raised, with the url where user should be
redirected
9. User authentication
The administrator can manage a database of users (accessible through the Admin menu). Users can have different roles : admin, edit, visit
In an application, calling the function Login(role_list)
checks if the user is authenticated with one of the roles defined in
role_list (if not specified, role_list defaults
to ["admin"])
If he is not yet logged in with this role, the application redirects to a script that checks login and password, then redirects to the application
The function Role() returns the user role (None
if user is not logged in). The function Logout() is used to log out
To run the script below, you will have to log in as the site administrator
10. Files and directories
In a shared environment like a web server, requests can be managed in
different threads or processes. When a script is executed, it is not
reliable to set the current directory (by os.chdir) to the
folder where the script stands, because another thread could modify it before
the script is finished
So you must be careful if a script has to open files :
- you can provide a relative path to the built-in functions
open()orfile(): they are modified by Karrigell so that relative paths are translated to absolute path, relatively to the script folder - you can use the built-in value
CWDwhich provides the absolute path of the script directory - or you can use the built-in function
REL()which converts a relative path to an absolute path, relatively to the script directory
11. Exceptions and errors
When an exception or an error is detected in a page, an explicit traceback is printed
The example below shows how it works
12. Importing modules
Modules in Python standard distribution can be safely imported by the usual syntax :
import os
For user-defined modules located inside the application folders, you can't use this syntax : the path where the interpreter searches for a module with the specified name is liable to change at any time in a multithreaded environment
For these modules, you must use the built-in function Import(url)
where url is the relative (to current script) or absolute url of the module
The return value of Import must be bound to a name, which will be used
as the module name
Module conv_date.py
13. Including other scripts
Inside a script, other static documents or the output of other scripts can be included,
using the built-in Include(other_url)
For a static document, simply use Include("static.html")
For a script, you can pass keyword arguments, they will be present in the namespace where the included script is run. For instance, to include a header with the user name :
Script header.py