[Pythonmac-SIG] Python CGI server

Just van Rossum just@letterror.com
Thu, 20 Aug 1998 12:03:26 +0200


My friend Erik retrieved the old CGI Python server I mentioned yesterday.
I added some comments and changed a few things without testing it.

I don't know much about CGI, let alone CGI on the Mac, so if this thing
appears simple-minded: well, it is. If you can use it, please do, if you
make any improvements, please let me know. If it works well enough,
maybe we should put it in the cgi demo folder in the next distribution.

Poissibly this script could be expanded so it puts the arguments/parameters
from the http request in the proper places, so they are accessible from
the CGI module. Then *maybe* unix CGI's could "just work" on the Mac.
Let me know if you have any ideas about this.

Just


--- pythoncgislave.py ---
"""pythoncgislave - A minimal Python server for CGI scripts."""

import MacOS
# It seems sometimes AE's get lost if we don't do this.
# Not sure if this is still true.
MacOS.EnableAppswitch(-1)

import os
import string
import StringIO
import sys
import traceback

__version__ = '2.1'

# fiddle with the next bit so _root becomes the root http directory
# I guess that if this applet lives in the http root directory
# it would be enough to write:
# _root = os.path.dirname(sys.argv[0])

_thisapplethome = os.getcwd()
_root = os.path.dirname(_thisapplethome)

from MiniAEFrame import AEServer, MiniApplication

class CGIslave(AEServer, MiniApplication):

	def __init__(self):
		MiniApplication.__init__(self)
		AEServer.__init__(self)
		self.installaehandler('aevt', 'oapp', self.open_app)
		self.installaehandler('aevt', 'quit', self.quit)
		self.installaehandler('WWW\275', 'sdoc', self.cgihandler)
		print 'ready.'
		print "python cgislave " + __version__
		# dict for some semi-persistent things.
		self.lib = {}

	def quit(self, **args):
		self.quitting = 1

	def open_app(self, **args):
		pass

	def cgihandler(self, pathargs, **args):
		path = args['scnm']
		# convert unix path to mac path, prepend http root dir.
		path = string.join(string.split(path, '/'), ':')
		path = os.path.join(_root, path)
		# Reroute stdout and stderr. Rerouting stderr may be handy
		# when debugging, but not advisable for a final product.
		saveout = sys.stdout
		out = sys.stderr = sys.stdout = StringIO.StringIO()
		try:
			# 'args' will be visible as a global variable for
			# the CGI script. It might be possible to wrap
			# them in a way so they become accessible through
			# the CGI module, as they should...
			execfile(path, {'args': args,
					'lib': self.lib,
					'__name__': '__main__',
					'__file__': path}
				)
		except:
			print '<pre>'
			traceback.print_exc()
			print '</pre>'
		sys.stderr = sys.stdout = saveout

		return out.getvalue()

cgislave = CGIslave()
cgislave.mainloop()