Writing CGI Scripts in Python

 in
This article is neither a Python tutorial nor a CGI tutorial, but a “Python Presentation from a CGI perspective”.
Documentation and Availability
  • The Python home page is located at http://www.python.org/. On the site there is a list of mirror sites, and the current distribution of Python.

  • A tutorial and other documents including the Language Reference, Library Reference, a guide on how to extend and embed the interpreter and a FAQ can be found in the doc directory of the Python Home Page (http://www.python.org/doc/).

  • Two books will soon be available about Python:

    • Programming Python, by Mark Lutz, O'Reilly and Associates Publishers.

    • Internet Programming with Python, by Aaron Watters, Guido Van Rossum (the author of the language) and James Ahlstrom, from MIS Press/Henry Holt Publishers. See http://www.python.org/python/arwbook.html.

  • And finally, there's a newsgroup devoted to Python: comp.lang.python.

CGI Scripts

In the following text, I will assume that you run your own HTTP daemon locally. My preference is Apache, but any server will do the work, if properly configured.

And of course, you should have installed Python on your system. You'll need to configure it to use the gdbm module, since it's used in count.py.

For the examples of scripts which interface with a relational database, I've used PostGres95 (and its contributed Python module, PyGres95). PostGres95 is available from http://www.ki.net/postgres95/. PyGres95 is available from http://zen.via.ecp.fr/via_dvpt/products/pygres.html.

To understand the following text, you should know how to write an HTML page, have a general idea of how CGI works, and have a little background with C programming.

Common Scripts

Listing 3, helloworld.py, is our first script. It's very simple. Run from the command line, it will print an HTML document. But you should copy it to your cgi-bin directory, then call it from your browser with the URL http://localhost/cgi-bin/script.py.

This script displays a little message and the local time. Here, you need to note only one thing: the script must send a header describing the contents of the document. This is done by the means of the Content-type header. Common values include text/html, text/plain, image/gif or image/jpeg. The header is terminated by a blank line. It is used by the client browser, and won't appear in the generated page. And, as you'll see, the script is executed, and not just displayed in the browser. Everything printed to sys.stdout by the script will be sent to the client, while error messages will go to an error log (/usr/local/etc/httpd/logs/error_log, if you are using Apache).

Listing 4 is the well-known Count script written in Python. This is used to display a graphical counter of the number of times that a particular page has been accessed.

This script imports a module called cgi, which I'll describe later. It's used to retrieve the URL parameter passed to the script. This script interfaces with gdbm (which must be included in the modules list when Python is configured) to store { URL ; access count } couples.

This is our first introduction to Python dictionaries. A dictionary is generally referred to as an “associative array” in the literature. It means that you can access arrays by keys instead of indices. For example, if you want to handle an e-mail address book, with couples like these:

"Michel", "Michel.Vanaken@ping.be"
"Veronique", "Vero@home.sweet.home"

Here is how you should retrieve the address of Michel in C and in Python:

struct {
        char    *key ;
        char    *addr ;
} email[ MAX ] ;
int     i ;
for( i=0 ; i<MAX ; i++ ) {
  if( strcmp( email[ i ].key, "Michel" ) = 0 ) {
            printf( "%s\n", email[ i ].addr ) ;
            break ;
  }
}
if( i = MAX ) {
        printf( "Not found\n" ) ;
}
if email.has_key( "Michel" ) :
        print email[ "Michel" ]
else :
        print "Not found"

Adding an entry with Python is also very easy :

email[ "Homer" ] =  \
"HSimpson@Springfield.power_plant.com"

adds an entry if Homer is not a valid key, and overwrites the old value if it is already present.

We see that Content-type here is image/x-bitmap (since the browser is waiting for an <img src=...>).

Of course, the bitmaps aren't very pretty (I drew them with a paint package, saved them as xbm files, then used a lot of keyboard macros and M-Kill/Yank rectangles in Emacs). The goal of this script is not to reinvent the wheel, but to allow readers to compare it with other versions widely available on the Net in different languages.

In order to use this script, the gdbm database must be created. Change the current directory to your cgi-bin directory, run Python, and type:

import gdbm
gdbm.open( "counters.gdbm", "n", 0666 )

and exit Python with Ctrl-D.

It should also be noted that the xbm file created by this script is bad. It contains an extraneous byte (added in the print_footer() function), in order to simplify the print_digit_values() function (in this version, there are no tests for commas).

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Thanks for tutorial! I found a syntax error.

Anonymous's picture

Thanks for the tutorial. :)

There is a syntax error in listing 7, in the line "if len( fields ) = 0 :". You probably see it now, it should have been "==" and not "=" - we need the comparison operator, not the assignment operator.

-Nobody

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState