Using python to create CGI scripts


In this document we will (eventually) explain how to create Python CGI scripts for use with Personal WebServer, WebStar and probably other Mac-based HTTP servers too. Since CGI scripts are AppleEvent servers on the mac we will also learn a little about general AppleEvent server programming and about applet debugging.

Note that the current setup is very preliminary, and hence itis probably not wise to base your strategic products on the information in this document:-) In stead, play with the code here and join the pythonmac-sig, where we I would like to have a discussion on a real design for a Mac CGI framework (preferrably something that will make CGI scripts portable to unix and other platforms).

AppleEvent servers

Since AppleEvent clients are easier to write and understand than servers you should probably read the section on Open Scripting clients in Python first.

Next, let us have a look at the AE Server framework, MiniAEFrame.py. This file contains two classes, MiniApplication and AEServer. MiniApplication is a tiny replacement for FrameWork.Application, suitable if your application does not need windows and such. AEServer is a bit of glue that does part of the appleevent decoding for you. You call installaehandler passing it the class and id (4-char strings) of the event you have a handler for and the handler callback routine. When the appleevent occurs your callback is called with the right arguments. For now, your argument names are the 4-char values used internally by Open Scripting, eventually there will be a translation similar to what the generated OSA client suites provide.

You can test AEServer by double-clicking it. It will react to the standard run/open/print/quit OSA commands. If it is running as a normal python script and you drag a file onto the interpreter the script will tell you what event it got.

A Minimal CGI script

To try a CGI script you will first need a http server. Apple's Personal Webserver is fine, but I have also used the shareware NetPresenz by Peter Lewis (don't forget to pay if you give it more than a test run!). Install your http server, and make sure that it can serve textual documents.

Next, let us have a look at our example CGI scripts. CGI scripts have to be applications, so we will have to make an applet as explained in example 2. Our applet code, cgitest.cgi.py is a rather minimal execfile statement. The reason for this is debugging: the real code is in realcgitest.py, and this way you do not have to run mkapplet again every time you change the code. Rename realcgitest.py to cgitest.cgi.py once you are satisfied that it works.

The resource file is not very special, with one exception: since we want to do our own appleevent handling we don't want the Python initialization code to create argc and argv for use, since this might gobble up any appleevents we are interested in. For this reason we have included a 'Popt' resource that disables the argv initialization. An easy way to create this resource is to drop the .rsrc file (or the finished applet, if you like) onto EditPythonPrefs and set the "no argv processing" option.

The code itself is actually not too complicated either. We install handlers for "open application" and "quit" (stolen from the test code in MiniAEFrame) and the "WWW\275"/"sdoc" event, the event sent on CGI execution. The cgi handler pretty-prints the CGI arguments in HTML and returns the whole string that is to be passed to the client. The actual parameters passed are explained in http://www.biap.com/datapig/mrwheat/cgi_params.html.

To test the script drop cgitest.cgi.py onto mkapplet, move the resulting cgitest.cgi to somewhere where it is reachable by NetPresenz, and point your web browser towards it. Note that this assume you have already renamed realcgitest.py to cgitest.cgi.py, otherwise you'll also have to copy that file along.

For Apple's Personal Webserver you need to do a bit more: you have to copy the cgi applet to somewhere in your "Webpages" folder and you have to tell the webserver (in the control panels) that your CGI script exists. I don't understand what the various types of cgi scripts mean, but experiment with them.