How to Test CGI with Python

106 82
The Test CGI Script

As you know, Python CGI programming relies on the cgi and cgitb modules. Within the cgi module, however, is a little used function that you can use to create a CGI test script.

While debugging software is available for most web servers, such software often puts you out of control of the testing process. This is a program that you can use as a drop-in replacement for any CGI script that is not working.

It is a great way of gathering the salient environment data without weeding your way through Apache's configuration or log files.

#!/usr/bin/pythonimport syssys.stderr = sys.stdoutimport osfrom cgi import escape print "Content-type: text/html"printprint "<html><head><title>Situation snapshot</title></head><body><p>"print "Running:"print "<b>Python %s</b><br><br>" %(sys.version)print "Environmental variables:<br>"print "<ul>"for k in sorted(os.environ):print "<li><b>%s:</b>\t\t%s<br>" %(escape(k), escape(os.environ[k]))print "</ul></p></body></html>" Let's take this apart line-by-line.

Testing CGI With Python: What You Need to Import

The first line is, as you know, the "bang" line (sometimes called the "shebang" line) and tells the web server where to find the interpreter for the program (nb: always use absolute paths for this). If you are on Windows, you should substitute for this line the following:

#!c:/python25/python.exe
After importing the sys module, we redirect all error output (stderror) to the screen (stdout). In this way, we ensure that every problem that Python hits is reflected in the output.

Next we import cgitb and os. cgitb prettifies and reports any errors that are thrown in execution. As we will be working with operating system variables, we need the os module.

Importing cgitb is not enough. One must remember to enable it -- the next line does this.

Finally, we import a single function, escape from the cgi module. The purpose of this function is to escape characters such as ampersand ('&'), greater than ('>'), and less than ('<') to HTML-safe sequences ('$amp;', '>', '<', respectively).

The four subsequent print statements set the framework for the HTML output. The fifth calls on the version function of the sys module to determine the version of Python being used, the compiler used to create the binary, and on what kind of system it is running.

After the output "Environmental variables", we use a for-loop to work through the dictionary os.environ. We bracket this with the "<ul>...</ul>" tags so the output can be in bulleted format.

The keys of the os.environ dictionary change with the environment into which you import the os module. If you use it in a terminal shell, you will get output like this (taken from my terminal session on an Ubuntu Linux system):

COLORFGBG: default;default;0
COLORTERM: rxvt-xpm
DBUS_SESSION_BUS_ADDRESS: unix:abstract=/tmp/dbus-KBLFrpYxUT,guid=29058646df034d11ca95e1b864f6df00
DESKTOP_SESSION: gnome
DISPLAY: :0.0
GDMSESSION: gnome
GDM_XSERVER_LOCATION: local
GNOME_DESKTOP_SESSION_ID: Default
GNOME_KEYRING_SOCKET: /tmp/keyring-PFIVd8/socket
GTK_RC_FILES: /etc/gtk/gtkrc:/home/al/.gtkrc-1.2-gnome2
HISTCONTROL: ignoredups
HOME: /home/al
LANG: en_GB.UTF-8
LANGUAGE: en_GB:en
LESSCLOSE: /usr/bin/lesspipe %s %s
LESSOPEN: | /usr/bin/lesspipe %s
LOGNAME: al
LS_COLORS:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games
PWD: /home/al
SESSION_MANAGER: local/BlackPhoenix:/tmp/.ICE-unix/5343
SHELL: /bin/bash
SHLVL: 2
SSH_AGENT_PID: 5386
SSH_AUTH_SOCK: /tmp/ssh-HdFRPy5343/agent.5343
TERM: rxvt-unicode
USER: al
USERNAME: al
WINDOWID: 77594629
XAUTHORITY: /home/al/.Xauthority


In the case of Apache, you get output similar to the following:
DOCUMENT_ROOT: /var/www
GATEWAY_INTERFACE: CGI/1.1
HTTP_ACCEPT: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
HTTP_ACCEPT_CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.7
HTTP_ACCEPT_ENCODING: gzip,deflate
HTTP_ACCEPT_LANGUAGE: en-gb,en;q=0.5
HTTP_CACHE_CONTROL: max-age=0
HTTP_CONNECTION: keep-alive
HTTP_HOST: 192.168.0.2
HTTP_KEEP_ALIVE: 300
HTTP_USER_AGENT: Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.8.0.11) Gecko/20070327 Ubuntu/dapper-security Firefox/1.5.0.11
PATH: /usr/local/bin:/usr/bin:/bin
QUERY_STRING:
REMOTE_ADDR: 192.168.0.2
REMOTE_PORT: 46164
REQUEST_METHOD: GET
REQUEST_URI: /~al/About.com_Playground/test_cgi.cgi
SCRIPT_FILENAME: /home/al/public_html/About.com_Playground/test_cgi.cgi
SCRIPT_NAME: /~al/About.com_Playground/test_cgi.cgi
SERVER_ADDR: 192.168.0.2
SERVER_ADMIN: webmaster@localhost
SERVER_NAME: 192.168.0.2
SERVER_PORT: 80
SERVER_PROTOCOL: HTTP/1.1
SERVER_SIGNATURE: <address>Apache/2.0.55 (Ubuntu) mod_jk/1.2.14 mod_python/3.1.4 Python/2.4.3 PHP/5.1.2 Server at 192.168.0.2 Port 80</address>
SERVER_SOFTWARE: Apache/2.0.55 (Ubuntu) mod_jk/1.2.14 mod_python/3.1.4 Python/2.4.3 PHP/5.1.2
This for-loop will work on Python 2.4 and later. If it does not work for you, you may find that your Python installation needs updating. In the meantime, you can substitute these three lines for the one beginning "for k in...":

keys = os.environ.keys()keys.sort()for k in keys:
With either for-loop, you will get the same output. The result will be a small Python CGI script that you can use anywhere to figure out the environment in which you are programming. I should note in closing that parts of this tutorial were inspired by the coding of Jeff Bauer and Carey Evans and their script of a similar nature.


Source...
Subscribe to our newsletter
Sign up here to get the latest news, updates and special offers delivered directly to your inbox.
You can unsubscribe at any time

Leave A Reply

Your email address will not be published.