cherrypy.process package

Submodules

cherrypy.process.plugins module

Site services for use with a Web Site Process Bus.

class cherrypy.process.plugins.Autoreloader(bus, frequency=1, match='.*')

Bases: cherrypy.process.plugins.Monitor

Monitor which re-executes the process when files change.

This plugin restarts the process (via os.execv()) if any of the files it monitors change (or is deleted). By default, the autoreloader monitors all imported modules; you can add to the set by adding to autoreload.files:

cherrypy.engine.autoreload.files.add(myFile)

If there are imported files you do not wish to monitor, you can adjust the match attribute, a regular expression. For example, to stop monitoring cherrypy itself:

cherrypy.engine.autoreload.match = r'^(?!cherrypy).+'

Like all Monitor plugins, the autoreload plugin takes a frequency argument. The default is 1 second; that is, the autoreloader will examine files once each second.

files = None

The set of files to poll for modifications.

frequency = 1

The interval in seconds at which to poll for modified files.

match = '.*'

A regular expression by which to match filenames.

run()

Reload the process if registered files have been modified.

start()

Start our own background task thread for self.run.

sysfiles()

Return a Set of sys.modules filenames to monitor.

class cherrypy.process.plugins.BackgroundTask(interval, function, args=[], kwargs={}, bus=None)

Bases: threading.Thread

A subclass of threading.Thread whose run() method repeats.

Use this class for most repeating tasks. It uses time.sleep() to wait for each interval, which isn’t very responsive; that is, even if you call self.cancel(), you’ll have to wait until the sleep() call finishes before the thread stops. To compensate, it defaults to being daemonic, which means it won’t delay stopping the whole process.

cancel()
run()
class cherrypy.process.plugins.Daemonizer(bus, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null')

Bases: cherrypy.process.plugins.SimplePlugin

Daemonize the running script.

Use this with a Web Site Process Bus via:

Daemonizer(bus).subscribe()

When this component finishes, the process is completely decoupled from the parent environment. Please note that when this component is used, the return code from the parent process will still be 0 if a startup error occurs in the forked children. Errors in the initial daemonizing process still return proper exit codes. Therefore, if you use this plugin to daemonize, don’t use the return code as an accurate indicator of whether the process fully started. In fact, that return code only indicates if the process succesfully finished the first fork.

start()
class cherrypy.process.plugins.DropPrivileges(bus, umask=None, uid=None, gid=None)

Bases: cherrypy.process.plugins.SimplePlugin

Drop privileges. uid/gid arguments not available on Windows.

Special thanks to Gavin Baker

gid

The gid under which to run. Availability: Unix.

start()
uid

The uid under which to run. Availability: Unix.

umask

The default permission mode for newly created files and directories.

Usually expressed in octal format, for example, 0644. Availability: Unix, Windows.

class cherrypy.process.plugins.Monitor(bus, callback, frequency=60, name=None)

Bases: cherrypy.process.plugins.SimplePlugin

WSPBus listener to periodically run a callback in its own thread.

callback = None

The function to call at intervals.

frequency = 60

The time in seconds between callback runs.

graceful()

Stop the callback’s background task thread and restart it.

start()

Start our callback in its own background thread.

stop()

Stop our callback’s background task thread.

thread = None

A BackgroundTask thread.

class cherrypy.process.plugins.PIDFile(bus, pidfile)

Bases: cherrypy.process.plugins.SimplePlugin

Maintain a PID file via a WSPBus.

exit()
start()
class cherrypy.process.plugins.PerpetualTimer(*args, **kwargs)

Bases: threading.Timer

A responsive subclass of threading.Timer whose run() method repeats.

Use this timer only when you really need a very interruptible timer; this checks its ‘finished’ condition up to 20 times a second, which can results in pretty high CPU usage

run()
class cherrypy.process.plugins.SignalHandler(bus)

Bases: object

Register bus channels (and listeners) for system signals.

You can modify what signals your application listens for, and what it does when it receives signals, by modifying SignalHandler.handlers, a dict of {signal name: callback} pairs. The default set is:

handlers = {'SIGTERM': self.bus.exit,
            'SIGHUP': self.handle_SIGHUP,
            'SIGUSR1': self.bus.graceful,
           }

The SignalHandler.handle_SIGHUP`() method calls bus.restart() if the process is daemonized, but bus.exit() if the process is attached to a TTY. This is because Unix window managers tend to send SIGHUP to terminal windows when the user closes them.

Feel free to add signals which are not available on every platform. The SignalHandler will ignore errors raised from attempting to register handlers for unknown signals.

handle_SIGHUP()

Restart if daemonized, else exit.

handlers = {}

A map from signal names (e.g. ‘SIGTERM’) to handlers (e.g. bus.exit).

set_handler(signal, listener=None)

Subscribe a handler for the given signal (number or name).

If the optional ‘listener’ argument is provided, it will be subscribed as a listener for the given signal’s channel.

If the given signal name or number is not available on the current platform, ValueError is raised.

signals = {64: 'SIGRTMAX', 1: 'SIGHUP', 2: 'SIGINT', 3: 'SIGQUIT', 4: 'SIGILL', 5: 'SIGTRAP', 6: 'SIGIOT', 7: 'SIGBUS', 8: 'SIGFPE', 9: 'SIGKILL', 10: 'SIGUSR1', 11: 'SIGSEGV', 12: 'SIGUSR2', 13: 'SIGPIPE', 14: 'SIGALRM', 15: 'SIGTERM', 17: 'SIGCHLD', 18: 'SIGCONT', 19: 'SIGSTOP', 20: 'SIGTSTP', 21: 'SIGTTIN', 22: 'SIGTTOU', 23: 'SIGURG', 24: 'SIGXCPU', 25: 'SIGXFSZ', 26: 'SIGVTALRM', 27: 'SIGPROF', 28: 'SIGWINCH', 29: 'SIGPOLL', 30: 'SIGPWR', 31: 'SIGSYS', 34: 'SIGRTMIN'}

A map from signal numbers to names.

subscribe()

Subscribe self.handlers to signals.

unsubscribe()

Unsubscribe self.handlers from signals.

class cherrypy.process.plugins.SimplePlugin(bus)

Bases: object

Plugin base class which auto-subscribes methods for known channels.

bus = None

A Bus, usually cherrypy.engine.

subscribe()

Register this object as a (multi-channel) listener on the bus.

unsubscribe()

Unregister this object as a listener on the bus.

class cherrypy.process.plugins.ThreadManager(bus)

Bases: cherrypy.process.plugins.SimplePlugin

Manager for HTTP request threads.

If you have control over thread creation and destruction, publish to the ‘acquire_thread’ and ‘release_thread’ channels (for each thread). This will register/unregister the current thread and publish to ‘start_thread’ and ‘stop_thread’ listeners in the bus as needed.

If threads are created and destroyed by code you do not control (e.g., Apache), then, at the beginning of every HTTP request, publish to ‘acquire_thread’ only. You should not publish to ‘release_thread’ in this case, since you do not know whether the thread will be re-used or not. The bus will call ‘stop_thread’ listeners for you when it stops.

acquire_thread()

Run ‘start_thread’ listeners for the current thread.

If the current thread has already been seen, any ‘start_thread’ listeners will not be run again.

graceful()

Release all threads and run all ‘stop_thread’ listeners.

release_thread()

Release the current thread and run ‘stop_thread’ listeners.

stop()

Release all threads and run all ‘stop_thread’ listeners.

threads = None

A map of {thread ident: index number} pairs.

cherrypy.process.servers module

Starting in CherryPy 3.1, cherrypy.server is implemented as an Engine Plugin. It’s an instance of cherrypy._cpserver.Server, which is a subclass of cherrypy.process.servers.ServerAdapter. The ServerAdapter class is designed to control other servers, as well.

Multiple servers/ports

If you need to start more than one HTTP server (to serve on multiple ports, or protocols, etc.), you can manually register each one and then start them all with engine.start:

s1 = ServerAdapter(
    cherrypy.engine,
    MyWSGIServer(host='0.0.0.0', port=80)
)
s2 = ServerAdapter(
    cherrypy.engine,
    another.HTTPServer(host='127.0.0.1', SSL=True)
)
s1.subscribe()
s2.subscribe()
cherrypy.engine.start()

FastCGI/SCGI

There are also FlupFCGIServer and FlupSCGIServer classes in cherrypy.process.servers. To start an fcgi server, for example, wrap an instance of it in a ServerAdapter:

addr = ('0.0.0.0', 4000)
f = servers.FlupFCGIServer(application=cherrypy.tree, bindAddress=addr)
s = servers.ServerAdapter(cherrypy.engine, httpserver=f, bind_addr=addr)
s.subscribe()

The cherryd startup script will do the above for you via its -f flag. Note that you need to download and install flup yourself, whether you use cherryd or not.

FastCGI

A very simple setup lets your cherry run with FastCGI. You just need the flup library, plus a running Apache server (with mod_fastcgi) or lighttpd server.

CherryPy code

hello.py:

#!/usr/bin/python
import cherrypy

class HelloWorld:
    '''Sample request handler class.'''
    @cherrypy.expose
    def index(self):
        return "Hello world!"

cherrypy.tree.mount(HelloWorld())
# CherryPy autoreload must be disabled for the flup server to work
cherrypy.config.update({'engine.autoreload.on':False})

Then run /deployguide/cherryd with the ‘-f’ arg:

cherryd -c <myconfig> -d -f -i hello.py
Apache

At the top level in httpd.conf:

FastCgiIpcDir /tmp
FastCgiServer /path/to/cherry.fcgi -idle-timeout 120 -processes 4

And inside the relevant VirtualHost section:

# FastCGI config
AddHandler fastcgi-script .fcgi
ScriptAliasMatch (.*$) /path/to/cherry.fcgi$1
Lighttpd

For Lighttpd you can follow these instructions. Within lighttpd.conf make sure mod_fastcgi is active within server.modules. Then, within your $HTTP["host"] directive, configure your fastcgi script like the following:

$HTTP["url"] =~ "" {
  fastcgi.server = (
    "/" => (
      "script.fcgi" => (
        "bin-path" => "/path/to/your/script.fcgi",
        "socket"          => "/tmp/script.sock",
        "check-local"     => "disable",
        "disable-time"    => 1,
        "min-procs"       => 1,
        "max-procs"       => 1, # adjust as needed
      ),
    ),
  )
} # end of $HTTP["url"] =~ "^/"

Please see Lighttpd FastCGI Docs for an explanation of the possible configuration options.

class cherrypy.process.servers.FlupCGIServer(*args, **kwargs)

Bases: object

Adapter for a flup.server.cgi.WSGIServer.

start()

Start the CGI server.

stop()

Stop the HTTP server.

class cherrypy.process.servers.FlupFCGIServer(*args, **kwargs)

Bases: object

Adapter for a flup.server.fcgi.WSGIServer.

start()

Start the FCGI server.

stop()

Stop the HTTP server.

class cherrypy.process.servers.FlupSCGIServer(*args, **kwargs)

Bases: object

Adapter for a flup.server.scgi.WSGIServer.

start()

Start the SCGI server.

stop()

Stop the HTTP server.

class cherrypy.process.servers.ServerAdapter(bus, httpserver=None, bind_addr=None)

Bases: object

Adapter for an HTTP server.

If you need to start more than one HTTP server (to serve on multiple ports, or protocols, etc.), you can manually register each one and then start them all with bus.start:

s1 = ServerAdapter(bus, MyWSGIServer(host='0.0.0.0', port=80))
s2 = ServerAdapter(bus, another.HTTPServer(host='127.0.0.1', SSL=True))
s1.subscribe()
s2.subscribe()
bus.start()
bound_addr

The bind address, or if it’s an ephemeral port and the socket has been bound, return the actual port bound.

description

A description about where this server is bound.

restart()

Restart the HTTP server.

start()

Start the HTTP server.

stop()

Stop the HTTP server.

subscribe()
unsubscribe()
wait()

Wait until the HTTP server is ready to receive requests.

cherrypy.process.servers.check_port(host, port, timeout=1.0)

Raise an error if the given port is not free on the given host.

cherrypy.process.servers.client_host(server_host)

Return the host on which a client can connect to the given listener.

cherrypy.process.servers.wait_for_free_port(host, port, timeout=None)

Wait for the specified port to become free (drop requests).

cherrypy.process.servers.wait_for_occupied_port(host, port, timeout=None)

Wait for the specified port to become active (receive requests).

cherrypy.process.win32 module

Windows service. Requires pywin32.

class cherrypy.process.win32.ConsoleCtrlHandler(bus)

Bases: cherrypy.process.plugins.SimplePlugin

A WSPBus plugin for handling Win32 console events (like Ctrl-C).

handle(event)

Handle console control events (like Ctrl-C).

start()
stop()
class cherrypy.process.win32.Win32Bus

Bases: cherrypy.process.wspbus.Bus

A Web Site Process Bus implementation for Win32.

Instead of time.sleep, this bus blocks using native win32event objects.

state
wait(state, interval=0.1, channel=None)

Wait for the given state(s), KeyboardInterrupt or SystemExit.

Since this class uses native win32event objects, the interval argument is ignored.

cherrypy.process.win32.signal_child(service, command)

cherrypy.process.wspbus module

An implementation of the Web Site Process Bus.

This module is completely standalone, depending only on the stdlib.

Web Site Process Bus

A Bus object is used to contain and manage site-wide behavior: daemonization, HTTP server start/stop, process reload, signal handling, drop privileges, PID file management, logging for all of these, and many more.

In addition, a Bus object provides a place for each web framework to register code that runs in response to site-wide events (like process start and stop), or which controls or otherwise interacts with the site-wide components mentioned above. For example, a framework which uses file-based templates would add known template filenames to an autoreload component.

Ideally, a Bus object will be flexible enough to be useful in a variety of invocation scenarios:

  1. The deployer starts a site from the command line via a framework-neutral deployment script; applications from multiple frameworks are mixed in a single site. Command-line arguments and configuration files are used to define site-wide components such as the HTTP server, WSGI component graph, autoreload behavior, signal handling, etc.
  2. The deployer starts a site via some other process, such as Apache; applications from multiple frameworks are mixed in a single site. Autoreload and signal handling (from Python at least) are disabled.
  3. The deployer starts a site via a framework-specific mechanism; for example, when running tests, exploring tutorials, or deploying single applications from a single framework. The framework controls which site-wide components are enabled as it sees fit.

The Bus object in this package uses topic-based publish-subscribe messaging to accomplish all this. A few topic channels are built in (‘start’, ‘stop’, ‘exit’, ‘graceful’, ‘log’, and ‘main’). Frameworks and site containers are free to define their own. If a message is sent to a channel that has not been defined or has no listeners, there is no effect.

In general, there should only ever be a single Bus object per process. Frameworks and site containers share a single Bus object by publishing messages and subscribing listeners.

The Bus object works as a finite state machine which models the current state of the process. Bus methods move it from one state to another; those methods then publish to subscribed listeners on the channel for the new state.:

                 O
                 |
                 V
STOPPING --> STOPPED --> EXITING -> X
   A   A         |
   |    \___     |
   |        \    |
   |         V   V
 STARTED <-- STARTING
class cherrypy.process.wspbus.Bus

Bases: object

Process state-machine and messenger for HTTP site deployment.

All listeners for a given channel are guaranteed to be called even if others at the same channel fail. Each failure is logged, but execution proceeds on to the next listener. The only way to stop all processing from inside a listener is to raise SystemExit and stop the whole server.

block(interval=0.1)

Wait for the EXITING state, KeyboardInterrupt or SystemExit.

This function is intended to be called only by the main thread. After waiting for the EXITING state, it also waits for all threads to terminate, and then calls os.execv if self.execv is True. This design allows another thread to call bus.restart, yet have the main thread perform the actual execv call (required on some platforms).

execv = False
exit()

Stop all services and prepare to exit the process.

graceful()

Advise all services to reload.

log(msg='', level=20, traceback=False)

Log the given message. Append the last traceback if requested.

max_cloexec_files = 524288
publish(channel, *args, **kwargs)

Return output of all subscribers for the given channel.

restart()

Restart the process (may close connections).

This method does not restart the process from the calling thread; instead, it stops the bus and asks the main thread to call execv.

start()

Start all services.

start_with_callback(func, args=None, kwargs=None)

Start ‘func’ in a new thread T, then start self (and return T).

state = states.STOPPED
states = <cherrypy.process.wspbus._StateEnum object>
stop()

Stop all services.

subscribe(channel, callback, priority=None)

Add the given callback at the given channel (if not present).

unsubscribe(channel, callback)

Discard the given callback (if present).

wait(state, interval=0.1, channel=None)

Poll for the given state(s) at intervals; publish to channel.

exception cherrypy.process.wspbus.ChannelFailures(*args, **kwargs)

Bases: Exception

Exception raised when errors occur in a listener during Bus.publish().

delimiter = '\n'
get_instances()

Return a list of seen exception instances.

handle_exception()

Append the current exception to self.

Module contents

Site container for an HTTP server.

A Web Site Process Bus object is used to connect applications, servers, and frameworks with site-wide services such as daemonization, process reload, signal handling, drop privileges, PID file management, logging for all of these, and many more.

The ‘plugins’ module defines a few abstract and concrete services for use with the bus. Some use tool-specific channels; see the documentation for each class.