Overview of CherryPy - A Web Application Server (Part2)

Exclusive offer: get 50% off this eBook here
CherryPy Essentials: Rapid Python Web Application Development

CherryPy Essentials: Rapid Python Web Application Development — Save 50%

Design, develop, test, and deploy your Python web applications easily

$23.99    $12.00
by Sylvain Hellegouarch | September 2009 | Content Management

Read Part One of Overview of CherryPy - A Web Application Server here.

Library

CherryPy comes with a set of modules covering common tasks when building a web application such as session management, static resource service, encoding handling, or basic caching.

The Autoreload Feature

CherryPy is a long-running Python process, meaning that if we modify a Python module of the application, it will not be propagated in the existing process. Since stopping and restarting the server manually can be a tedious task, the CherryPy team has included an autoreload module that restarts the process as soon as it detects a modification to a Python module imported by the application. This feature is handled via configuration settings.

If you need the autoreload module to be enabled while in production you will set it up as below. Note the engine.autoreload_frequency option that sets the number of seconds the autoreloader engine has to wait before checking for new changes. It defaults to one second if not present.

[global]
server.environment = "production"
engine.autoreload_on = True
engine.autoreload_frequency = 5

Autoreload is not properly a module but we mention it here as it is a common feature offered by the library.

The Caching Module

Caching is an important side of any web application as it reduces the load and stress of the different servers in action—HTTP, application, and database servers. In spite of being highly correlated to the application itself, generic caching tools such as the ones provided by this module can help in achieving decent improvements in your application's performance.

The CherryPy caching module works at the HTTP server level in the sense that it will cache the generated output to be sent to the user agent and will retrieve a cached resource based on a predefined key, which defaults to the complete URL leading to that resource. The cache is held in the server memory and is therefore lost when stopping it. Note that you can also pass your own caching class to handle the underlying process differently while keeping the same high-level interface.

The Coverage Module

When building an application it is often beneficial to understand the path taken by the application based on the input it processes. This helps to determine potential bottlenecks and also see if the application runs as expected. The coverage module provided by CherryPy does this and provides a friendly browseable output showing the lines of code executed during the run. The module is one of the few that rely on a third-party package to run.

The Encoding/Decoding Module

Publishing over the Web means dealing with the multitude of existing character encoding. To one extreme you may only publish your own content using US-ASCII without asking for readers' feedback and to the other extreme you may release an application such as bulletin board that will handle any kind of charset. To help in this task CherryPy provides an encoding/decoding module that filters the input and output content based on server or user-agent settings.

The HTTP Module

This module offers a set of classes and functions to handle HTTP headers and entities.

For example, to parse the HTTP request line and query string:

s = 'GET /note/1 HTTP/1.1' # no query string
r = http.parse_request_line(s) # r is now ('GET', '/note/1', '',
'HTTP/1.1')
s = 'GET /note?id=1 HTTP/1.1' # query string is id=1
r = http.parse_request_line(s) # r is now ('GET', '/note', 'id=1',
'HTTP/1.1')
http.parseQueryString(r[2]) # returns {'id': '1'}
Provide a clean interface to HTTP headers:
For example, say you have the following Accept header value:
accept_value = "text/xml,application/xml,application/xhtml+xml,text/
html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
values = http.header_elements('accept', accept_value)
print values[0].value, values[0].qvalue # will print text/html 1.0

The Httpauth Module

This module provides an implementation of the basic and digest authentication algorithm as defined in RFC 2617.

The Profiler Module

This module features an interface to conduct a performance check of the application.

The Sessions Module

The Web is built on top of a stateless protocol, HTTP, which means that requests are independent of each other. In spite of that, a user can navigate an e-commerce website with the impression that the application more or less follows the way he or she would call the store to pass an order. The session mechanism was therefore brought to the Web to allow servers to keep track of users' information.

CherryPy's session module offers a straightforward interface to the application developer to store, retrieve, amend, and delete chunks of data from a session object. CherryPy comes natively with three different back-end storages for session objects:

Back-end type

Advantages

Drawbacks

RAM

Efficient

Accepts any type of objects

No configuration needed

Information lost when server is shutdown

Memory consumption can grow fast

File system

Persistence of the information

Simple setup

File system locking can be inefficient

Only serializable (via the pickle module) objects can be stored

Relational database (PostgreSQL built-in support)

Persistence of the information

Robust

Scalable

Can be load balanced

Only serializable objects can be stored

Setup less straightforward

CherryPy Essentials: Rapid Python Web Application Development Design, develop, test, and deploy your Python web applications easily
Published: March 2007
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

Tools

In the previous sections we have introduced the built-in modules. CherryPy provides a unified interface, referred as the tool interface, to call those modules or build and call your own modules.

Tools can be set up from three different contexts:

  • The configuration file or dictionary
    conf = {'/': {
    'tools.encode.on': True,
    'tools.encode.encoding': 'ISO-8859-1'
    }
    }
    cherrypy.tree.mount(Root(), '/', config=conf)
  • Attached to a particular page handler

    It is not uncommon to decide to add extra processing to an object path matching a URI. In that case you might want to use a Python decorator around the page handler.

    @cherrypy.expose
    @cherrypy.tools.encode(encoding='ISO 8859-1')
    def index(self)
    return "Et voilà"
  • Making a library call with a higher-level interface

    Tools can be applied as regular Python callable objects.

    def index(self):
    cherrypy.tools.accept.callable(media='text/html')

The previous line shows how to call the accept tool that looks up the provided media type within the requested Accept HTTP header.

Thanks to that unified interface it is possible to modify the underlying code of the tool without having to modify the application level itself.

A tool is an interface to extend CherryPy by plugging third-party components into the CherryPy engine.

Error and Exception Handling

CherryPy tries hard to help the developer see a web application as close as a rich application. This means that from your page handler you may raise a Python error or exception as in any other Python application. CherryPy will catch those and transform them into HTTP messages depending on the type of errors.

Note that when an exception is raised and not caught by any other part of the application, CherryPy will return the corresponding HTTP 500 error code.

For example, the following example will show the default behavior of CherryPy.

import cherrypy
class Root:
@cherrypy.expose
def index(self):
raise NotImplementedError, "This is an error..."
if __name__ == '__main__':
cherrypy.quickstart(Root(), '/')

CherryPy Essentials: Rapid Python Web Application Development

As you can see CherryPy displays the complete traceback of the Python error. Although this is useful when developing the application, it might not be relevant in production mode. In that case, CherryPy returns simply a default message.

CherryPy Essentials: Rapid Python Web Application Development

In development mode you can hide the tracebacks on error by using the request.show_tracebacks key in the global section of the configuration settings.

CherryPy returns an HTTP error code 500 when it catches an error that is not handled otherwise by the application developer. The HTTP specification defines two sets of error codes, client errors in the 4xx range and server errors in the 5xx range. The client errors indicate that the user agent has sent an invalid request (e.g. missing authentication credentials, requested resource not found or gone, etc.). The server errors inform the user agent that an event occurred that prevented the server fulfilling the request processing.

CherryPy provides a simple interface allowing the application developer to send the correct error code:

cherrypy.HTTPError(error_code, [error_message])

The HTTPError error will be trapped by the CherryPy engine, which will in turn use the error code and error message of the error as the status and body of the HTTP response to be sent.

When raising that error, CherryPy sets the HTTP response body to the provided message and the HTTP header matching the error code defined.

import cherrypy
class Root:
@cherrypy.expose
def index(self):
raise cherrypy.HTTPError(401, 'You are not authorized to
access this resource')
if __name__ == '__main__':
cherrypy.quickstart(Root(), '/')

The returned HTTP response will be:

HTTP/1.x 401 Unauthorized
Date: Wed, 14 Feb 2007 11:41:55 GMT
Content-Length: 744
Content-Type: text/html
Server: CherryPy/3.0.1alpha

CherryPy Essentials: Rapid Python Web Application Development

import cherrypy
class Root:
@cherrypy.expose
def index(self):
# shortcut to cherrypy.HTTPError(404)
raise cherrypy.NotFound
if __name__ == '__main__':
conf = {'global':{'request.show_tracebacks':False}}
cherrypy.config.update(conf)
cherrypy.quickstart(Root(), '/')

CherryPy Essentials: Rapid Python Web Application Development

You might wonder how to change the layout of the error page returned by CherryPy to integrate it with your own application. The way to achieve this is by using the configuration system.

import cherrypy
class Root:
# Uncomment this line to use this template for this level of the
# tree as well as its sub-levels
#_cp_config = {'error_page.404': 'notfound.html'}
@cherrypy.expose
def index(self):
raise cherrypy.NotFound
# Uncomment this line to tell CherryPy to use that html page only
# for this page handler. The other page handlers will use
# the default CherryPy layout
# index._cp_config = {'error_page.404': 'notfound.html'}
if __name__ == '__main__':
# Globally set the new layout for an HTTP 404 error code
cherrypy.config.update({'global':{'error_page.404':
'notfound.html' }})
cherrypy.quickstart(Root(), '/')

The notfound.html page:

<html>
<head><title>Clearly not around here</title></head>
<body>
<p>Well sorry but couldn't find the requested resource.</p>
</body>
</html>

CherryPy Essentials: Rapid Python Web Application Development

When catching an HTTPError error CherryPy looks for an error_page.xxx (where xxx is the HTTP error code used) entry in the configuration for that page handler and uses it instead of the default template.

As you can see CherryPy offers a very flexible and yet effective way to use your own page template for displaying friendlier error messages.

In this article we have discussed the high-level handling of errors in CherryPy. However, it is possible to modify the internal processing used through the hook API.

Summary

This article should have introduced you to some of the core principles of CherryPy, HTTP, and the server engine as well as its configuration system. We have also briefly discussed the object publisher engine, which allows transparent mapping of a URI to an exposed Python object. Finally we briefly reviewed the core modules of the CherryPy library that enhance its capacities and the way CherryPy lets you handle errors.

If you have read this article you may be interested to view :

 

CherryPy Essentials: Rapid Python Web Application Development Design, develop, test, and deploy your Python web applications easily
Published: March 2007
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

About the Author :


Sylvain Hellegouarch

Sylvain Hellegouarch is an IT Software Consultant dedicated to the development of free software projects such as CherryPy. Since 2004 he has been coordinating and administrating the community efforts around the project providing support for newcomers and seasoned developers, alike. In 2006 he developed 'bridge' and 'amplee', two Python-based projects centered on XML and the upcoming Atom Publishing Protocol respectively. He has also been deeply involved in The Viberavetions Project, a comprehensive grassroots solution for independent artists and musicians to better connect with consumers, as well as the nuXleus project, a platform designed for faster, more reliable inter and intra application and personal communication. Born in France, Sylvain graduated with a degree in Computer Science from South Brittany University, Vannes, France in 2002. Since then he has been working as an IT consultant for a variety of companies, both small and large. He currently resides in the United Kingdom.

Contact Sylvain Hellegouarch

Books From Packt

jQuery 1.3 with PHP
jQuery 1.3 with PHP

Drupal 6 Site Blueprints
Drupal 6 Site Blueprints

Joomla! 1.5 Development Cookbook
Joomla! 1.5 Development Cookbook

WordPress 2.7 Cookbook
WordPress 2.7 Cookbook

Plone 3 Theming
Plone 3 Theming

Drupal 6 Search Engine Optimization
Drupal 6 Search Engine Optimization

Joomla! 1.5 Content Administration
Joomla! 1.5 Content Administration

eZ Publish 4: Enterprise Web Sites Step-by-Step
eZ Publish 4: Enterprise Web Sites Step-by-Step

Your rating: None Average: 3 (1 vote)
Enjoyed your tutorial by
going to start hacking it to learn more about CherryPy and Python, which I do not have a lot under my belt

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
C
R
U
i
w
k
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software