Fiction    

Fiction L
A Fake Internet Presence,
since 1994

 Home
 TidBits
 BLong
   Source
     GBuffy
     Mutt
     ClearSilver
     Python
     PyApache
   PalmOS Tools  
 Neotonic

PyApache Notes

I've noticed that most of the current information about PyApache is a bit out of date, and I figured I'd post what I've learned here in the hopes that other people might be helped. I've pretty extensive experience with python in a web environment, we used a modified version of PyApache at eGroups on about 100 web servers. The entire site was in python, until we started moving more of the code to C for maintainability (someday maybe I'll write an article about why not to use an untyped language for a large development project that you hope to maintain over years without hundreds of volunteer QA people (ie, your users), but later).

Problems with PyApache and Python 2.0/2.1

There is a bug in Python 2.0 and 2.1 (fixed in 2.2 and 2.1.2) with the handling of embedded python. You are most likely seeing this if you are using the MySQLdb module, and it probably looks something like:
'import site' failed; traceback:
  Traceback (most recent call last):
     File ".../lib/python2.1/site.py", line 60, in ?    
	import sys, os
     File ".../lib/python2.1/os.py", line 54, in ?
	__all__.extend(_get_exports_list(posix))
     File ".../lib/python2.1/os.py", line 35, in _get_exports_list
	return list(module.__all__)
AttributeError: 'posix' module has no attribute '__all__'
This error is due to a missing call to _PyImport_FixupExtension("exceptions", "exceptions"); in Python/pythonrun.c:Py_Initialize()

Short POST reads with PyApache 4.25

There is a bug in PyApache 4.25 where attempts to read off sys.stdin for POST or PUT requests will result in short reads. Version 4.22 does not contain this error, and I don't have the code for the interim versions to know when the bug was introduced. There is a call to ap_should_client_block() in mod_pyapache.c:ab_fill_read_buffer(). This Apache API call will always return 0 after a call to ap_get_client_block(). This means any post over 8192 bytes, or any read before the entire post data is available to the process (in our tests, about anything over 2k) will result in a short read as the buffer fill will only work once, and then it will return a premature EOF. For this reason, I recommend running with 4.22 unless you need the Apache2 support.

Using Python 2.x

As mentioned earlier, you probably need to use 2.1.2 or 2.2 if you want to use PyApache. I also recommend compiling a version of python without threading support. I personally have never gotten PyApache to work as an Apache DSO, so I recommend compiling it into your Apache server directly. You will have to edit the mod_pyapache.h to change the include files to point to python2.1 (or python2.2) instead of python1.5. You will need to change mod_pyapache.c to change the MODULE-DEFINITION to point at your install of python 2.x. You may also need to point the build at the correct include files for the version of python you are compiling against. If you are compiling without threading, there is a missing #ifdef WITH_THREAD/#endif for the call to PyEval_InitThreads() in pyapache_init().

Weirdness with PyApache SingleInterpreter

We've noticed some problems using the SingleInterpreter mode of PyApache. For instance, we've seen instances where all POST requests fail because the python code can't read from sys.stdin. We haven't been able to find the solution to this, so we use the work around of always setting our Apache configuration MaxRequestsPerChild to around 55. Not great, but it works.

Links

http://www.bel-epa.com/pyapache/
One of the major sites with information about PyApache

 

 


Copyright (C) 2003 Brandon Long. All Rights Reserved.
blong@fiction.net / PGP / Terms of Service