CSC/ECE 517 Fall 2014/ch1a 3 zq

From Expertiza_Wiki
Revision as of 19:27, 16 September 2014 by Nkdalmia (talk | contribs)
Jump to navigation Jump to search

CherryPy Framework

CherryPy is a python based, object-oriented web framework that enables developers to quickly create lightweight and fast web applications.<ref>http://www.cherrypy.org/</ref><ref>http://en.wikipedia.org/wiki/CherryPy</ref>

Background

CherryPy is a lightweight web server framework written in python. It has an object-oriented design and provides a basic HTTP web server as defined in RFC 7321. It includes built-in profiling, coverage, and testing tools to assist in development.

CherryPy does not have any built-in templating or database engines, and instead relies on external libraries and plugins. <ref>http://www.cherrypy.org/</ref> The users of CherryPy also have the rich set of python modules to choose from which can be used to provide many of the complex functionalities. All of these result in a very simple, yet powerful framework having a very steep learning curve.

It is distributed under the BSD License<ref>https://bitbucket.org/cherrypy/cherrypy/src/697c7af588b8/cherrypy/LICENSE.txt</ref>. The latest version is 3.6 as on September 15, 2014<ref>https://pypi.python.org/pypi/CherryPy</ref>.

Some of the popular websites using it are Hulu<ref>http://tech.hulu.com/blog/2013/03/13/python-and-hulu/</ref> and Netflix<ref>http://techblog.netflix.com/2013/03/python-at-netflix.html</ref>. The full list can be found here.

Basic Example

The following code demonstrates the most basic webserver using the CherryPy framework.

WebApp.py

import cherrypy

class WebApp(object):

    @cherrypy.expose
    def index(self):
        return "Hello, CherryPy!"
   
cherrypy.quickstart(WebApp())

Start the application by running the above python file "WebApp.py" and open your web browser to localhost:8080. The following page is displayed

Features

Query Strings

CherryPy will automatically parse the query string of a URL. Fields are passed as method arguments with matching names, and can take advantage of default argument values.

import cherrypy

class WebApp(object):
    @cherrypy.expose
    def test(self, value=1):
        return "Value = " + str(value)
   
cherrypy.quickstart(WebApp())

A URL of localhost:8080/test?value=5 gives the following

Cookies

CherryPy can set browser cookies with cherrypy.response.cookie and read browser cookies with cherrypy.request.cookie by accessing these variables as python dictionary objects.

import cherrypy

class WebApp(object):
    @cherrypy.expose
    def set(self, value = "Test"):
        cookie = cherrypy.response.cookie
        cookie['Value'] = value
        return "Cookie set"
    
    @cherrypy.expose
    def get(self):
        cookie = cherrypy.request.cookie
        return "Cookie value = " + str(cookie['Value'].value)
   
cherrypy.quickstart(WebApp())

Navigating to localhost:8080/set?value=test followed by localhost:8080/get gives the following

Logging

CherryPy provides the following method for application logging

cherrypy.log("Hello, CherryPy!")

By default, all logging is written to the console. The configuration keys log.access_file and log.error_file are also available for writing logging and errors to a text file.

In-built HTTP Server to host single or multiple applications

CherryPy comes with its own HTTP server which can be used to host web applications.

Single application

The easiest way to do that is by calling the cherrypy.quickstart() function. The function takes at least one argument.

cherrypy.quickstart(WebApp())

This starts the application 'WebApp' at http://localhost:8080/.

It can also take 2 more arguments.

cherrypy.quickstart(WebApp(), '/hello', {'/': {'tools.gzip.on': True}})

This starts the application 'WebApp' at http://localhost:8080/hello. The third argument defines the configuration for our application. It can either be a dictionary object or a file.

Multiple applications

The function cherrypy.tree.mount is used to host multiple applications.

cherrypy.tree.mount(MyApp1(), '/app1', app1_conf)
cherrypy.tree.mount(MyApp2(), '/app2', app2_conf)

cherrypy.engine.start()
cherrypy.engine.block()

This will host two applications having paths http://localhost:8080/app1 and http://localhost:8080/app2.

Server Configuration

The cherrypy.config.update function can be used to configure the HTTP server.

import cherrypy

class WebApp(object):
    @cherrypy.expose
    def index(self):
        return "Hello, CherryPy!"

cherrypy.config.update({'server.socket_port': 9090})
cherrypy.quickstart(WebApp())

This will start the server on port 9999 instead of the default port 8080. The application can then be accessed at http://localhost:9999/.

We can also pass a file (containing configuration) as an argument to this function.

cherrypy.config.update("WebAppServer.conf")

WebAppServer.conf

[global]
server.socket_port: 9999

Sessions

In CherryPy, sessions are disabled by default. To enable sessions, set the configuration tools.sessions.on to True. <ref>http://docs.cherrypy.org/en/latest/basics.html#using-sessions</ref>

Session variables can be accessed with cherrypy.session, which is a python dictionary object.

import cherrypy

class WebApp(object):
    @cherrypy.expose
    def index(self):
        if 'number' not in cherrypy.session:
            cherrypy.session['number'] = 0
        else:
            cherrypy.session['number'] += 1
        return "Number = " + str(cherrypy.session['number'])

cherrypy.config.update({'tools.sessions.on': True})
cherrypy.quickstart(WebApp())

This example shows a number that increments by 1 every time the user navigates to localhost:8080.

Serve Static Content

Static contents like files, images, stylesheets etc. can be easily served by adding the following lines in the the application configuration file.

[/images]
tools.staticdir.on = True
tools.staticdir.dir = "/site/public/images"

This will allow us to access some file "user.jpg" present in the folder "/site/public/images/user.jpg" using the url http://localhost:8080/images/user.jpg.

Publish REST APIs

It allows to expose our APIs as Restful Web Services.

import cherrypy


class MyAppRestMode(object):
    exposed = True

    def GET(self):
        return "Hello, CherryPy!"


conf = {
    '/': {
        'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
        'tools.response_headers.on': True,
        'tools.response_headers.headers': [('Content-Type', 'text/plain')],
    }
}
cherrypy.quickstart(MyAppRestMode(), '/', conf)

This exposes the REST API "GET": http://localhost:8080/. The API returns the string "Hello, CherryPy!".

Multiple HTTP Servers

It is possible to host the application with multiple servers, where each server runs on a different port.

from cherrypy._cpserver import Server

server = Server()
server.socket_port = 443
server.subscribe()

cherrypy.quickstart(WebApp())

The above code hosts our application with one more server which runs on port 443. We can create any number of additional servers.

Test Suite

References

<references/>