CGI Tutorial

Jim jhefferon at smcvt.edu
Thu Oct 5 17:56:54 EDT 2006


Clodoaldo Pinto Neto wrote:
> I'm just building a Python CGI Tutorial and would appreciate any
> feedback from the many experts in this list.
I'm not an expert, but I have written a lot of these and I have a
couple of $0.02's.

* All code you put in your writing needs to be correct.  That is, on
the web you can't say something and later in the text say "but this has
a problem and needs to be tightened up" because people will paste in
code that they got from you and won't read the rest.  They will.

Instead, you need the scripts to be right, from the start.  Then you
say "Lets look at lines 1-5.  The reason for those is ..".

* All cgi scripts need logging.  Debugging cgi can be hard and you need
to have a place to write statements of the form log.debug("in
getValues(): value of x is %s" % (repr(x),)).

* You need a DEBUG variable:
    from defaults import DEBUG
    :
    if DEBUG:
       ..

* I've been impressed by Guido's writing that a main() routine makes
sense.  One reason is that you can more easily make unit tests.
Because testing cgi is so hard, this is especially useful in this
context.  (I admit that I'm only a recent convert to this but it really
makes sense.)

So, continuing with my opinions as though they were facts, the skeleton
of all cgi's is something like this, IMHO:

  import sys, os, os.path, urllib, cgi

  from cgi import escape
  from xml.sax.saxutils import quoteattr

  from defaults import DEBUG, LOGGING
  THIS_SCRIPT=os.path.basename(sys.argv[0])
  LOGFILE_NAME=os.path.splitext(THIS_SCRIPT)[0]+'.log'

  if DEBUG:
     import cgitb
     cgitb.enable()

  # all kinds of functions here

  def main(fs,argv=None,log=None,debug=False):
      if argv is None:
         argv=sys.argv
      # logic here

  if __name__=='__main__':
    log=None
    if LOGGING:
      log=openLog(LOGFILE_NAME)
    fs=cgi.FieldStorage(keep_blank_values=1)
    try:
        main(fs,argv=sys.argv,log=log,debug=DEBUG)
    except StandardError, err:
        mesg="General programming error"
        bail(mesg,devel=mesg+":
error=%(err)s",log=log,debug=DEBUG,err=err)
    except SystemExit, err:  # bailed out in a subroutine
        pass
    sys.exit(0)

(where bail() is a routine that puts up an error page -- on that page,
I have one of two messages, the second of which, using the "devel"
string, only appears when DEBUG is True).

In my humble experience, all cgi programs should follow something like
that scheme.

You asked for an opinion!  :-)
Jim




More information about the Python-list mailing list