cherrypy.lib package


cherrypy.lib.auth_basic module

HTTP Basic Authentication tool.

This module provides a CherryPy 3.x tool which implements the server-side of HTTP Basic Access Authentication, as described in RFC 2617.

Example usage, using the built-in checkpassword_dict function which uses a dict as the credentials store:

userpassdict = {'bird' : 'bebop', 'ornette' : 'wayout'}
checkpassword = cherrypy.lib.auth_basic.checkpassword_dict(userpassdict)
basic_auth = {'tools.auth_basic.on': True,
              'tools.auth_basic.realm': 'earth',
              'tools.auth_basic.checkpassword': checkpassword,
              'tools.auth_basic.accept_charset': 'UTF-8',
app_config = { '/' : basic_auth }
cherrypy.lib.auth_basic.basic_auth(realm, checkpassword, debug=False, accept_charset='utf-8')[source]

A CherryPy tool which hooks at before_handler to perform HTTP Basic Access Authentication, as specified in RFC 2617 and RFC 7617.

If the request has an ‘authorization’ header with a ‘Basic’ scheme, this tool attempts to authenticate the credentials supplied in that header. If the request has no ‘authorization’ header, or if it does but the scheme is not ‘Basic’, or if authentication fails, the tool sends a 401 response with a ‘WWW-Authenticate’ Basic header.

A string containing the authentication realm.
A callable which checks the authentication credentials. Its signature is checkpassword(realm, username, password). where username and password are the values obtained from the request’s ‘authorization’ header. If authentication succeeds, checkpassword returns True, else it returns False.

Returns a checkpassword function which checks credentials against a dictionary of the form: {username : password}.

If you want a simple dictionary-based authentication scheme, use checkpassword_dict(my_credentials_dict) as the value for the checkpassword argument to basic_auth().

cherrypy.lib.auth_digest module

HTTP Digest Authentication tool.

An implementation of the server-side of HTTP Digest Access Authentication, which is described in RFC 2617.

Example usage, using the built-in get_ha1_dict_plain function which uses a dict of plaintext passwords as the credentials store:

userpassdict = {'alice' : '4x5istwelve'}
get_ha1 = cherrypy.lib.auth_digest.get_ha1_dict_plain(userpassdict)
digest_auth = {'tools.auth_digest.on': True,
               'tools.auth_digest.realm': 'wonderland',
               'tools.auth_digest.get_ha1': get_ha1,
               'tools.auth_digest.key': 'a565c27146791cfb',
               'tools.auth_digest.accept_charset': 'UTF-8',
app_config = { '/' : digest_auth }

The hash function H

class cherrypy.lib.auth_digest.HttpDigestAuthorization(auth_header, http_method, debug=False, accept_charset='UTF-8')[source]

Bases: object

Parses a Digest Authorization header and performs re-calculation of the digest.


Returns the H(A2) string. See RFC 2617 section


Returns True if a validated nonce is stale. The nonce contains a timestamp in plaintext and also a secure hash of the timestamp. You should first validate the nonce to ensure the plaintext timestamp is not spoofed.

classmethod matches(header)[source]
request_digest(ha1, entity_body='')[source]

Calculates the Request-Digest. See RFC 2617 section

The HA1 string obtained from the credentials store.
If ‘qop’ is set to ‘auth-int’, then A2 includes a hash of the “entity body”. The entity body is the part of the message which follows the HTTP headers. See RFC 2617 section 4.3. This refers to the entity the user agent sent in the request which has the Authorization header. Typically GET requests don’t have an entity, and POST requests do.
scheme = 'digest'
validate_nonce(s, key)[source]

Validate the nonce. Returns True if nonce was generated by synthesize_nonce() and the timestamp is not spoofed, else returns False.

A string related to the resource, such as the hostname of the server.
A secret string known only to the server.

Both s and key must be the same values which were used to synthesize the nonce we are trying to validate.

cherrypy.lib.auth_digest.digest_auth(realm, get_ha1, key, debug=False, accept_charset='utf-8')[source]

A CherryPy tool that hooks at before_handler to perform HTTP Digest Access Authentication, as specified in RFC 2617.

If the request has an ‘authorization’ header with a ‘Digest’ scheme, this tool authenticates the credentials supplied in that header. If the request has no ‘authorization’ header, or if it does but the scheme is not “Digest”, or if authentication fails, the tool sends a 401 response with a ‘WWW-Authenticate’ Digest header.

A string containing the authentication realm.
A callable that looks up a username in a credentials store and returns the HA1 string, which is defined in the RFC to be MD5(username : realm : password). The function’s signature is: get_ha1(realm, username) where username is obtained from the request’s ‘authorization’ header. If username is not found in the credentials store, get_ha1() returns None.
A secret string known only to the server, used in the synthesis of nonces.

Returns a get_ha1 function which obtains a HA1 password hash from a dictionary of the form: {username : HA1}.

If you want a dictionary-based authentication scheme, but with pre-computed HA1 hashes instead of plain-text passwords, use get_ha1_dict(my_userha1_dict) as the value for the get_ha1 argument to digest_auth().


Returns a get_ha1 function which obtains a plaintext password from a dictionary of the form: {username : password}.

If you want a simple dictionary-based authentication scheme, with plaintext passwords, use get_ha1_dict_plain(my_userpass_dict) as the value for the get_ha1 argument to digest_auth().


Returns a get_ha1 function which obtains a HA1 password hash from a flat file with lines of the same format as that produced by the Apache htdigest utility. For example, for realm ‘wonderland’, username ‘alice’, and password ‘4x5istwelve’, the htdigest line would be:


If you want to use an Apache htdigest file as the credentials store, then use get_ha1_file_htdigest(my_htdigest_file) as the value for the get_ha1 argument to digest_auth(). It is recommended that the filename argument be an absolute path, to avoid problems.

cherrypy.lib.auth_digest.synthesize_nonce(s, key, timestamp=None)[source]

Synthesize a nonce value which resists spoofing and can be checked for staleness. Returns a string suitable as the value for ‘nonce’ in the www-authenticate header.

A string related to the resource, such as the hostname of the server.
A secret string known only to the server.
An integer seconds-since-the-epoch timestamp
cherrypy.lib.auth_digest.www_authenticate(realm, key, algorithm='MD5', nonce=None, qop='auth', stale=False, accept_charset='UTF-8')[source]

Constructs a WWW-Authenticate header for Digest authentication.

cherrypy.lib.caching module

CherryPy implements a simple caching system as a pluggable Tool. This tool tries to be an (in-process) HTTP/1.1-compliant cache. It’s not quite there yet, but it’s probably good enough for most sites.

In general, GET responses are cached (along with selecting headers) and, if another request arrives for the same resource, the caching Tool will return 304 Not Modified if possible, or serve the cached response otherwise. It also sets request.cached to True if serving a cached representation, and sets request.cacheable to False (so it doesn’t get cached again).

If POST, PUT, or DELETE requests are made for a cached resource, they invalidate (delete) any cached response.


Configuration file example:

tools.caching.on = True
tools.caching.delay = 3600

You may use a class other than the default MemoryCache by supplying the config entry cache_class; supply the full dotted name of the replacement class as the config value. It must implement the basic methods get, put, delete, and clear.

You may set any attribute, including overriding methods, on the cache instance by providing them in config. The above sets the delay attribute, for example.

class cherrypy.lib.caching.AntiStampedeCache[source]

Bases: dict

A storage system for cached items which reduces stampede collisions.

wait(key, timeout=5, debug=False)[source]

Return the cached value for the given key, or None.

If timeout is not None, and the value is already being calculated by another thread, wait until the given timeout has elapsed. If the value is available before the timeout expires, it is returned. If not, None is returned, and a sentinel placed in the cache to signal other threads to wait.

If timeout is None, no waiting is performed nor sentinels used.

class cherrypy.lib.caching.Cache[source]

Bases: object

Base class for Cache implementations.


Reset the cache to its initial, empty state.


Remove ALL cached variants of the current resource.


Return the current variant if in the cache, else None.

put(obj, size)[source]

Store the current variant in the cache.

class cherrypy.lib.caching.MemoryCache[source]

Bases: cherrypy.lib.caching.Cache

An in-memory cache for varying response content.

Each key in is a URI, and each value is an AntiStampedeCache. The response for any given URI may vary based on the values of “selecting request headers”; that is, those named in the Vary response header. We assume the list of header names to be constant for each URI throughout the lifetime of the application, and store that list in[uri].selecting_headers.

The items contained in[uri] have keys which are tuples of request header values (in the same order as the names in its selecting_headers), and values which are the actual responses.

antistampede_timeout = 5

Seconds to wait for other threads to release a cache lock.


Reset the cache to its initial, empty state.

debug = False
delay = 600

Seconds until the cached content expires; defaults to 600 (10 minutes).


Remove ALL cached variants of the current resource.


Continuously examine cached objects, expiring stale ones.

This function is designed to be run in its own daemon thread, referenced at self.expiration_thread.

expire_freq = 0.1

Seconds to sleep between cache expiration sweeps.


Return the current variant if in the cache, else None.

maxobj_size = 100000

The maximum size of each cached object in bytes; defaults to 100 KB.

maxobjects = 1000

The maximum number of cached objects; defaults to 1000.

maxsize = 10000000

The maximum size of the entire cache in bytes; defaults to 10 MB.

put(variant, size)[source]

Store the current variant in the cache.

cherrypy.lib.caching.expires(secs=0, force=False, debug=False)[source]

Tool for influencing cache mechanisms using the ‘Expires’ header.


Must be either an int or a datetime.timedelta, and indicates the number of seconds between response.time and when the response should expire. The ‘Expires’ header will be set to response.time + secs. If secs is zero, the ‘Expires’ header is set one year in the past, and the following “cache prevention” headers are also set:

  • Pragma: no-cache
  • Cache-Control’: no-cache, must-revalidate

If False, the following headers are checked:

  • Etag
  • Last-Modified
  • Age
  • Expires

If any are already present, none of the above response headers are set.

cherrypy.lib.caching.get(invalid_methods=('POST', 'PUT', 'DELETE'), debug=False, **kwargs)[source]

Try to obtain cached output. If fresh enough, raise HTTPError(304).

  • invalidates (deletes) any cached response for this resource
  • sets request.cached = False
  • sets request.cacheable = False
else if a cached copy exists:
  • sets request.cached = True
  • sets request.cacheable = False
  • sets response.headers to the cached values
  • checks the cached Last-Modified response header against the current If-(Un)Modified-Since request headers; raises 304 if necessary.
  • sets response.status and response.body to the cached values
  • returns True
  • sets request.cached = False
  • sets request.cacheable = True
  • returns False

Tee response output to cache storage. Internal.

cherrypy.lib.covercp module

Code-coverage tools for CherryPy.

To use this module, or the coverage tools in the test suite, you need to download ‘’, either Gareth Rees’ original implementation or Ned Batchelder’s enhanced version:

To turn on coverage tracing, use the following code:

cherrypy.engine.subscribe('start', covercp.start)

DO NOT subscribe anything on the ‘start_thread’ channel, as previously recommended. Calling start once in the main thread should be sufficient to start coverage on all threads. Calling start again in each thread effectively clears any coverage data gathered up to that point.

Run your code, then use the covercp.serve() function to browse the results in a web browser. If you run this module from the command line, it will call serve() for you.

class cherrypy.lib.covercp.CoverStats(coverage, root=None)[source]

Bases: object

annotated_file(filename, statements, excluded, missing)[source]
menu(base='/', pct='50', showpct='', exclude='python\\d\\.\\d|test|tut\\d|tutorial')[source]
cherrypy.lib.covercp.get_tree(base, exclude, coverage=<coverage.control.Coverage object>)[source]

Return covered module names as a nested dict.

cherrypy.lib.covercp.serve(path='/home/docs/checkouts/', port=8080, root=None)[source]

cherrypy.lib.cpstats module

CPStats, a package for collecting and reporting on program statistics.


Statistics about program operation are an invaluable monitoring and debugging tool. Unfortunately, the gathering and reporting of these critical values is usually ad-hoc. This package aims to add a centralized place for gathering statistical performance data, a structure for recording that data which provides for extrapolation of that data into more useful information, and a method of serving that data to both human investigators and monitoring software. Let’s examine each of those in more detail.

Data Gathering

Just as Python’s logging module provides a common importable for gathering and sending messages, performance statistics would benefit from a similar common mechanism, and one that does not require each package which wishes to collect stats to import a third-party module. Therefore, we choose to re-use the logging module by adding a statistics object to it.

That logging.statistics object is a nested dict. It is not a custom class, because that would:

  1. require libraries and applications to import a third-party module in order to participate
  2. inhibit innovation in extrapolation approaches and in reporting tools, and
  3. be slow.

There are, however, some specifications regarding the structure of the dict.:

  +----"SQLAlchemy": {
  |        "Inserts": 4389745,
  |        "Inserts per Second":
  |            lambda s: s["Inserts"] / (time() - s["Start"]),
  |  C +---"Table Statistics": {
  |  o |        "widgets": {-----------+
N |  l |            "Rows": 1.3M,      | Record
a |  l |            "Inserts": 400,    |
m |  e |        },---------------------+
e |  c |        "froobles": {
s |  t |            "Rows": 7845,
p |  i |            "Inserts": 0,
a |  o |        },
c |  n +---},
e |        "Slow Queries":
  |            [{"Query": "SELECT * FROM widgets;",
  |              "Processing Time": 47.840923343,
  |              },
  |             ],

The logging.statistics dict has four levels. The topmost level is nothing more than a set of names to introduce modularity, usually along the lines of package names. If the SQLAlchemy project wanted to participate, for example, it might populate the item logging.statistics[‘SQLAlchemy’], whose value would be a second-layer dict we call a “namespace”. Namespaces help multiple packages to avoid collisions over key names, and make reports easier to read, to boot. The maintainers of SQLAlchemy should feel free to use more than one namespace if needed (such as ‘SQLAlchemy ORM’). Note that there are no case or other syntax constraints on the namespace names; they should be chosen to be maximally readable by humans (neither too short nor too long).

Each namespace, then, is a dict of named statistical values, such as ‘Requests/sec’ or ‘Uptime’. You should choose names which will look good on a report: spaces and capitalization are just fine.

In addition to scalars, values in a namespace MAY be a (third-layer) dict, or a list, called a “collection”. For example, the CherryPy StatsTool keeps track of what each request is doing (or has most recently done) in a ‘Requests’ collection, where each key is a thread ID; each value in the subdict MUST be a fourth dict (whew!) of statistical data about each thread. We call each subdict in the collection a “record”. Similarly, the StatsTool also keeps a list of slow queries, where each record contains data about each slow query, in order.

Values in a namespace or record may also be functions, which brings us to:


The collection of statistical data needs to be fast, as close to unnoticeable as possible to the host program. That requires us to minimize I/O, for example, but in Python it also means we need to minimize function calls. So when you are designing your namespace and record values, try to insert the most basic scalar values you already have on hand.

When it comes time to report on the gathered data, however, we usually have much more freedom in what we can calculate. Therefore, whenever reporting tools (like the provided StatsPage CherryPy class) fetch the contents of logging.statistics for reporting, they first call extrapolate_statistics (passing the whole statistics dict as the only argument). This makes a deep copy of the statistics dict so that the reporting tool can both iterate over it and even change it without harming the original. But it also expands any functions in the dict by calling them. For example, you might have a ‘Current Time’ entry in the namespace with the value “lambda scope: time.time()”. The “scope” parameter is the current namespace dict (or record, if we’re currently expanding one of those instead), allowing you access to existing static entries. If you’re truly evil, you can even modify more than one entry at a time.

However, don’t try to calculate an entry and then use its value in further extrapolations; the order in which the functions are called is not guaranteed. This can lead to a certain amount of duplicated work (or a redesign of your schema), but that’s better than complicating the spec.

After the whole thing has been extrapolated, it’s time for:


The StatsPage class grabs the logging.statistics dict, extrapolates it all, and then transforms it to HTML for easy viewing. Each namespace gets its own header and attribute table, plus an extra table for each collection. This is NOT part of the statistics specification; other tools can format how they like.

You can control which columns are output and how they are formatted by updating StatsPage.formatting, which is a dict that mirrors the keys and nesting of logging.statistics. The difference is that, instead of data values, it has formatting values. Use None for a given key to indicate to the StatsPage that a given column should not be output. Use a string with formatting (such as ‘%.3f’) to interpolate the value(s), or use a callable (such as lambda v: v.isoformat()) for more advanced formatting. Any entry which is not mentioned in the formatting dict is output unchanged.


Although the HTML output takes pains to assign unique id’s to each <td> with statistical data, you’re probably better off fetching /cpstats/data, which outputs the whole (extrapolated) logging.statistics dict in JSON format. That is probably easier to parse, and doesn’t have any formatting controls, so you get the “original” data in a consistently-serialized format. Note: there’s no treatment yet for datetime objects. Try time.time() instead for now if you can. Nagios will probably thank you.

Turning Collection Off

It is recommended each namespace have an “Enabled” item which, if False, stops collection (but not reporting) of statistical data. Applications SHOULD provide controls to pause and resume collection by setting these entries to False or True, if present.


To collect statistics on CherryPy applications:

from cherrypy.lib import cpstats
appconfig['/']['tools.cpstats.on'] = True

To collect statistics on your own code:

import logging
# Initialize the repository
if not hasattr(logging, 'statistics'): logging.statistics = {}
# Initialize my namespace
mystats = logging.statistics.setdefault('My Stuff', {})
# Initialize my namespace's scalars and collections
    'Enabled': True,
    'Start Time': time.time(),
    'Important Events': 0,
    'Events/Second': lambda s: (
        (s['Important Events'] / (time.time() - s['Start Time']))),
for event in events:
    # Collect stats
    if mystats.get('Enabled', False):
        mystats['Important Events'] += 1

To report statistics:

root.cpstats = cpstats.StatsPage()

To format statistics reports:

See 'Reporting', above.
class cherrypy.lib.cpstats.ByteCountWrapper(rfile)[source]

Bases: object

Wraps a file-like object, counting the number of bytes read.

class cherrypy.lib.cpstats.StatsPage[source]

Bases: object

formatting = {'CherryPy Applications': {'Bytes Read/Request': '%.3f', 'Bytes Read/Second': '%.3f', 'Bytes Written/Request': '%.3f', 'Bytes Written/Second': '%.3f', 'Current Time': <function iso_format>, 'Enabled': <function pause_resume.<locals>._pause_resume>, 'Requests': {'Bytes Read': '%s', 'Bytes Written': '%s', 'End Time': None, 'Processing Time': '%.3f', 'Start Time': None}, 'Requests/Second': '%.3f', 'Slow Queries': {'End Time': None, 'Processing Time': '%.3f', 'Start Time': <function iso_format>}, 'Start Time': <function iso_format>, 'Total Time': '%.3f', 'URI Set Tracking': {'Avg': '%.3f', 'Max': '%.3f', 'Min': '%.3f', 'Sum': '%.3f'}, 'Uptime': '%.3f'}, 'CherryPy WSGIServer': {'Connections/second': '%.3f', 'Enabled': <function pause_resume.<locals>._pause_resume>, 'Start time': <function iso_format>}}
get_dict_collection(v, formatting)[source]

Return ([headers], [rows]) for the given collection.

get_list_collection(v, formatting)[source]

Return ([headers], [subrows]) for the given collection.


Yield (title, scalars, collections) for each namespace.

class cherrypy.lib.cpstats.StatsTool[source]

Bases: cherrypy._cptools.Tool

Record various information about the current request.


Record the beginning of a request.

record_stop(uriset=None, slow_queries=1.0, slow_queries_count=100, debug=False, **kwargs)[source]

Record the end of a request.


Return an extrapolated copy of the given scope.


cherrypy.lib.cptools module

Functions for builtin CherryPy tools.

class cherrypy.lib.cptools.MonitoredHeaderMap[source]

Bases: cherrypy.lib.httputil.HeaderMap

class cherrypy.lib.cptools.SessionAuth[source]

Bases: object

Assert that the user is logged in.


Provide a temporary user name for anonymous users.

check_username_and_password(username, password)[source]
debug = False

Assert username. Raise redirect, or return True if request handled.

do_login(username, password, from_page='..', **kwargs)[source]

Login. May raise redirect, or return True if request handled.

do_logout(from_page='..', **kwargs)[source]

Logout. May raise redirect, or return True if request handled.

login_screen(from_page='..', username='', error_msg='', **kwargs)[source]
session_key = 'username'
cherrypy.lib.cptools.accept(media=None, debug=False)[source]

Return the client’s preferred media-type (from the given Content-Types).

If ‘media’ is None (the default), no test will be performed.

If ‘media’ is provided, it should be the Content-Type value (as a string) or values (as a list or tuple of strings) which the current resource can emit. The client’s acceptable media ranges (as declared in the Accept request header) will be matched in order to these Content-Type values; the first such string is returned. That is, the return value will always be one of the strings provided in the ‘media’ arg (or None if ‘media’ is None).

If no match is found, then HTTPError 406 (Not Acceptable) is raised. Note that most web browsers send / as a (low-quality) acceptable media range, which should match any Content-Type. In addition, “…if no Accept header field is present, then it is assumed that the client accepts all media types.”

Matching types are checked in order of client preference first, and then in the order of the given ‘media’ values.

Note that this function does not honor accept-params (other than “q”).

cherrypy.lib.cptools.allow(methods=None, debug=False)[source]

Raise 405 if request.method not in methods (default [‘GET’, ‘HEAD’]).

The given methods are case-insensitive, and may be in any order. If only one method is allowed, you may supply a single string; if more than one, supply a list of strings.

Regardless of whether the current method is allowed or not, this also emits an ‘Allow’ response header, containing the given methods.

cherrypy.lib.cptools.autovary(ignore=None, debug=False)[source]

Auto-populate the Vary response header based on request.header access.

cherrypy.lib.cptools.convert_params(exception=<class 'ValueError'>, error=400)[source]

Convert request params based on function annotations, with error handling.

Exception class to catch.
The HTTP error code to return to the client on failure.

Wrap response.body in a generator that recursively iterates over body.

This allows cherrypy.response.body to consist of ‘nested generators’; that is, a set of generators that yield generators.

cherrypy.lib.cptools.ignore_headers(headers=('Range', ), debug=False)[source]

Delete request headers whose field names are included in ‘headers’.

This is a useful tool for working behind certain HTTP servers; for example, Apache duplicates the work that CP does for ‘Range’ headers, and will doubly-truncate the response.


Write request.hooks to the cherrypy error log.


Write request headers to the cherrypy error log.

cherrypy.lib.cptools.log_traceback(severity=40, debug=False)[source]

Write the last error’s traceback to the cherrypy error log.

cherrypy.lib.cptools.proxy(base=None, local='X-Forwarded-Host', remote='X-Forwarded-For', scheme='X-Forwarded-Proto', debug=False)[source]

Change the base URL (scheme://host[:port][/path]).

For running a CP server behind Apache, lighttpd, or other HTTP server.

For Apache and lighttpd, you should leave the ‘local’ argument at the default value of ‘X-Forwarded-Host’. For Squid, you probably want to set tools.proxy.local = ‘Origin’.

If you want the new request.base to include path info (not just the host), you must explicitly set base to the full base path, and ALSO set ‘local’ to ‘’, so that the X-Forwarded-Host request header (which never includes path info) does not override it. Regardless, the value for ‘base’ MUST NOT end in a slash.

cherrypy.request.remote.ip (the IP address of the client) will be rewritten if the header specified by the ‘remote’ arg is valid. By default, ‘remote’ is set to ‘X-Forwarded-For’. If you do not want to rewrite remote.ip, set the ‘remote’ arg to an empty string.

cherrypy.lib.cptools.redirect(url='', internal=True, debug=False)[source]

Raise InternalRedirect or HTTPRedirect to the given url.

cherrypy.lib.cptools.referer(pattern, accept=True, accept_missing=False, error=403, message='Forbidden Referer header.', debug=False)[source]

Raise HTTPError if Referer header does/does not match the given pattern.

A regular expression pattern to test against the Referer.
If True, the Referer must match the pattern; if False, the Referer must NOT match the pattern.
If True, permit requests with no Referer header.
The HTTP error code to return to the client on failure.
A string to include in the response body on failure.
cherrypy.lib.cptools.response_headers(headers=None, debug=False)[source]

Set headers on the response.

cherrypy.lib.cptools.trailing_slash(missing=True, extra=False, status=None, debug=False)[source]

Redirect if path_info has (missing|extra) trailing slash.

cherrypy.lib.cptools.validate_etags(autotags=False, debug=False)[source]

Validate the current ETag against If-Match, If-None-Match headers.

If autotags is True, an ETag response-header value will be provided from an MD5 hash of the response body (unless some other code has already provided an ETag header). If False (the default), the ETag will not be automatic.

WARNING: the autotags feature is not designed for URL’s which allow methods other than GET. For example, if a POST to the same URL returns no content, the automatic ETag will be incorrect, breaking a fundamental use for entity tags in a possibly destructive fashion. Likewise, if you raise 304 Not Modified, the response body will be empty, the ETag hash will be incorrect, and your application will break. See RFC 2616 Section 14.24.


Validate the current Last-Modified against If-Modified-Since headers.

If no code has set the Last-Modified response header, then no validation will be performed.

cherrypy.lib.encoding module

class cherrypy.lib.encoding.ResponseEncoder(**kwargs)[source]

Bases: object

add_charset = True
debug = False
default_encoding = 'utf-8'

Encode a streaming response body.

Use a generator wrapper, and just pray it works as the stream is being written out.


Encode a buffered response body.

encoding = None
errors = 'strict'
failmsg = 'Response body could not be encoded with %r.'
text_only = True
class cherrypy.lib.encoding.UTF8StreamEncoder(iterator)[source]

Bases: object

cherrypy.lib.encoding.compress(body, compress_level)[source]

Compress ‘body’ at the given compress_level.

cherrypy.lib.encoding.decode(encoding=None, default_encoding='utf-8')[source]

Replace or extend the list of charsets used to decode a request entity.

Either argument may be a single string or a list of strings.

If not None, restricts the set of charsets attempted while decoding a request entity to the given set (even if a different charset is given in the Content-Type request header).
Only in effect if the ‘encoding’ argument is not given. If given, the set of charsets attempted while decoding a request entity is extended with the given value(s).
cherrypy.lib.encoding.gzip(compress_level=5, mime_types=['text/html', 'text/plain'], debug=False)[source]

Try to gzip the response body if Content-Type in mime_types.

cherrypy.response.headers[‘Content-Type’] must be set to one of the values in the mime_types arg before calling this function.

The provided list of mime-types must be of one of the following form:
  • type/subtype
  • type/*
  • type/*+subtype
No compression is performed if any of the following hold:
  • The client sends no Accept-Encoding request header
  • No ‘gzip’ or ‘x-gzip’ is present in the Accept-Encoding header
  • No ‘gzip’ or ‘x-gzip’ with a qvalue > 0 is present
  • The ‘identity’ value is given with a qvalue > 0.

Ensure response body is iterable and resolves to False when empty.

cherrypy.lib.gctools module

class cherrypy.lib.gctools.GCRoot[source]

Bases: object

A CherryPy page handler for testing reference leaks.

classes = [(<class 'cherrypy._cprequest.Request'>, 2, 2, 'Should be 1 in this request thread and 1 in the main thread.'), (<class 'cherrypy._cprequest.Response'>, 2, 2, 'Should be 1 in this request thread and 1 in the main thread.'), (<class 'cherrypy._cpwsgi.AppResponse'>, 1, 1, 'Should be 1 in this request thread only.')]
class cherrypy.lib.gctools.ReferrerTree(ignore=None, maxdepth=2, maxparents=10)[source]

Bases: object

An object which gathers all referrers of an object to a given depth.

ascend(obj, depth=1)[source]

Return a nested list containing referrers of the given object.


Return a list of string reprs from a nested list of referrers.


Return s, restricted to a sane length.

peek_length = 40
class cherrypy.lib.gctools.RequestCounter(bus)[source]

Bases: cherrypy.process.plugins.SimplePlugin


cherrypy.lib.httputil module

HTTP library functions.

This module contains functions for building an HTTP application framework: any one, not just one whose name starts with “Ch”. ;) If you reference any modules from some popular framework inside this module, FuManChu will personally hang you up by your thumbs and submit you to a public caning.

class cherrypy.lib.httputil.AcceptElement(value, params=None)[source]

Bases: cherrypy.lib.httputil.HeaderElement

An element (with parameters) from an Accept* header’s element list.

AcceptElement objects are comparable; the more-preferred object will be “less than” the less-preferred object. They are also therefore sortable; if you sort a list of AcceptElement objects, they will be listed in priority order; the most preferred value will be first. Yes, it should have been the other way around, but it’s too late to fix now.

classmethod from_str(elementstr)[source]

Construct an instance from a string of the form ‘token;key=val’.


The qvalue, or priority, of this value.

class cherrypy.lib.httputil.CaseInsensitiveDict(*args, **kargs)[source]

Bases: jaraco.collections.KeyTransformingDict

A case-insensitive dict subclass.

Each key is changed on entry to title case.

static transform_key(key)[source]
cherrypy.lib.httputil.HTTPDate(timeval=None, localtime=False, *, usegmt=True)

Returns a date string as specified by RFC 2822, e.g.:

Fri, 09 Nov 2001 01:08:47 -0000

Optional timeval if given is a floating point time value as accepted by gmtime() and localtime(), otherwise the current time is used.

Optional localtime is a flag that when True, interprets timeval, and returns a date relative to the local timezone instead of UTC, properly taking daylight savings time into account.

Optional argument usegmt means that the timezone is written out as an ascii string, not numeric one (so “GMT” instead of “+0000”). This is needed for HTTP, and is only used when localtime==False.

class cherrypy.lib.httputil.HeaderElement(value, params=None)[source]

Bases: object

An element (with parameters) from an HTTP header’s element list.

classmethod from_str(elementstr)[source]

Construct an instance from a string of the form ‘token;key=val’.

static parse(elementstr)[source]

Transform ‘token;key=val’ to (‘token’, {‘key’: ‘val’}).

class cherrypy.lib.httputil.HeaderMap(*args, **kargs)[source]

Bases: cherrypy.lib.httputil.CaseInsensitiveDict

A dict subclass for HTTP request and response headers.

Each key is changed on entry to str(key).title(). This allows headers to be case-insensitive and avoid duplicates.

Values are header values (decoded according to RFC 2047 if necessary).


Return a sorted list of HeaderElements for the given header.

classmethod encode(v)[source]

Return the given header name or value, encoded for HTTP output.

classmethod encode_header_item(item)[source]
classmethod encode_header_items(header_items)[source]

Prepare the sequence of name, value tuples into a form suitable for transmitting on the wire for HTTP.

encodings = ['ISO-8859-1']

Transform self into a list of (name, value) tuples.

protocol = (1, 1)
use_rfc_2047 = True

Return a sorted list of HeaderElement.value for the given header.

class cherrypy.lib.httputil.Host(ip, port, name=None)[source]

Bases: object

An internet address.

Should be the client’s host name. If not available (because no DNS lookup is performed), the IP address should be used instead.
ip = ''
name = 'unknown.tld'
port = 80

Decode RFC 2047 TEXT

>>> decode_TEXT("=?utf-8?q?f=C3=BCr?=") == b'f\xfcr'.decode('latin-1')

Decode the text but only if ‘=?’ appears in it.

cherrypy.lib.httputil.get_ranges(headervalue, content_length)[source]

Return a list of (start, stop) indices from a Range header, or None.

Each (start, stop) tuple will be composed of two ints, which are suitable for use in a slicing operation. That is, the header “Range: bytes=3-6”, if applied against a Python string, is requesting resource[3:7]. This function will return the list [(3, 7)].

If this function returns an empty list, you should return HTTP 416.

cherrypy.lib.httputil.header_elements(fieldname, fieldvalue)[source]

Return a sorted HeaderElement list from a comma-separated header string.

cherrypy.lib.httputil.parse_query_string(query_string, keep_blank_values=True, encoding='utf-8')[source]

Build a params dictionary from a query_string.

Duplicate key/value pairs in the provided query_string will be returned as {‘key’: [val1, val2, …]}. Single key/values will be returned as strings: {‘key’: ‘value’}.


Return a protocol tuple from the given ‘HTTP/x.y’ string.


Return the given path *atoms, joined into a single URL.

This will correctly join a SCRIPT_NAME and PATH_INFO into the original URL, even if either atom is blank.


Return the given path *atoms, joined into a single URL.

This will correctly join a SCRIPT_NAME and PATH_INFO into the original URL, even if either atom is blank.


Return legal HTTP status Code, Reason-phrase and Message.

The status arg must be an int, a str that begins with an int or the constant from http.client stdlib module.

If status has no reason-phrase is supplied, a default reason- phrase will be provided.

>>> import http.client
>>> from http.server import BaseHTTPRequestHandler
>>> valid_status(http.client.ACCEPTED) == (
...     int(http.client.ACCEPTED),
... ) + BaseHTTPRequestHandler.responses[http.client.ACCEPTED]

cherrypy.lib.jsontools module

cherrypy.lib.jsontools.json_handler(*args, **kwargs)[source]
cherrypy.lib.jsontools.json_in(content_type=['application/json', 'text/javascript'], force=True, debug=False, processor=<function json_processor>)[source]

Add a processor to parse JSON request entities: The default processor places the parsed data into request.json.

Incoming request entities which match the given content_type(s) will be deserialized from JSON to the Python equivalent, and the result stored at cherrypy.request.json. The ‘content_type’ argument may be a Content-Type string or a list of allowable Content-Type strings.

If the ‘force’ argument is True (the default), then entities of other content types will not be allowed; “415 Unsupported Media Type” is raised instead.

Supply your own processor to use a custom decoder, or to handle the parsed data differently. The processor can be configured via tools.json_in.processor or via the decorator method.

Note that the deserializer requires the client send a Content-Length request header, or it will raise “411 Length Required”. If for any other reason the request entity cannot be deserialized from JSON, it will raise “400 Bad Request: Invalid JSON document”.

cherrypy.lib.jsontools.json_out(content_type='application/json', debug=False, handler=<function json_handler>)[source]

Wrap request.handler to serialize its output to JSON. Sets Content-Type.

If the given content_type is None, the Content-Type response header is not set.

Provide your own handler to use a custom encoder. For example cherrypy.config[‘tools.json_out.handler’] = <function>, or @json_out(handler=function).


Read application/json data into request.json.

cherrypy.lib.locking module

class cherrypy.lib.locking.LockChecker(session_id, timeout)[source]

Bases: object

Keep track of the time and detect if a timeout has expired

exception cherrypy.lib.locking.LockTimeout[source]

Bases: Exception

An exception when a lock could not be acquired before a timeout period

class cherrypy.lib.locking.NeverExpires[source]

Bases: object

class cherrypy.lib.locking.Timer(expiration)[source]

Bases: object

A simple timer that will indicate when an expiration time has passed.

classmethod after(elapsed)[source]

Return a timer that will expire after elapsed passes.


cherrypy.lib.profiler module

Profiler tools for CherryPy.

CherryPy users

You can profile any of your pages as follows:

from cherrypy.lib import profiler

class Root:
    p = profiler.Profiler("/path/to/profile/dir")

    def index(self):

    def _index(self):
        return "Hello, world!"


You can also turn on profiling for all requests using the make_app function as WSGI middleware.

CherryPy developers

This module can be used whenever you make changes to CherryPy, to get a quick sanity-check on overall CP performance. Use the --profile flag when running the test suite. Then, use the serve() function to browse the results in a web browser. If you run this module from the command line, it will call serve() for you.

class cherrypy.lib.profiler.ProfileAggregator(path=None)[source]

Bases: cherrypy.lib.profiler.Profiler

run(func, *args, **params)[source]

Dump profile data into self.path.

class cherrypy.lib.profiler.Profiler(path=None)[source]

Bases: object

run(func, *args, **params)[source]

Dump profile data into self.path.

Return type:list of available profiles.
stats(filename, sortby='cumulative')[source]
Rtype stats(index):
 output of print_stats() for the given profile.
class cherrypy.lib.profiler.make_app(nextapp, path=None, aggregate=False)[source]

Bases: object


Make profiler output more readable by adding __init__ modules’ parents

cherrypy.lib.profiler.serve(path=None, port=8080)[source]

cherrypy.lib.reprconf module

Generic configuration system using unrepr.

Configuration data may be supplied as a Python dictionary, as a filename, or as an open file object. When you supply a filename or file, Python’s builtin ConfigParser is used (with some extensions).


Configuration keys are separated into namespaces by the first “.” in the key.

The only key that cannot exist in a namespace is the “environment” entry. This special entry ‘imports’ other config entries from a template stored in the Config.environments dict.

You can define your own namespaces to be called when new config is merged by adding a named handler to Config.namespaces. The name can be any string, and the handler must be either a callable or a context manager.

class cherrypy.lib.reprconf.Config(file=None, **kwargs)[source]

Bases: dict

A dict-like set of configuration data, with defaults and namespaces.

May take a file, filename, or dict.

defaults = {}
environments = {}
namespaces = {'checker': <function <lambda>>, 'engine': <function _engine_namespace_handler>, 'log': <function <lambda>>, 'server': <function _server_namespace_handler>, 'tree': <function _tree_namespace_handler>}

Reset self to default values.


Update self from a dict, file, or filename.

class cherrypy.lib.reprconf.NamespaceSet[source]

Bases: dict

A dict of config namespace names and handlers.

Each config entry should begin with a namespace name; the corresponding namespace handler will be called once for each config entry in that namespace, and will be passed two arguments: the config key (with the namespace removed) and the config value.

Namespace handlers may be any Python callable; they may also be context managers, in which case their __enter__ method should return a callable to be used as the handler. See (the Toolbox class) for an example.

class cherrypy.lib.reprconf.Parser(defaults=None, dict_type=<class 'collections.OrderedDict'>, allow_no_value=False, *, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section='DEFAULT', interpolation=<object object>, converters=<object object>)[source]

Bases: configparser.ConfigParser

Sub-class of ConfigParser that keeps the case of options and that raises an exception if the file cannot be read.

as_dict(raw=False, vars=None)[source]

Convert an INI file to a dictionary

classmethod load(input)[source]

Resolve ‘input’ to dict from a dict, file, or filename.


Read and parse a filename or an iterable of filenames.

Files that cannot be opened are silently ignored; this is designed so that you can specify an iterable of potential configuration file locations (e.g. current directory, user’s home directory, systemwide directory), and all existing configuration files in the iterable will be read. A single filename may also be given.

Return list of successfully read files.


Load a module and retrieve an attribute of that module.


Load a module and retrieve a reference to that module.


Return a Python object compiled from a string.

cherrypy.lib.sessions module

Session implementation for CherryPy.

You need to edit your config file to use sessions. Here’s an example:

tools.sessions.on = True
tools.sessions.storage_class = cherrypy.lib.sessions.FileSession
tools.sessions.storage_path = "/home/site/sessions"
tools.sessions.timeout = 60

This sets the session to be stored in files in the directory /home/site/sessions, and the session timeout to 60 minutes. If you omit storage_class, the sessions will be saved in RAM. tools.sessions.on is the only required line for working sessions, the rest are optional.

By default, the session ID is passed in a cookie, so the client’s browser must have cookies enabled for your site.

To set data for the current session, use cherrypy.session['fieldname'] = 'fieldvalue'; to get data use cherrypy.session.get('fieldname').

Locking sessions

By default, the 'locking' mode of sessions is 'implicit', which means the session is locked early and unlocked late. Be mindful of this default mode for any requests that take a long time to process (streaming responses, expensive calculations, database lookups, API calls, etc), as other concurrent requests that also utilize sessions will hang until the session is unlocked.

If you want to control when the session data is locked and unlocked, set tools.sessions.locking = 'explicit'. Then call cherrypy.session.acquire_lock() and cherrypy.session.release_lock(). Regardless of which mode you use, the session is guaranteed to be unlocked when the request is complete.

Expiring Sessions

You can force a session to expire with cherrypy.lib.sessions.expire(). Simply call that function at the point you want the session to expire, and it will cause the session cookie to expire client-side.

Session Fixation Protection

If CherryPy receives, via a request cookie, a session id that it does not recognize, it will reject that id and create a new one to return in the response cookie. This helps prevent session fixation attacks. However, CherryPy “recognizes” a session id by looking up the saved session data for that id. Therefore, if you never save any session data, you will get a new session id for every request.

A side effect of CherryPy overwriting unrecognised session ids is that if you have multiple, separate CherryPy applications running on a single domain (e.g. on different ports), each app will overwrite the other’s session id because by default they use the same cookie name ("session_id") but do not recognise each others sessions. It is therefore a good idea to use a different name for each, for example:

... = "my_app_session_id"

Sharing Sessions

If you run multiple instances of CherryPy (for example via mod_python behind Apache prefork), you most likely cannot use the RAM session backend, since each instance of CherryPy will have its own memory space. Use a different backend instead, and verify that all instances are pointing at the same file or db location. Alternately, you might try a load balancer which makes sessions “sticky”. Google is your friend, there.

Expiration Dates

The response cookie will possess an expiration date to inform the client at which point to stop sending the cookie back in requests. If the server time and client time differ, expect sessions to be unreliable. Make sure the system time of your server is accurate.

CherryPy defaults to a 60-minute session timeout, which also applies to the cookie which is sent to the client. Unfortunately, some versions of Safari (“4 public beta” on Windows XP at least) appear to have a bug in their parsing of the GMT expiration date–they appear to interpret the date as one hour in the past. Sixty minutes minus one hour is pretty close to zero, so you may experience this bug as a new session id for every request, unless the requests are less than one second apart. To fix, try increasing the session.timeout.

On the other extreme, some users report Firefox sending cookies after their expiration date, although this was on a system with an inaccurate system time. Maybe FF doesn’t trust system time.

class cherrypy.lib.sessions.FileSession(id=None, **kwargs)[source]

Bases: cherrypy.lib.sessions.Session

Implementation of the File backend for sessions

The folder where session data will be saved. Each session will be saved as pickle.dump(data, expiration_time) in its own file; the filename will be self.SESSION_PREFIX +
A timedelta or numeric seconds indicating how long to block acquiring a lock. If None (default), acquiring a lock will block indefinitely.
LOCK_SUFFIX = '.lock'
SESSION_PREFIX = 'session-'

Acquire an exclusive lock on the currently-loaded session data.


Clean up expired sessions.

pickle_protocol = 4

Release the lock on the currently-loaded session data.

classmethod setup(**kwargs)[source]

Set up the storage system for file-based sessions.

This should only be called once per process; this will be done automatically when using sessions.init (as the built-in Tool does).

class cherrypy.lib.sessions.MemcachedSession(id=None, **kwargs)[source]

Bases: cherrypy.lib.sessions.Session


Acquire an exclusive lock on the currently-loaded session data.

locks = {}
mc_lock = <unlocked _thread.RLock object owner=0 count=0>

Release the lock on the currently-loaded session data.

servers = ['localhost:11211']
classmethod setup(**kwargs)[source]

Set up the storage system for memcached-based sessions.

This should only be called once per process; this will be done automatically when using sessions.init (as the built-in Tool does).

class cherrypy.lib.sessions.RamSession(id=None, **kwargs)[source]

Bases: cherrypy.lib.sessions.Session


Acquire an exclusive lock on the currently-loaded session data.

cache = {}

Clean up expired sessions.

locks = {}

Release the lock on the currently-loaded session data.

class cherrypy.lib.sessions.Session(id=None, **kwargs)[source]

Bases: object

A CherryPy dict-like Session object (one per request).

clean_freq = 5

The poll rate for expired session cleanup in minutes.

clean_thread = None

Class-level Monitor which calls self.clean_up.


Clean up expired sessions.

clear() → None. Remove all items from D.[source]
debug = False

If True, log debug information.


Delete stored session data.


Return a new session id.

get(k[, d]) → D[k] if k in D, else d. d defaults to None.[source]

Return the current session id.

id_observers = None

A list of callbacks to which to pass new id’s.

items() → list of D's (key, value) pairs, as 2-tuples.[source]
keys() → list of D's keys.[source]

Copy stored session data into this session instance.

loaded = False

If True, data has been retrieved from storage. This should happen automatically on the first attempt to access session data.

locked = False

If True, this session instance has exclusive read/write access to session data.

missing = False

True if the session requested by the client did not exist.


Generate the session specific concept of ‘now’.

Other session providers can override this to use alternative, possibly timezone aware, versions of ‘now’.

originalid = None

The session id passed by the client. May be missing or unsafe.

pop(key, default=False)[source]

Remove the specified key and return the corresponding value. If key is not found, default is returned if given, otherwise KeyError is raised.


Replace the current session (with a new id).

regenerated = False

True if the application called session.regenerate(). This is not set by internal calls to regenerate the session id.


Save session data.

setdefault(k[, d]) → D.get(k,d), also set D[k]=d if k not in D.[source]
timeout = 60

Number of minutes after which to delete session data.

update(E) → None. Update D from E: for k in E: D[k] = E[k].[source]
values() → list of D's values.[source]

Close the session object for this request.


Expire the current session cookie.

cherrypy.lib.sessions.init(storage_type=None, path=None, path_header=None, name='session_id', timeout=60, domain=None, secure=False, clean_freq=5, persistent=True, httponly=False, debug=False, **kwargs)[source]

Initialize session object (using cookies).

The Session subclass to use. Defaults to RamSession.
(deprecated) One of ‘ram’, ‘file’, memcached’. This will be used to look up the corresponding class in cherrypy.lib.sessions globals. For example, ‘file’ will use the FileSession class.
The ‘path’ value to stick in the response cookie metadata.
If ‘path’ is None (the default), then the response cookie ‘path’ will be pulled from request.headers[path_header].
The name of the cookie.
The expiration timeout (in minutes) for the stored session data. If ‘persistent’ is True (the default), this is also the timeout for the cookie.
The cookie domain.
If False (the default) the cookie ‘secure’ value will not be set. If True, the cookie ‘secure’ value will be set (to 1).
clean_freq (minutes)
The poll rate for expired session cleanup.
If True (the default), the ‘timeout’ argument will be used to expire the cookie. If False, the cookie will not have an expiry, and the cookie will be a “session cookie” which expires when the browser is closed.
If False (the default) the cookie ‘httponly’ value will not be set. If True, the cookie ‘httponly’ value will be set (to 1).

Any additional kwargs will be bound to the new Session instance, and may be specific to the storage type. See the subclass of Session you’re using for more information.[source]

Save any changed session data.

Set a response cookie for the client.

the ‘path’ value to stick in the response cookie metadata.
if ‘path’ is None (the default), then the response cookie ‘path’ will be pulled from request.headers[path_header].
the name of the cookie.
the expiration timeout for the cookie. If 0 or other boolean False, no ‘expires’ param will be set, and the cookie will be a “session cookie” which expires when the browser is closed.
the cookie domain.
if False (the default) the cookie ‘secure’ value will not be set. If True, the cookie ‘secure’ value will be set (to 1).
If False (the default) the cookie ‘httponly’ value will not be set. If True, the cookie ‘httponly’ value will be set (to 1).

cherrypy.lib.static module

Module with helpers for serving static files.

cherrypy.lib.static.serve_download(path, name=None)[source]

Serve ‘path’ as an application/x-download attachment.

cherrypy.lib.static.serve_file(path, content_type=None, disposition=None, name=None, debug=False)[source]

Set status, headers, and body in order to serve the given path.

The Content-Type header will be set to the content_type arg, if provided. If not provided, the Content-Type will be guessed by the file extension of the ‘path’ argument.

If disposition is not None, the Content-Disposition header will be set to “<disposition>; filename=<name>”. If name is None, it will be set to the basename of path. If disposition is None, no Content-Disposition header will be written.

cherrypy.lib.static.serve_fileobj(fileobj, content_type=None, disposition=None, name=None, debug=False)[source]

Set status, headers, and body in order to serve the given file object.

The Content-Type header will be set to the content_type arg, if provided.

If disposition is not None, the Content-Disposition header will be set to “<disposition>; filename=<name>”. If name is None, ‘filename’ will not be set. If disposition is None, no Content-Disposition header will be written.

CAUTION: If the request contains a ‘Range’ header, one or more seek()s will be performed on the file object. This may cause undesired behavior if the file object is not seekable. It could also produce undesired results if the caller set the read position of the file object prior to calling serve_fileobj(), expecting that the data would be served starting from that position.

cherrypy.lib.static.staticdir(section, dir, root='', match='', content_types=None, index='', debug=False)[source]

Serve a static resource from the given (root +) dir.

If given, request.path_info will be searched for the given regular expression before attempting to serve static content.
If given, it should be a Python dictionary of {file-extension: content-type} pairs, where ‘file-extension’ is a string (e.g. “gif”) and ‘content-type’ is the value to write out in the Content-Type response header (e.g. “image/gif”).
If provided, it should be the (relative) name of a file to serve for directory requests. For example, if the dir argument is ‘/home/me’, the Request-URI is ‘myapp’, and the index arg is ‘index.html’, the file ‘/home/me/myapp/index.html’ will be sought.
cherrypy.lib.static.staticfile(filename, root=None, match='', content_types=None, debug=False)[source]

Serve a static resource from the given (root +) filename.

If given, request.path_info will be searched for the given regular expression before attempting to serve static content.
If given, it should be a Python dictionary of {file-extension: content-type} pairs, where ‘file-extension’ is a string (e.g. “gif”) and ‘content-type’ is the value to write out in the Content-Type response header (e.g. “image/gif”).

cherrypy.lib.xmlrpcutil module

XML-RPC tool helpers.

cherrypy.lib.xmlrpcutil.on_error(*args, **kwargs)[source]

Construct HTTP response body for an error response.


Return ‘path’, doctored for RPC.


Return (params, method) from request body.

cherrypy.lib.xmlrpcutil.respond(body, encoding='utf-8', allow_none=0)[source]

Construct HTTP response body.

Module contents

CherryPy Library.

class cherrypy.lib.file_generator(input, chunkSize=65536)[source]

Bases: object

Yield the given input (a file object) in chunks (default 64k).



Return next chunk of file.

cherrypy.lib.file_generator_limited(fileobj, count, chunk_size=65536)[source]

Yield the given file object in chunks.

Stopps after count bytes has been emitted. Default chunk size is 64kB. (Core)


Detect if the given object is both closable and iterator.


Detect if the object provided implements the iterator protocol.

(i.e. like a generator).

This will return False for objects which are iterable, but not iterators themselves.

cherrypy.lib.set_vary_header(response, header_name)[source]

Add a Vary header to a response.