Local execution of Python CGI scripts

September 6th, 2008 at 6:42 pm

Update (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:

  1. Local execution of Python CGI scripts – with Python 3
  2. Problem passing arguments to Python scripts on Windows
  3. Installing Python 2.5 on Bluehost
  4. Sending mail from Python with SMTP
  5. matplotlib – plotting with Python

4 Responses to “Local execution of Python CGI scripts”

  1. Vasudev RamNo Gravatar Says:

    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

  2. elibenNo Gravatar Says:

    Interesting. Thanks, Vasudev.

  3. damjanNo Gravatar Says:

    And if you use Linux + KDE, konqueror can run CGI scripts too :)

  4. JANELLANo Gravatar Says:

    My coder is trying to convince me to move to .net from PHP. I have always disliked the idea because of the costs. But he’s tryiong none the less. I’ve been using Movable-type on numerous websites for about a year and am anxious about switching to another platform. I have heard good things about blogengine.net. Is there a way I can import all my wordpress content into it? Any help would be greatly appreciated!