Writing CGI Scripts in Python
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.
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.
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).
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- New Products
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- another very interesting
1 min 1 sec ago - Reply to comment | Linux Journal
1 hour 54 min ago - Reply to comment | Linux Journal
8 hours 48 min ago - Reply to comment | Linux Journal
9 hours 4 min ago - Favorite (and easily brute-forced) pw's
10 hours 55 min ago - Have you tried Boxen? It's a
16 hours 47 min ago - seo services in india
21 hours 19 min ago - For KDE install kio-mtp
21 hours 20 min ago - Evernote is much more...
23 hours 20 min ago - Reply to comment | Linux Journal
1 day 8 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
Thanks for tutorial! I found a syntax error.
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