So one day you’re too lazy to write a fcgi library for your favorite language but you want nonetheless expose an application on the web… Then use python ! There are quite a few frameworks to run fcgi with python, but if you want something easy, I think that flup is for you.

The code below takes care of few aspects for you. First flup span a server talking at port 5555 on localhost. You can configure it to be multi thread is you want to. Then using the cgi module we make sure that the input is clean and ready to use. Finally we run your fantastic application as DOSOMETHING. If your application is a simple program, of course there is no reason to write a fcgi. A common cgi will pay the bill. However, if your application can benefit from some form of caching, then maybe writing the web related stuff in python and use the application as a black box can be a nice idea.

If might want to check out [flup http://trac.saddi.com/flup] and [werkzeug http://werkzeug.pocoo.org/]. I’ve not used the last one, but it seems more complete then flup.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from cgi import escape
import sys, os
from flup.server.fcgi import WSGIServer
import subprocess
import urlparse
import cgi
# expose python errors on the web
import cgitb
cgitb.enable()

def app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    yield '<html><head></head>'
    yield '<body>\n'

    form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ,keep_blank_values=1)

    yield '<table border="1">'
    if form.list:
        yield '<tr><th colspan="2">Form data</th></tr>'

    for field in form.list:
        yield '<tr><td>%s</td><td>%s</td></tr>' % (field.name, field.value)

    yield '</table>'

    if form.has_key('c') and form.has_key('l'):
        cat = form.getvalue('c')
        pl = form.getlist('l')
        command = DOSOMETHING(cat,pl)
        results = subprocess.Popen(command,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        (i,e) = results.communicate()
        yield '%s\n' % i
        yield '%s\n' % e

    yield '</body>\n'
    yield '</html>\n'

WSGIServer(app,bindAddress=('localhost',5555)).run()