The main installation and configuration information for PyWX can be found in the INSTALL file in the distribution. This page contains some discussion of higher-level considerations regarding the configuration of PyWX.
There are two ways for PyWX to be invoked: through a mapping to a C++ handler function that calls a Python function that sources your .py script, or as a filter that runs a Tcl function that in turns runs a Python function that sources the script. If you are interested, you can read about the gory details of the two procedures. However, once your script is running, there is hardly a difference between the two methods.
This option is configured by using either the Map
directive in your configuration file, or setting
"EnablePythonPages On
" in the config file and installing
00-python.tcl in your tcl directory. See the
INSTALL file for more information.
ReuseInterpreters
option. More details about Python's
execution environments are available here.
In neither case do multiple Python scripts run at the same time in the same interpreter. That would require multiple threads within a single Python interpreter, which hasn't been implemented yet.
Reusing interpreters has a significant speed advantage, mostly (it seems) because Python modules only need to be initialized once in each interpreter. However, reused interpreters provide slightly less isolation between scripts, and might be more prone to memory leaks due to buggy scripts.
The canonical and most efficient way to return headers and content
to the client with AOLserver is via AOLserver API calls, of which
there is a huge variety. In PyWX, these functions are available as
member functions of the Ns.Conn connection object such as
conn.SetHeaders()
, conn.ReturnHtml()
,
conn.ReturnData()
, and conn.Redirect()
.
However, PyWX also provides a method to return headers and content by printing them to sys.stdout in the same format that is used by CGI scripts. Internally, sys.stdout is attached to a special object called a PyWX_buffer which: parses the headers and sets them via the above API; and buffers the content then gives it all at once to AOLserver. This method is obviously less efficient than using the API calls directly, but it may be more convenient, especially if you are already familiar with CGI programming.
The choice of whether to attach a PyWX_buffer object to sys.stdin
and sys.stdout is configured with the AttachStdio
option
in the configuration file.
Aside from special treatment of stdin and stdout, a CGI script requires additional special settings in its environment. Information about the request needs to be set in environment variables; the working directory needs to be changed to the directory containing the script; and other information must be put in the script's command-line arguments. None of this is strictly necessary for a PyWX script, because the same information is available via the AOLserver API.
However, since many people already have scripts written to the CGI standard, PyWX provides a way to emulate the CGI environment to allow old CGI scripts to take advantage of the huge performance gain of running in a multithreaded server. The emulation is necessarily imperfect, though, because things like the current working directory are shared by all threads in a process and so can't be changed without affecting all scripts. Moreover, turning on CGI emulation causes a memory leak in the current version (0.6) of PyWX.
To turn on CGI emulation, enable the SetupCGIEnv
option in your configuration file.
Normally your Python scripts are run by PyWX using Python's
execfile()
function. execfile()
has two
undesirable features from a performance point of view: it reads the
file each time from disk, and it doesn't even compile the file into a
.pyc bytecode file (as is done with imported Python modules)
so it has to parse the file anew each time. To avoid these problems,
PyWX can use a specially-written replacement version of
execfile()
that caches the compiled code in
memory the first time a script is run, and thereafter runs
the precompiled code. (If the modification time of the file on disk
has changed, it reloads the file.) This feature can be enabled or
disabled by setting the variable UseCachingExec
in the
file pywx.py. In the future we might provide a
configuration-file option to set this parameter.
The disadvantages of caching compiled scripts are that cached scripts permanently consume server memory, and that the implementation is currently not thread-safe. The performance advantage depends heavily on the application; if you run short scripts that load most of their code from modules, it shouldn't make much difference. But if you use long scripts, the gain might be substantial.
If you want the caching execfile()
to override the
normal execfile()
within your scripts too, set
InstallCachingExec
in the same file.