[siː dʒiː aɪ]
Note: if you can’t see the title, it means your browser can’t display Unicode characters properly.
The Common Gateway Interface (CGI) is a standard protocol for interfacing external application software with an information server, commonly a web server. This allows the server to pass requests from a client web browser to the external application. The web server can then return the output from the application to the web browser.
Today, I’ll explain how to generate Web pages using Python - the easiest programming language ever. They won’t be just static pages, however; in the article there will be examples of CGI scripts processing data from HTML forms, uploading files to the server, some GET and POST requests and even a simple how-to showing how to set up a small CGI server. However, this article is about using CGI in Python, so I assume you have some knowledge of the Python syntax.
The simpliest of the simpliest
Let’s start with a simple static page. The first line of any CGI script has to point to the location of Python. It’ll usually be /usr/bin/python on most Unix-based servers. Next, we have to inform Python that the output of the script is actually HTML (and put an \n at the end of this line)- and the rest of the code is up to you. Remember that all CGI scripts need permissions at least equal to chmod 755.
#!/usr/bin/python
print "Content-type: text/html\\n"
print "OMG, it's actually working!"
You can see the script working.
Of course, this script doesn’t even include the most basic html tags such as <html> and <body>, so have a look at a second example:
#!/usr/bin/python
print "Content-type: text/html\\n"
print """<html>
<head>
<title>OMG</title>
</head>
<body>
<h2>It's actually working!</h2>
<img src="some_crappy_image_source">
</body>
</html>"""
Again, you can see how it works.
Mummy, my script isn’t working!
CGI scripts are difficult to write, as even the simpliest mistakes cause internal server errors (#500). Remember to put a new line sign (if your server is a Unix-based one, \n is the new line sign, and the DOS \r\n is not supported) at the end of the line that indicates the content type. Also, be sure to check if your server actually supports Python and CGI scripts. If the answer is yes, but the scripts still don’t work, ask the hosting support (e.g. on Dreamhost, without proper domain settins, you won’t be able to execute any CGI scripts). We’ll get to some other errors later.
Processing data
Of course, using CGI to generate static web pages is stupid. Now, I’ll show you how to write a data-processing script. First, the form:
#!/usr/bin/python
print "Content-type: text/html\\n"
print """<html>
<head><title>The form</title></head>
<body>
<form action="path-to-the-script.cgi" method="post">
<label for="login">Login: </label>
<input type="text" name="login">
<br>
<label for="pass">Password: </label>
<input type="text" name="pass">
<br><input type="submit" value="OK, let\\'s go">
</form>
</body>
</html>"""
Next, let’s write a script that will check whether the password equals to “pass123″ and display a nice message to the user. The function that we’ll use is cgi.FieldStorage(), which returns a dictionary of all GET and POST request variables.
#!/usr/bin/python
from cgi import FieldStorage as data
from sys import stderr, stdout
stderr = stdout
data = data()
print "Content-type: text/html\\n"
if data.has_key('login') and data.has_key('password'):
if data['password'].value == 'pass123':
print 'Hello, %s. You\\'ve entered a <b>correct password</b>!' % data['login'].value
else:
print 'Hello, %s. The password you\\'ve entered is incorrect.' % data['login'].value
else:
print 'Fill all the form fields!'
Check it out.
Some explanation: we want errors (sys.stderr) to be displayed via the default output (sys.stdout), which is the data that goes to the browser and, as a result of that, to the user. I used has_hey() to check if all the fields were filled in, and then displayed a message. CGI handles GET request the same way, i.e. I could’ve sent the form data using the GET method and the script would still work properly. The FieldStorage function stores all requests from you to the server, so it even stores files you send via forms (see below).
Self-posting CGI scripts
Of course having two separate CGI scripts isn’t necessary and we can get the code into one file, which will be a self-posting script. Here’s the code of a simple guestbook saving the guest data to a file:
#!/usr/bin/python
from cgi import FieldStorage as data
from sys import stderr, stdout
stderr = stdout
data = data()
f = open('guestbook.txt', 'a+')
print "Content-type: text/html\\n"
print "<html><head><title>Guestbook</title></head>"
print "<body><h2>Guestbook</h2>"
if data.has_key('name') and data.has_key('comment'):
f.write('<li><b>%s</b> said:<br>%s</li>' % (data['name'].value, data['comment'].value))
print "Thanks for commenting on our site!<br>"
print "<a href='path-to-the-guestbook.cgi'>See the guestbook</a>"
else:
print '<ul>', f.read(), '</ul>'
print "<br>Add your comment:<br><br>"
print """<form action="path-to-the-guestbook.cgi" method="post">
Your name:<br>
<input type="text" name="name"><br>
Your comment:<br>
<textarea name="comment" rows="4" cols="50"></textarea><br>
<input type="submit" value="OK">
</form>"""
f.close()
print "</body></html>"
Now you can write some stupid things in my guestbook.
Needless to say, we need a guestbook.txt file with proper permitions for the guestbook to work.
File upload
When writing CGI scripts, you may want the users to be able to upload files. How to accomplish this? Again, using the FieldStorage function! Yeah, it’s extremely easy. In the following script, the information on all uploaded files is saved to a file list, which is read every time you enter the page without the actual file in FieldStorage. Notice the form enctype="multipart/form-data".
#!/usr/bin/python
from cgi import FieldStorage as data
from sys import stdout, stderr
stderr = stdout
data = data()
f = open('FILE-LIST', 'a+')
print 'Content-type: text/html\\n'
print '<html><head><title>Files</title></head><body><h2>Files</h2>'
if data.has_key('upload'):
upload = data['upload']
content = upload.file.read()
size = len(content)
name = upload.filename
path = 'files/' + name
if size < 2048:
t = open(path, 'wb')
t.write(content)
t.close()
f.write("<a href='%s'>%s</a><br>\\n" % (path, name))
print "Succesfully uploaded file <b>%s</b> (%d bytes).<br>" % (name, size)
print "<a href='PATH-TO-THE-SCRIPT'>See the file list or upload another file</a>"
else:
print "Maximum file size is 2 kB."
else:
print f.read()
print """<br>Upload your file:<br><form action="PATH-TO-THE-SCRIPT"
method="post" enctype="multipart/form-data">
<input type="file" name="upload">
<input type="submit" value="Upload">
</form>"""
f.close()
print '</body></html>'
Admire the script here.
As you can see, CGI in Python isn’t that difficult. All file data can be accessed via upload.file.(the data you want) or just upload.(the data you want). In the script I create the file using binary mode, so that images would be properly uploaded as well. Now, let’s get to something more advanced!
Your own CGI server
All that’s needed to set up a simple HTTP server lies in the module BaseHTTPServer. The following example show the simpliest HTTP server that will allow you to run .cgi files as scripts on your computer:
#!/usr/bin/python
import CGIHTTPServer, BaseHTTPServer
address = ('', 666)
server = BaseHTTPServer.HTTPServer(address, CGIHTTPServer.CGIHTTPRequestHandler)
print "Serving at 127.0.0.1:666..."
server.serve_forever()
The first parametre of the address list is the server address (e.g. 128.666.0.0), the second one is the port. If no address is given, the server works on localhost (http://127.0.0.1 or http://localhost). Printing the text will inform you that the server actually started working, if you access it via the command line. Remember to put server.serve_forever() at the end of the file to make the server work.
Now, enter http://127.0.0.1:666 in your browser and you should see the file list of the folder the script’s in. Create a directory, e.g. cgi-bin and a script inside it. Remember to give proper permitions - and that’s it! I can show you a screenshot.
The article’s showed you the basic CGI usage. Hope you enjoyed it and will make use of it. You can see how simple Python is; and it can do almost everything. I’ll write more articles on the usage of Python in different situations in the near future. C’ya!
posted on Tuesday, 14th August, 2007 at 16:08 (UTC +1000)
comments feed
leave a response or trackback

August 15th, 2007 at 17:29
Why not WSGI? And why you haven’t made OpenID-enabled comments yet? :P
October 12th, 2007 at 22:19
I’ll get to WSGI later.
I can’t find any suitable OpenID Wordpress plugin, and I really don’t think OpenID is worth writing a plugin by myself ;P
March 6th, 2008 at 16:35
if data.has_key(’upload’):
upload = data[’upload’]
content = upload.file.read()
size = len(content)
What happens if someone tries to upload a file of, say, 20Go ?
How about this :
if data.has_key(’upload’):
upload = data[’upload’]
upload.file.seek(0,2)
size = upload.file.tell()
This way you don’t have to read the entire file (and waste memory space) to know its size.
Y.chaouche
April 1st, 2008 at 09:16
i hope. abcbae147e thanks
April 6th, 2008 at 02:15
http://nudekimkardashi.blog.drecom.jp
May 12th, 2008 at 04:13
Can You Look At THis?I think This Is One Of My Favorites
Kendra wilkinson photos
May 13th, 2008 at 22:53
I really Want You To Check This Site.Really Enjoyed the site guys bear share free music
June 3rd, 2008 at 21:03
hQgv6v fdv084y0v4t3cnfv593bv29vb
June 15th, 2008 at 05:07
starfire fanfics
and starfire fanfic
starfire fanfic
starfire and robin fanfiction
starfire fanfiction
and starfire fan fiction
starfire fan fiction
and starfire fanfiction
robin and starfire fan fiction
robin starfire fanfiction
June 18th, 2008 at 03:25
This nbc lets rss 15 die hentei videos
all hentei videos on e in playlists
series hentei videos itg espn faq not
hentei videos
henati dvds hentia dvds henti dvds
sex on movies music practice you arise.
June 22nd, 2008 at 20:00
How would you like to see this?, buy free get hoodia one one, buy free get hoodia one one, 67052,
June 23rd, 2008 at 01:59
Brilliant work guys, nicely doneI Enjoyed It Very Much, caffeine free diet coke logo, caffeine free diet coke logo, 107196,
June 23rd, 2008 at 22:41
This Is Pretty Much The Best SiteDo You Have Other Sites?, .rar free download, .rar free download, eds,
June 24th, 2008 at 00:17
Come here and leave your commentYou Are Very Creative,
June 25th, 2008 at 04:59
Might Be The Best Ever Yet,
June 25th, 2008 at 06:50
Have You Seen This Already?,
July 3rd, 2008 at 21:40
teen titans bandai
communicator teen titans bandai is game
a teen titans bandai films teen teen
teen titans bandai
July 18th, 2008 at 02:32
fpyvqtmnfdux ‾
July 30th, 2008 at 19:17
A huge choice of MP3 music!
Tons of mp3 music! Buy and download here legally!
August 12th, 2008 at 12:17
, ?
?