|
IntegrationWithCherryPy
How to use CherryPy with mod_wsgi.
Integration With CherryPyNote: Requires CherryPy 3.0 or later. Note: This is not intended as a basic tutorial on how to setup mod_wsgi. It is recommended you first read more introductory material for mod_wsgi. Start by reading through various documents linked off Installation Instructions. The CherryPy framework application objects are already a WSGI compliant application. Thus a script file for a CherryPy application which is compatible with mod_wsgi would be constructed as follows: import sys
sys.stdout = sys.stderr
import atexit
import threading
import cherrypy
cherrypy.config.update({'environment': 'embedded'})
if cherrypy.engine.state == 0:
cherrypy.engine.start(blocking=False)
atexit.register(cherrypy.engine.stop)
class Root(object):
def index(self):
return 'Hello World!'
index.exposed = True
application = cherrypy.Application(Root(), None)Although the CherryPy application objects act as a WSGI application, if using CherryPy 3.0 it is necessary as shown above to startup the internal CherryPy engine and ensure that it is subsequently shutdown on process shutdown. If the CherryPy engine is not started, then the client will always see the response: 503 Service Unavailable The CherryPy engine has stopped. It is necessary to ensure that the CherryPy engine is stopped on process shutdown. This is so that any actions registered for execution on process shutdown with the CherryPy framework will be called. CherryPy 3.1 supports running CherryPy applications as WSGI applications without requiring the internal CherryPy engine be run, so for that and later versions the lines: if cherrypy.engine.state == 0:
cherrypy.engine.start(blocking=False)
atexit.register(cherrypy.engine.stop)are not required. Note that the internal CherryPy engine by default attempts to register signal handlers for SIGTERM and SIGHUP. Registration of signal handlers by a WSGI component application is not something that it should be doing as it has the potential to interfere with the operation of the web server which is hosting the application. In the case of Apache, the registration of a signal handler by CherryPy for SIGTERM can prevent Apache child processes from shutting down cleanly as it replaces the signal handler that Apache has already installed and which it uses for that purpose. To avoid such problems caused by signal handlers being registered from Python code, mod_wsgi currently ensures that all signal handler registrations from within Python code are ignored. Although this is the case, CherryPy can also be configured as shown not to register the signal handlers in the first place. This is done in this instance by configuring CherryPy as running in an 'embedded' environment. If such configuration is not done, or a version of CherryPy is used which doesn't support this option, log messages may still be found in the Apache error log file indicating when such signal handler registrations are being attempted. Because mod_wsgi is actually silently ignoring the signal handler registrations, such error messages in the Apache error log can be ignored. Also note that the CherryPy engine also defaults to logging information to sys.stdout when a portable WSGI component application should not do that. To catch such portability problems mod_wsgi restricts use of sys.stdout. Defining CherryPy as running in an 'embedded' environment should avoid this restriction, but sys.stdout is also mapped to sys.stderr in the script in case anything else also attempts to log to sys.stdout. Instead of doing the mapping in the script the WSGIRestrictStdout directive could also be set to Off. |
If you want to pass configuration to the application, do:
I'm trying to get the WSGIPythonPath server config directive to work with my cherrypy application. It does not appear to be appended to sys.path, so I presume I'm not putting the directive in the right place. If I put this somewhere in my http.conf file:
WSGIPythonPath /foo
And then modify the sample WSGI script at the top of this page:
class Root(object): def index(self): return '<br>'.join(sys.path) index.exposed = TrueShould I see /foo on the page?
If using daemon mode and mod_wsgi 2.0, you need to use python-path option to WSGIDaemonProcess and not WSGIPythonPath.
WSGIPythonPath also has no effect if using mod_wsgi 1.X and mod_python is also being loaded into Apache. This is because in that case mod_python gets to initialise the Python interpreter and thus there was no opportunity to set the PYTHON_PATH in mod_wsgi.