Home arrow Python arrow Page 6 - Writing CGI Programs in Python

Putting the pieces together - Python

And now for something completely different... Python has a very extensive, well documented and portable module library that provides a large variety of useful functions. The Internet-related collection is particularly impressive, with modules to deal with everything from parsing and retrieving URL's to retrieving mail from POP servers and everything in between.

TABLE OF CONTENTS:
  1. Writing CGI Programs in Python
  2. Why should my next CGI project be in Python?
  3. Your First CGI program in Python
  4. Getting some real work done
  5. Defining a useful Display function
  6. Putting the pieces together
  7. Simple Database Access
  8. Other Resources and Links
By: Preston Landers
Rating: starstarstarstarstar / 78
August 25, 1999

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement
Let's review what we've covered so far. We've learned how to get information from the user via a CGI form and we've learned how to print out information in a nicely formatted HTML page. Let's put these two separate bits of knowledge together into one program that will prompt the user with a form, and then print out the information submitted by that form.

We're going to go ahead and get fancy and use two templates this time ... one, the same generic site template as before, and the other template will contain our form that will be presented to the user.

form.html

<FORM METHOD="POST" ACTION="sample1.py"> <INPUT TYPE=HIDDEN NAME="key" VALUE="process"> Your name:<BR> <INPUT TYPE=TEXT NAME="name" size=60> <BR> Email: (optional)<BR> <INPUT TYPE=TEXT NAME="email" size=60> <BR> Favorite Color:<BR> <INPUT TYPE=RADIO NAME="color" VALUE="blue" CHECKED>Blue <INPUT TYPE=RADIO NAME="color" VALUE="yellow">No, Yellow... <INPUT TYPE=RADIO NAME="color" VALUE="swallow">What do you mean, an African or European swallow? <P> Comments:<BR> <TEXTAREA NAME="comment" ROWS=8 COLS=60> </TEXTAREA> <P> <INPUT TYPE="SUBMIT" VALUE="Okay"> </FORM>

We'll use the same generic template file from before.

Here is the program itself:

sample1.py:

#!/usr/bin/python import re import cgi # specify the filename of the template file TemplateFile = "template.html" # specify the filename of the form to show the user FormFile = "form.html" # Display takes one parameter - a string to Display def Display(Content): TemplateHandle = open(TemplateFile, "r") # open in read only mode # read the entire file as a string TemplateInput = TemplateHandle.read() TemplateHandle.close() # close the file # this defines an exception string in case our # template file is messed up BadTemplateException = "There was a problem with the HTML template." SubResult = re.subn("<!-- *** INSERT CONTENT HERE *** -->", Content,TemplateInput) if SubResult[1] == 0: raise BadTemplateException print "Content-Type: text/html\n\n" print SubResult[0] ### what follows are our two main 'action' functions, one to show the ### form, and another to process it # this is a really simple function def DisplayForm(): FormHandle = open(FormFile, "r") FormInput = FormHandle.read() FormHandle.close() Display(FormInput) def ProcessForm(form): # extract the information from the form in easily digestible format try: name = form["name"].value except: # name is required, so output an error if # not given and exit script Display("You need to at least supply a name. Please go back.") raise SystemExit try: email = form["email"].value except: email = None try: color = form["color"].value except: color = None try: comment = form["comment"].value except: comment = None Output = "" # our output buffer, empty at first Output = Output + "Hello, " if email != None: Output = Output + "<A HREF="mailto:" + email + "">" + name + "</A>.<P>" else: Output = Output + name + ".<P>" if color == "swallow": Output = Output + "You must be a Monty Python fan.<P>" elif color != None: Output = Output + "Your favorite color was " + color + "<P>" else: Output = Output + "You cheated! You didn't specify a color!<P>" if comment != None: Output = Output + "In addition, you said:<BR>" + comment + "<P>" Display(Output) ### ### Begin actual script ### ### evaluate CGI request form = cgi.FieldStorage() ### "key" is a hidden form element with an ### action command such as "process" try: key = form["key"].value except: key = None if key == "process": ProcessForm(form) else: DisplayForm()

Notice that we defined the function Display() again. This isn't really necessary; in fact, it's a bad idea to cut-n-paste code from one script to another. A far better solution (which I will show you later) is to put all your functions that are common to multiple scripts in separate file. That way, if you want to improve or debug the function later, you don't have to hunt for each occurrence of it in all of your scripts. However, we can get away with it for this learning exercise.

Note that since Python is a dynamically interpreted language, functions have to be defined before they can be used. That's why the first thing this program does is define its functions.

The DisplayForm() function is very simple and uses the same principle as the Display() function (which it, of course, calls upon to do most of the hard work.) Using these kinds of functions rather than embedding static HTML forms will save you an incredible amount of aggravation. Sometimes, of course, you'll need to generate HTML on-the-fly; we'll talk about that later.

The ProcessForm() function has two main parts. The first extracts values from the <INPUT> fields of the form and stores them in regular variables. This is the section of your program logic where you validate the information in the form to make sure it is kosher by your application's definition.

It is a VERY bad idea to use form data provided by random people on the web without validating it; especially if you're going to use that data to execute a system command or for acting on a database. Naively written CGI scripts, in any language, are a favorite target for malicious system crackers. At the minimum, make sure form information doesn't exceed a certain appropriate length. Passing huge strings to external programs where they aren't expected can cause buffer overflows which can lead to arbitrary code execution by a clever cracker. We will be discussing security in greater detail in the next article. Fortunately, Python makes it easy to write scripts securely.

In our program, we enclose these validation statements in try: and except: blocks because if the value isn't present, it will generate an exception, which could potentially stop your program. In this case, we catch the exception if a given field was left blank (or simply not in the original form.) That variable will be assigned the None value, which has special meaning in Python. (By definition, it is the state of not having a value, similar to NULL in other languages.) A special case is the "name" field; we've decided that that field is absolutely required. If "name" is not given, then the program will use its Display() method to print a helpful message to the user: "Please go back and try again." It then raises the exception SystemExit, which in effect, stops the script then and there.

Once we have validated all of our form input, we can act on it however we choose. In this case, we just want to print a simple message acknowledging receipt of the information. We set up an empty string to use as a buffer for our output, and we begin adding to it. We can conditionally include stuff in this buffer depending on whether or not a value is defined is None. Sharp observers will note that we cheated a bit and put a little actual HTML directly in our code. Again, this is not ideal, but we can get away with it in this learning exercise. The next article in this series will address using objects to avoid the problems of embedding HTML directly in output statements.

The actual main part of the script follows the function definitions, and is very simple. We obtain the form, and conditionally execute one of our two action functions depending on the value of a hidden form element called "key". We know that if this key is present, and it is set to the value "process," we'll want to process the form. Otherwise, we'll just display the form. If you're not sure what I mean by hidden key, go back and look at our form.html template carefully.



 
 
>>> More Python Articles          >>> More By Preston Landers
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PYTHON ARTICLES

- Python Big Data Company Gets DARPA Funding
- Python 32 Now Available
- Final Alpha for Python 3.2 is Released
- Python 3.1: String Formatting
- Python 3.1: Strings and Quotes
- Python 3.1: Programming Basics and Strings
- Tuples and Other Python Object Types
- The Dictionary Python Object Type
- String and List Python Object Types
- Introducing Python Object Types
- Mobile Programming using PyS60: Advanced UI ...
- Nested Functions in Python
- Python Parameters, Functions and Arguments
- Python Statements and Functions
- Statements and Iterators in Python

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: