Contents
scgi-wsgi is a WSGI [1] server/gateway that implements SCGI [2] to communicate with a web server [3]. It is written in C and embeds a Python interpreter to run the actual application. Since all of the low-level transport code is in C, scgi-wsgi is significantly faster than any pure-Python (or hybrid) SCGI servers.
scgi-wsgi supports both threading and forking.
[1] | (1, 2) http://www.python.org/dev/peps/pep-0333/ |
[2] | http://www.python.ca/scgi/protocol.txt |
[3] | Typically, you would use mod_scgi or mod_proxy_scgi (included with Apache HTTPD 2.2.14+) to connect your web server to scgi-wsgi. |
- Wholly written in C - the Python Global Interpreter Lock only enters the picture when calling the WSGI application, allowing greater concurrency.
- If the iterable returned by the WSGI application has a length and that length is 1, the Content-Length header is automatically deduced.
- Supports the wsgi.file_wrapper feature. On some platforms (i.e. FreeBSD), it is implemented using the OS-level sendfile(2) syscall.
The latest version of scgi-wsgi may be found at http://www.saddi.com/software/scgi-wsgi/dist/
First execute configure.py with the version of Python you wish to embed. So far scgi-wsgi has been tested with Python 2.3, 2.4, 2.5, 2.6, and 2.7.
python configure.py
Next, execute make. If everything goes well, you should have an scgi-wsgi executable that's ready to use.
At this time, scgi-wsgi is only confirmed to compile/work on FreeBSD 6.x, Mac OS X 10.6, and (Gentoo) Linux. Other Linux distros probably work as well. Patches and/or suggestions to improve portability are highly welcome!
Before using scgi-wsgi, you most likely want to set two important environment variables: PYTHONHOME and PYTHONPATH.
PYTHONHOME determines where scgi-wsgi will import its standard Python modules. If you are using a "virtual" Python installation, set this to the base directory of your installation. Otherwise, leave it unset to use your default Python's modules (the Python found in your PATH).
For example:
export PYTHONHOME=/home/myusername
PYTHONPATH is any additional directories to search for Python modules. Note that the current directory is always searched first. For example, to search the directories named mymodules and othermodules in your home directory:
export PYTHONPATH=$HOME/mymodules:$HOME/othermodules
Note that other standard Python environment variables are also accepted by the embedded interpreter, e.g. PYTHONOPTIMIZE.
Finally, to actually use scgi-wsgi, simply execute it with the name of the module for your WSGI application, and the name of your application's object within that module:
scgi-wsgi myappmodule app
By default, scgi-wsgi will listen on port 4000.
The scgi-wsgi command-line options take the following form:
scgi-wsgi [-BFQVv] [-l <logFile>] [-h <ifname>] [-p <port>] [-n <maxConnections>] <moduleName> <appName> [<scriptName>]
Where:
-V Report version and exit. -v Run verbosely. -B Run in the background. It is strongly recommended that you use the -l logFile option as well. -F Use a new process (fork) for each SCGI request, rather than a new thread. -Q Do not attempt to decode REQUEST_URI/PATH_INFO. -l logFile Redirect stderr to logFile. stderr is where most of the useful diagnostic messages (tracebacks, etc.) go. -h ifname Bind to interface ifname rather than localhost. May be a resolvable name or an IPv4/IPv6 address. -p port Listen on port port rather than 4000. -n maxConnections Maximum number of threads or processes. When threading, default is MAX_INT, i.e. effectively unlimited. When forking, the default is 16. Note that the -t option served the same purpose in previous versions. As of 1.1, it is deprecated, but it will still set maxConnections correctly. -m minConnections Minimum number of processes to maintain in the process pool. Only has meaning when forking. Default is 1. -i maxIdle Maximum time a thread or process can remain idle in the pool in seconds. Default is 300 (5 minutes). -E profile Set environment profile for SCGI. Default is pass-through. Other available profiles are request-uri and script-name. Only the shortest unique prefix needs to be given, which happens to be p, r, and s.
- moduleName
- Name of the Python module to import. sys.path (which includes the current directory) will be searched for the module. Use the PYTHONPATH environment variable to add more search paths.
- appName
- Name of the application object within the module. This must be a Python callable object that takes 2 arguments. See [1] for more information.
- scriptName
By default, scgi-wsgi assumes your application is mounted at the virtual host root. If it isn't, you will need to specify its mount point (aka context) as the third argument to scgi-wsgi.
For example:
scgi-wsgi myappmodule app /fooIf the application is mounted at http://example.com/foo
Not setting this correctly will result in an erroneous PATH_INFO being passed to your application... which will probably break it.
scgi-wsgi exits 0 if it received a SIGINT or SIGTERM; 1 if there is a problem with the command-line arguments; 2 if there is a general problem (e.g. socket errors, thread errors, out of memory); and 3 if it received a SIGHUP.
Due to the inconsistency between the various SCGI connectors, you may need to specify an environment profile using the -E option. The default profile is pass-through. The profiles are described below:
Other SCGI modules (e.g. for lighttpd and nginx) have not yet been tested, but I imagine their handling of SCRIPT_NAME/PATH_INFO falls under one of the above.
scgi-wsgi is licensed under a standard 2-clause BSD license, reproduced below:
Copyright (c) 2006 Allan Saddi <allan@saddi.com> All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Please direct any questions to me at <allan@saddi.com>.
Please submit bug reports or patches at my general Trac site.
Now and then, there may be scgi-wsgi related news under the Python category of my projects blog.