logo

Python CGI Programming


Show

The Common Gateway Interface (CGI) is a set of standards in the Python programming language. The CGI defines how the information would be communicated between the web server and a custom script. The CGI specifications are at present administered by the NCSA.

What is CGI?

  • CGI stands for Common Gateway Interface
  • It is a standard for external gateway programs
  • CGI is an interface between HTTP servers for exchanging information
  • The current version is CGI/1.1 and CGI/1.2
  • It equips web browsing

To recognize the idea of CGI, we have taken the example of web surfing. When a user clicks on a hyperlink to browse a particular web page or URL, the respective browser contacts the HTTP web server and requests for the URL, i.e., filename. The HTTP server, called as web server parses the URL and waits for the filename. If it discovers that file then drives it back to the browser, or else sends an error message representative that you requested a wrong file.

Web browser seizes its own time to respond from the webserver. Therefore, the results that are displayed contain received files or error messages. However, it is likely to system the HTTP server so that at any time a file in a positive directory is demanded that file is not sent reverse; instead it is executed as an agenda, and whatever that program productions is sent reverse for your browser to put on a show. This function is recognized as the Common Gateway Interface or CGI and the lines up are known CGI scripts. These CGI programs are able to offer Python Script, C or C++ program, PERL Script, Shell Script, etc.

CGI Architecture Diagram

Web Server Support and Configuration

Before you go on with CGI Programming, confirm that your Web Server carries CGI and it is arranged to handle CGI Programs. All the CGI Programs to be executed by the HTTP server are kept in a pre-configured directory. This directory is called CGI Directory and by convention, it is named as /var/www/cgi-bin. By convention, CGI files have extensions as.CGI so that users can keep your files with python extension .py as well.

By default, the Linux server is configured to run only the scripts in the CGI-bin directory in /var/www. If you want to specify any other directory to run your CGI scripts, comment on the following lines in the httpd.conf file-

#!/usr/bin/python

print "Content-type:text/html\r\n\r\n"
print ''
print ''
print ''
print ''
print ''
print '

Hello World! This is my first CGI program

'
print ''
print ''

Here, we assume that you have Web Server up and running successfully and you are able to run any other CGI program like Perl or Shell, etc.

First CGI Program

Here is a simple link, which is linked to a CGI script called hello.py. This file is kept in /var/www/cgi-bin directory and it has the following content. Before running your CGI program, make sure you have to change the mode of the file using chmod 755 hello.py UNIX command to make the file executable.

#!/usr/bin/python

print "Content-type:text/html\r\n\r\n"
print ''
print ''
print ''
print ''
print ''
print '

Hello World! This is my first CGI program

'
print ''
print ''

If you click hello.py, then this produces the following output

Hello World! This is my first CGI program

This hello.py script is a easy Python script, which writes its production on STDOUT file, i.e., monitor. There is one imperative and added feature accessible which is initial line to be printed Content-type:text/html\r\n\r\n. This procession is sent reverse to the browser and it specifies the pleased type to be demonstrated on the browser display.

By now, you have to unspoken basic idea of CGI and you know how to write numerous complicated CGI lists using Python. This script container interacts with several other external system also to swap information such as RDBMS.

HTTP Header

The line Content-type:text/html\r\n\r\n is part of HTTP header which is sent to the browser to understand the content. All the HTTP header will be in the following form:

HTTP Field Name: Field Content

For Example

HTTP Field Name: Field Content

For Example
Content-type: text/html\r\n\r\n

There are few other important HTTP headers, which you will use frequently in your CGI Programming.

Sr.No.

Header & Description

1

Content-type:

A MIME string defining the format of the file being returned. Example is Content-type:text/html

2

Expires: Date

The date the information becomes invalid. It is used by the browser to decide when a page needs to be refreshed. A valid date string is in the format 01 Jan 1998 12:00:00 GMT.

3

Location: URL

The URL that is returned instead of the URL requested. You can use this field to redirect a request to any file.

4

Last-modified: Date

The date of last modification of the resource.

5

Content-length: N

The length, in bytes, of the data being returned. The browser uses this value to report the estimated download time for a file.

6

Set-Cookie: String

Set the cookie passed through the string

CGI Environment Variables

All the CGI programs have entre to the following environment variables. These variables play an important role while writing any CGI program.

Sr.No.

Variable Name & Description

1

CONTENT_TYPE

The data type of the content. Used when the client is sending attached content to the server. For example, file upload.

2

CONTENT_LENGTH

The length of the query information. It is available only for POST requests.

3

HTTP_COOKIE

Returns the set cookies in the form of key & value pair.

4

HTTP_USER_AGENT

The User-Agent request-header field contains information about the user agent originating the request. It is name of the web browser.

5

PATH_INFO

The path for the CGI script.

6

QUERY_STRING

The URL-encoded information that is sent with GET method request.

7

REMOTE_ADDR

The IP address of the remote host making the request. This is useful logging or for authentication.

8

REMOTE_HOST

The fully qualified name of the host making the request. If this information is not available, then REMOTE_ADDR can be used to get IR address.

9

REQUEST_METHOD

The method used to make the request. The most common methods are GET and POST.

10

SCRIPT_FILENAME

The full path to the CGI script.

11

SCRIPT_NAME

The name of the CGI script.

12

SERVER_NAME

The server's hostname or IP Address

13

SERVER_SOFTWARE

The name and version of the software the server is running.

Here is small CGI program to list out all the CGI variables. Click this link to see the result Get Environment

#!/usr/bin/python

import os

print "Content-type: text/html\r\n\r\n";
print "Environment<\br>";
for param in os.environ.keys():
   print "%20s: %s<\br>" % (param, os.environ[param])

GET and POST Methods

Users have to encounter many states when you call for bypassing some information from your browser to the web server and eventually to your CGI Program. Most regularly, the browser uses two techniques two go by this information to a web server. These techniques are GET Method and POST Method.

Passing Information using GET method

The GET method sends the encoded user information appended to the page request. The page and the encoded information are separated by the - character as follows:

http://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2

The GET technique is the default way to pass in turn from browser to web server and it creates a long string that emerges in your browser's Location: box. Never employ the GET method if you have a password or other responsive information to devolve the server. The GET method has a size curb: only 1024 characters can be sent in a request string. The GET method sends information using the QUERY_STRING header and will be accessible in your CGI Program through the QUERY_STRING environment variable.

You can pass information by simply concatenating key and value pairs along with any URL or you can use HTML

tags to pass information using the GET method.

Simple URL Example: Get Method

Here is a simple URL, which passes two values to the hello_get.py program using the GET method.

/cgi-bin/hello_get.py?first_name=ZARA&last_name=ALI

Below is the hello_get.py script to handle input given by the web browser. We are going to use a CGI module, which makes it very easy to access past information

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
first_name = form.getvalue('first_name')
last_name  = form.getvalue('last_name')

print "Content-type:text/html\r\n\r\n"
print ""
print ""
print ""
print ""
print ""
print "
Hello %s %s
" % (first_name, last_name)
print ""
print ""

This would generate the following result:

Hello MACK ALI
Simple FORM Example:GET Method

This example passes two values using HTML FORM and submit button. We use same CGI script hello_get.py to handle this input.

<form action = "/cgi-bin/hello_get.py" method = "get">
First Name: <input type = "text" name = "first_name">  <br />

Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />

Here is the actual output of the above form, you enter First and Last Name and then click submit button to see the result.

First Name:
Last Name:

Passing Information Using POST Method

A usually more dependable method of transient information to a CGI agenda is the POST method. This wraps up the information inaccurately the identical way as GET methods, but in place of sending it as a text string after a ? in the URL, it sends it as a separate message. This message comes into the CGI script in the form of the standard input.

Below is the same hello_get.py script which handles GET as well as the POST method.

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
first_name = form.getvalue('first_name')
last_name  = form.getvalue('last_name')

print "Content-type:text/html\r\n\r\n"
print ""
print ""
print ""
print ""
print ""
print "
Hello %s %s
" % (first_name, last_name)
print ""
print ""

Let us take again the same example as above, which passes two values using HTML FORM and submit button. We use the same CGI script hello_get.py to handle this input.

<form action = "/cgi-bin/hello_get.py" method = "post">
First Name: <input type = "text" name = "first_name"><br />
Last Name: <input type = "text" name = "last_name" />

<input type = "submit" value = "Submit" />

Here is the actual output of the above form. You enter First and Last Name and then click submit button to see the result.

First Name:
Last Name:

Passing Checkbox Data to CGI Program

Checkboxes are used when more than one option is required to be selected.

Here is an example HTML code for a form with two checkboxes:

<form action = "/cgi-bin/checkbox.cgi" method = "POST" target = "_blank">
<input type = "checkbox" name = "maths" value = "on" /> Maths
<input type = "checkbox" name = "physics" value = "on" /> Physics
<input type = "submit" value = "Select Subject" />

The result of this code is the following form

Maths Physics

Below is checkbox.cgi script to handle input given by the web browser for the checkbox button.

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
if form.getvalue('maths'):
   math_flag = "ON"
else:
   math_flag = "OFF"

if form.getvalue('physics'):
   physics_flag = "ON"
else:
   physics_flag = "OFF"

print "Content-type:text/html\r\n\r\n"
print ""
print ""
print ""
print ""
print ""
print "
CheckBox Maths is : %s
" % math_flag
print "
CheckBox Physics is : %s
" % physics_flag
print ""
print ""

Passing Radio Button Data to CGI Program

Radio Buttons are used when only one option is required to be selected.

Here is an example HTML code for a form with two radio buttons

<form action = "/cgi-bin/textarea.py" method = "post" target = "_blank">
<textarea name = "textcontent" cols = "40" rows = "4">
Type your text here...

<input type = "submit" value = "Submit" />

The result of this code is the following form:

Passing Text Area Data to CGI Program

TEXTAREA element is used when multiline text has to be passed to the CGI Program.

Here is an example HTML code for a form with a TEXTAREA box:

<form action = "/cgi-bin/textarea.py" method = "post" target = "_blank">
<textarea name = "textcontent" cols = "40" rows = "4">
Type your text here...

<input type = "submit" value = "Submit" />

The result of this code is the following form

Below is textarea.cgi script to handle input given by web browser:

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
if form.getvalue('textcontent'):
   text_content = form.getvalue('textcontent')
else:
   text_content = "Not entered"

print "Content-type:text/html\r\n\r\n"
print ""
print "";
print ""
print ""
print ""
print "
Entered Text Content is %s
" % text_content
print ""

Passing Drop Down Box Data to CGI Program

Drop Down Box is used when we have many options available but only one or two will be selected.

Here is an example HTML code for a form with one drop-down box:

<form action = "/cgi-bin/radiobutton.py" method = "post" target = "_blank">
<input type = "radio" name = "subject" value = "maths" /> Maths
<input type = "radio" name = "subject" value = "physics" /> Physics
<input type = "submit" value = "Select Subject" />

The result of this code is the following form:

Maths Physics

Below is radiobutton.py script to handle input given by web browser for radio button:

#!/usr/bin/python

# Import modules for CGI handling 
import cgi, cgitb 

# Create instance of FieldStorage 
form = cgi.FieldStorage() 

# Get data from fields
if form.getvalue('subject'):
   subject = form.getvalue('subject')
else:
   subject = "Not set"

print "Content-type:text/html\r\n\r\n"
print ""
print ""
print ""
print ""
print ""
print "
Selected Subject is %s
" % subject
print ""
print ""

Using Cookies in CGI

HTTP is a situation protocol. For a marketable website, it is entailed to preserve session information among diverse pages. For example, one consumer registration finishes after implementation many pages.

How maintain user's session information across all the web pages?

In numerous situations, cookies is the mainly resourceful method of detection and tracking favorites, purchases, payments, and other information wanted for better visitor knowledge or site statistics.

How does It work?

Your server propels some information to the visitor's browser in the shape of a cookie. The browser may believe the cookie. If it does, it is amassed as simple text evidence on the visitor's hard drive. Now, when the caller reaches your destination at another page on the site, the cookie is accessible for retrieval. Once recovered, your server knows/remembers what was stored.

Cookies are an unadorned text data proof of 5 variable-length fields:

Expires - The date the cookie will end. If this is empty, the cookie will end when the caller quits the browser.

Domain - The domain forename of the site.

Path - The path to the book or web page that puts the cookie. This may be vacant if you want to recover the cookie from any index or page.

Secure - If this meadow includes the word "secure", then the cookie might only be retrieved with a safe server. If this field is empty, no such restriction exists.

Name=Value - Cookies are set and retrieved in the form of key and value pairs.

Setting up Cookies

It is very easy to send cookies to the browser. These cookies are sent along with HTTP Header before to Content-type field. Assuming you want to set UserID and Password as cookies. Setting the cookies is done as follows:

#!/usr/bin/python

print "Set-Cookie:UserID = XYZ;\r\n"
print "Set-Cookie:Password = XYZ123;\r\n"
print "Set-Cookie:Expires = Tuesday, 31-Dec-2007 23:12:40 GMT";\r\n"
print "Set-Cookie:Domain = www.tutorialspoint.com;\r\n"
print "Set-Cookie:Path = /perl;\n"
print "Content-type:text/html\r\n\r\n"
...........Rest of the HTML Content....

From this example, you must have understood how to set cookies. We use the Set-Cookie HTTP header to set cookies.

It is optional to set cookies attributes like Expires, Domain, and Path. It is notable that cookies are set before sending magic line "Content-type:text/html\r\n\r\n.

Retrieving Cookies

It is very easy to retrieve all the set cookies. Cookies are stored in CGI environment variable HTTP_COOKIE and they will have the following form:

key1 = value1;key2 = value2;key3 = value3....

Here is an example of how to retrieve cookies.

#!/usr/bin/python

# Import modules for CGI handling 
from os import environ
import cgi, cgitb

if environ.has_key('HTTP_COOKIE'):
   for cookie in map(strip, split(environ['HTTP_COOKIE'], ';')):
      (key, value ) = split(cookie, '=');
      if key == "UserID":
         user_id = value

      if key == "Password":
         password = value

print "User ID  = %s" % user_id
print "Password = %s" % password

This produces the following result for the cookies set by the above script:

User ID = XYZ
Password = XYZ123

File Upload Example

To upload a file, the HTML form must have the enctype attribute set to multipart/form-data. The input tag with the file type creates a "Browse" button.

<html>
<body>
   <form enctype = "multipart/form-data" 
                     action = "save_file.py" method = "post">
   <p>File: <input type = "file" name = "filename" /></p>
   <p><input type = "submit" value = "Upload" /></p>
   </form>
</body>
</html>

The result of this code is the following form:

File:

The above example has been disabled intentionally to save people uploading files on our server, but you can try the above code with your server.

Here is the script save_file.py to handle file upload

#!/usr/bin/python

import cgi, os
import cgitb; cgitb.enable()

form = cgi.FieldStorage()

# Get filename here.
fileitem = form['filename']

# Test if the file was uploaded
if fileitem.filename:
   # strip leading path from file name to avoid 
   # directory traversal attacks
   fn = os.path.basename(fileitem.filename)
   open('/tmp/' + fn, 'wb').write(fileitem.file.read())

   message = 'The file "' + fn + '" was uploaded successfully'
   
else:
   message = 'No file was uploaded'
   
print """\
Content-Type: text/html\n

%s

"""
% (message,)

If you run the above script on Unix/Linux, then you need to take care of replacing the file separator as follows, otherwise, on your windows machine above open() statement should work fine.

fn = os.path.basename(fileitem.filename.replace("\\", "/" ))

How To Raise a "File Download" Dialog Box?

Sometimes, it is desired that you want to give an option where a user can click a link and it will pop up a "File Download" dialogue box to the user instead of displaying actual content. This is very easy and can be achieved through an HTTP header. This HTTP header is different from the header mentioned in the previous section.

For example, if you won't make a FileName file downloadable from a given link, then its syntax is as follows:

#!/usr/bin/python

# HTTP Header
print "Content-Type:application/octet-stream; name = \"FileName\"\r\n";
print "Content-Disposition: attachment; filename = \"FileName\"\r\n\n";

# Actual File Content will go here.
fo = open("foo.txt", "rb")

str = fo.read();
print str

# Close opend file
fo.close()

Hope you enjoyed this tutorial. If yes, please send me your feedback at: Contact Us

Here at Intellinuts, we have created a complete Python tutorial for Beginners to get started in Python.