CherryPy Project Download

SCGI WSGI

This is a HOWTO. See BehindApache for a higher-level discussion.

A very simple setup lets your cherry run under SCGI (on apache in my setup). You need just a running apache server with mod_scgi and have the scgi python module installed. You also need an SCGI front end to WSGI. In this case, I'm using the SCGI-->WSGI application proxy, aka "SWAP" from Python Paste. Here's a direct link to SWAP. If that link doesn't work, you may have to hunt down SWAP on your own.

#!/usr/bin/python

import cherrypy
from paste.util.scgiserver import serve_application

class HelloWorld:
    
    def index(self):
        return "Hello world!"
    index.exposed = True

app = cherrypy.tree.mount(HelloWorld())
cherrypy.engine.start(blocking=False)
serve_application(application=app, prefix="/dynamic", port=4000)

The Apache configuration that goes along with this is as follows:

<Location "/dynamic">
    SCGIServer 127.0.0.1 4000
    SCGIHandler On
</Location>

Alternatively you may use scgi-wsgi

The following example uses Python 3.2, lighttpd V1.4.26, scgi-wsgi-py3 V1.1 and CherryPy V3.2

Download scgi-wsgi I suggest using the latest code from mercurial. Check it out, and follow the instructions in README to build it.

Then create a sample application:

your_webapp.py:

#!/usr/bin/python3
import sys
import cherrypy

# Check if we are a child of the SCGI-WSGI interface
SCGIWSGI = (sys.argv[0] == 'scgi-wsgi')

# Default configurations - could get from a file.
ROOTCONFIG={'/':{}}
GLOBALCONFIG={}

# Adjust configurations to suit running under scgi-wsgi or native
if SCGIWSGI:
  WEBBASE='/your_webapp'
else:
  WEBBASE='/'
  GLOBALCONFIG.update({'server.socket_host':"0.0.0.0",
                       'server.socket_port': 8080,
                       'server.thread_pool': 10})

class Root:
    @cherrypy.expose
    def index(self):
        return "Hello world!"

class Branch:
    @cherrypy.expose
    def index(self):
        return "Howdy"
    
    @cherrypy.expose 
    def default(self, attr='abc'):
        return attr.upper()
    
    @cherrypy.expose
    def leaf(self, size=0):
        return str(int(size) + 3)
    
# Set Global configuration
cherrypy.config.update(GLOBALCONFIG)

# Define our website pages
root = Root()
root.branch = Branch()
app = cherrypy.tree.mount(root, script_name=WEBBASE, config=ROOTCONFIG)

# If running under scgi-wsgi then we dont need the built in http server or auto-reload.
if (SCGIWSGI) :
  # Prevent default Built In HTTP Server running.
  cherrypy.server.unsubscribe()
  # Autorestart doesn't work under scgi-wsgi server.
  cherrypy.config.update({'engine.autoreload_on':False})

# Initialise signal handler.
if hasattr(cherrypy.engine, 'signal_handler'):
    cherrypy.engine.signal_handler.subscribe()

# Initialise console control
if hasattr(cherrypy.engine, "console_control_handler"):
    cherrypy.engine.console_control_handler.subscribe()

# Start the engine.
cherrypy.engine.start()

# Running standalone?  if so we need to block.
if (not SCGIWSGI) :
  cherrypy.engine.block()

This application will run standalone with the embedded http server standard with CherryPy. But if you run it:

./scgi-wsgi -v your_webapp app

It will execute under the scgi-wsgi server and will be able to interface to Apache or Lighttpd. I only have tested against Lighttpd.

Example Lighttpd configs

10-scgi.conf:

## SCGI programs have the same functionality as CGI programs,
## but are considerably faster through lower interpreter startup
## time and socketed communication
##
## Documentation: /usr/share/doc/lighttpd-doc/fastcgi.txt.gz
##                http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ConfigurationOptions#mod_fastcgi-fastcgi

server.modules += ( "mod_scgi" )
#debug.log-request-handling = "enable"
#scgi.debug = 1

50-your_webapp.conf :

# Alias for your_webapp directory
alias.url += (
        "/imbibe" => "/opt/your_webapp/www",
)

$HTTP["url"] =~ "^/your_webapp" {
  scgi.server = (
                  "/" =>
                    ( "127.0.0.1" =>
                      (
                        "host" => "127.0.0.1",
                        "port" => 4000,
                        "check-local" => "disable",
                        "docroot" => "/opt/your_webapp/www"
                      )
                    )
                )
}

Place these files in your lighttpd "conf-available" directory and enable them with "lighttpd-enable-mod"

restart Lighttpd.

Browse to http://yourserver/your_webapp and you should see the sample running under Lighttpd using SCGI.

Older versions

2.2

This example uses the VirtualPathFilter? (not needed in CP 3); feel free to ignore it if you don't need it.

#!/usr/bin/python

import cherrypy
from virtualpathfilter import VirtualPathFilter
from cherrypy._cpwsgi import wsgiApp
from paste.util.scgiserver import serve_application

class HelloWorld:
    """ Sample request handler class. """
    _cpFilterList = [VirtualPathFilter()]

    def index(self):
        return "Hello world!"
    index.exposed = True

cherrypy.root = HelloWorld()
cherrypy.config.update({
    '/': {
        'server.environment': 'development',
        'virtualPathFilter.on': True,
        'virtualPathFilter.prefix': "/dynamic"
    }
})

# init cp
cherrypy.server.start(initOnly=True, serverClass=None)

# run the server
serve_application(application=wsgiApp, prefix="/dynamic", port=4000)

Hosted by WebFaction

Log in as guest/cherrypy to create/edit wiki pages