Local execution of Python CGI scripts
September 6th, 2008 at 6:42 pmUpdate (14.01.2011): A version of this code for Python 3 is available here.
Here’s a method to run Python CGI scripts locally, for testing. It employs the BaseHTTPServer and CGIHTTPServer standard modules to run a simple CGI-capable web server on your computer.
Here’s the code implementing the server:
import CGIHTTPServer
import BaseHTTPServer
class Handler(CGIHTTPServer.CGIHTTPRequestHandler):
cgi_directories = ["/cgi"]
PORT = 9999
httpd = BaseHTTPServer.HTTPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
This server assumes the directory it was run in is the root directory. It will run CGI scripts from the directory cgi, relative it its root. Place the following simple script in cgi and call it test.py:
#!/usr/bin/env python
print "Content-type: text/html"
print
print "<html><head><title>Situation snapshot</title></head>"
print "<body><pre>"
import sys
sys.stderr = sys.stdout
import os
from cgi import escape
print "<strong>Python %s</strong>" % sys.version
for k in sorted(os.environ.keys()):
print "%s\t%s" % (escape(k), escape(os.environ[k]))
print "</pre></body></html>"
All this script does it to print out a message and the environment variables. Now, after running the server, visit (in your browser) http://localhost:9999/cgi/test.py and you will hopefully see the expected results.
This method can be used to locally test CGI scripts before uploading them to a real server.
Related posts:

September 9th, 2008 at 19:22
Neat, Eli.
Something roughly along the same lines, but using only BaseHTTPServer, is to do ‘servlets’ (like Java servlets) in Python (also works in Ruby with Mongrel or WEBrick), something like this:
[ This is a pretty powerful technique that allows you to get a programmable web server with minimal code overhead. ]
Write a class with a method you want called over HTTP from a web client. (The client could be written in Python, Ruby or almost any other language that can do HTTP calls programmatically.)
Create an instance of BaseHTTPServer.
Mount your class on the server (this is similar to registering functions or classes with an XML-RPC server when using XML-RPC – though the method I describe is not using XML-RPC), configuring it to be callable at a particular URL on the server. the way XML-RPC-enabled code can typically be called at http://hostname/RPC2.
Start the server (the same .serve_forever() call as you used in your CGI code above.
And of course, multiple classes with multiple methods can be mounted this way, on the same instance of BaseHTTPServer, as long as they are referenced at different paths, and can be called at different times during the same session.
For a more detailed description about the ‘servlets’ approach, see here: a reply I wrote to a question on comp.lang.ruby – but it applies to Python too – the poster was asking about the same topic:
http://groups.google.com/group/ruby-talk-google/browse_thread/thread/29514a637cbf7cf3/c1330727c370bfe0?lnk=st&q=%2BVasudev+%2Bwriting+a+web+service#c1330727c370bfe0
- Vasudev
September 9th, 2008 at 20:42
Interesting. Thanks, Vasudev.
September 12th, 2008 at 23:00
And if you use Linux + KDE, konqueror can run CGI scripts too