This is a read-only archive. Find the latest Linux articles, documentation, and answers at the new Linux.com!

Linux.com

Feature: Programming

An introduction to CGI scripting with Python

By Robert D. Currier on June 04, 2008 (9:00:00 AM)

Share    Print    Comments   

Mention Common Gateway Interface scripting to a Web developer, and their first response is likely to be "I use Perl." While Perl has long dominated the CGI scripting world, there are other, and perhaps better, tools available. In this tutorial we'll take a look at CGI scripting with Python, a fast, versatile, multi-platform language.

Python is an interpreted, object-oriented language named after the BBC television show "Monty Python's Flying Circus." No johnny-come-lately, Python's first release was in 1991. Developed by Guido van Rossum, Python is the scripting language of choice for many enterprises, including Google, NASA, and ForecastWatch.com.

Getting started

For the purpose of this tutorial, we'll assume that you have minimal experience with Python. Beginners are advised to browse one of the many excellent Python references available online, such as the Python tutorial or the Python reference manual.

Make certain that Python is installed on your development system. From a shell prompt, type python -V. If Python is installed and in your path it should print the version number (we're using 2.5.1) and exit. If you don't have Python installed, use a package management tool such as yum or apt-get to download and install Python from a repository.

Once you've confirmed that Python is installed on your system, the next step is to verify that you have configured your Web server to allow CGI scripting. We'll be using the Apache Web server for our tutorial. If you don't have root access or sudo privileges, you'll need to ask your systems administrator for assistance with the following instructions.

Edit /etc/httpd/conf/httpd.conf. Search for a block of text beginning with #ScriptAlias: This controls which directories contain server scripts. and make certain that your configuration file looks like this:

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" # # "/var/www/cgi-bin" should be changed to whatever your ScriptAliased # CGI directory exists, if you have that configured. # <Directory "/var/www/cgi-bin"> AllowOverride None Options None Order allow,deny Allow from all </Directory>

If your httpd.conf file doesn't exactly match the above text, don't worry. While most installations are configured to allow CGI scripting, your configuration file may have CGI capacity commented out. Check for a '#' character preceding the ScriptAlias directive. If you find one, remove it, save the httpd.conf file, and restart Apache using /etc/init.d/httpd restart.

Your first script

Using a text editor, create a file called example1.py and enter the following lines:

#!/usr/bin/python print "Content-type: text/html" print print "<html>" print "<center>Hello, Linux.com!</center>" print "</html>"

Save the file in /var/www/cgi-bin (you'll need to be root or have sudo access) and make sure that the file is executable by setting permissions with chmod 755 example1.py.

Using a Web browser, open the file by entering the file's URL: http://yourtesthost.com/var/www/cgi-bin/example1.py. Make sure that you don't try to open the file directly using the File -> Open menu selection; you need to retrieve the file via a Web server for this to work. You should see "Hello, Linux.com!" centered in your browser window if all went well. If not, double-check first.py and make sure your code matches our example. It's important that you don't leave out the empty print statement on line three. The Web server requires a blank line following the "Content-type: text/html" entry. The lack of a blank line will result in an internal server error.

An easy way to verify your syntax is to execute the file directly by entering ./example1.py. If your code is correct, Python should execute the file and print the HTML code as plain text. While useful for checking syntax, this technique won't help you debug more advanced CGI scripts. A CGI script won't always perform perfectly from the command line, and a script that executes properly from the command line may crash and burn when invoked by the Web server.

More sophisticated scripts require some additions to your coding toolkit. It's time to take a look at the cgi and cgitb modules.

Getting formal

Included with the standard Python distribution, the cgi and cgitb modules provide enhanced functionality for writing and debugging CGI applications. The cgi module defines several classes, including the FieldStorage class, which we'll use to build our second example: a forms-based script. The cgitb module is a debugger and will prove useful when we start writing scripts longer than a few lines. We'll use cgitb to help us debug our third script.

Our sample script is a short questionnaire that asks two questions and tabulates the results. Follow the same procedure we used in our first example and create a file called example2.py. Copy and paste the following code into example2.py and save the file in /var/www/cgi-bin. Don't forget to make the file executable using chmod 755 second.py.

#!/usr/bin/python import cgi print "Content-type: text/html" print form = cgi.FieldStorage() laptops = form.getvalue('laptops','0') desktops = form.getvalue('desktops','0') print """ <html> <body> <form action='second.py'> How many laptops do you own?&nbsp; <input type='radio' checked name='laptops' value='0' />0&nbsp; <input type='radio' name='laptops' value='1' />1&nbsp; <input type='radio' name='laptops' value='2' />2 <p> How many desktops do you own?&nbsp; <input type='radio' checked name='desktops' value='0' />0&nbsp; <input type='radio' name='desktops' value='1' />1&nbsp; <input type='radio' name='desktops' value='2' />2 <p> <input type='submit' /> <p> You own %d computers. </form> </body> </html>""" % (int(laptops)+int(desktops))

Example2.py differs from our first example in several ways. Note the inclusion of the cgi module on line two and the form creation statement on line five. We'll be using the FieldStorage class to retrieve data from our form as shown in lines six and seven. The rest of example2.py is standard HTML. Make sure example2.py is in your cgi-bin directory and load the URL of example2.py using your Web browser. The file should load and display a two-line questionnaire asking you to list the number of laptop and desktop computers you own. Your answers will be totaled and displayed at the bottom of the form. Try changing your answers and submitting the form to verify proper operation.

Debugging with cgitb

Code that works the first time you test it is always a pleasant surprise, but we're not always that lucky. The standard error messages provided by httpd can be less than helpful when you're trying to track down a problem. Using a debugger like cgitb can mean the difference between puzzling through perplexing error messages and quickly identifying the source of the problem. To demonstrate how helpful cgitb can be, we're going to introduce an error into our second script and use cgitb to sniff out the bad code.

Edit example2.py and scroll to the last line of the file. You'll see a line containing the statement (int(laptops) + int(desktops)). Change the plus sign to a division sign -- (int(laptops) / int(desktops)) -- and save the file. Reload the URL of example2.py with your Web browser. You should see a big difference from the first time we ran this script: you're presented with a blank page. Our introduced error has turned a working script into one that won't execute and that provides no useful debugging output.

Open example2.py and add the following two lines to the top of the file, directly under the import cgi statment:

import cgitb cgitb.enable()

Save the file in /var/www/cgi-bin and reload the URL. Notice the difference? Instead of a blank Web page we now have a detailed report on exactly what is wrong with our sample script. Cgitb tells us that we have a ZeroDivisionError: integer division or modulo by zero. Change the division symbol back to a plus sign, save example2.py, and reload. Example2.py should now function properly.

Admittedly, finding a single incorrect arithmetic operator doesn't take sophisticated debugging skills, and we would have noticed our mistake quickly. Most scripts, however, aren't as short as our example. An incorrect entry in a large and complex script can mean spending hours of debugging time. Cgitb can help you minimize the time spent tracking down typos.

Learning more

We didn't have the space to demonstrate more than a small sample of what Python is capable of when used for CGI scripting, but we hope that we've aroused your interest in learning more. Some good choices for further reading are Magnus Lie Hetland's Beginning Python: From Novice to Professional and O'Reilly's Programming Python, Third Edition by Mark Lutz.

Bob Currier is a senior data engineer at Mote Marine Laboratory in Sarasota, Florida, where he manages a Linux server farm and writes code for a fleet of autonomous underwater vehicles. He is the author of more than 100 features, reviews, and opinion pieces in Linux.com, Network World, ZDnet.com, Smart Computing, and other trade publications.

Share    Print    Comments   

Comments

on An introduction to CGI scripting with Python

Note: Comments are owned by the poster. We are not responsible for their content.

An introduction to CGI scripting with Python

Posted by: Anonymous [ip: 89.175.165.2] on June 04, 2008 10:55 AM
"If not, double-check first.py (???) and make sure your code matches our example."

#

An introduction to CGI scripting with Python

Posted by: Anonymous [ip: 71.253.239.234] on June 04, 2008 02:04 PM
My bad -- I changed the names of the example scripts at the last minute and missed this. There's also one occurrence of 'second.py' instead of 'Example2.py.' Apologies.

-bob currier

#

An introduction to CGI scripting with Python

Posted by: Anonymous [ip: 75.72.96.53] on June 04, 2008 04:05 PM
Don't forget to validate your input. Even in this trivial example, just because the form fields are checkboxes doesn't prevent someone from posting "laptops=foo" to the script, which will make the int() function call raise an exception. To handle those cases, I like to extend FieldStorage with a small getint() method, which works like getvalue() but will check for non-ints and return a default for those cases.

#

An introduction to CGI scripting with Python

Posted by: Anonymous [ip: 67.109.105.226] on June 06, 2008 05:07 PM
Wow, thanks for the flashback to 1994. Python has print statements!

#

This story has been archived. Comments can no longer be posted.



 
Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya