CSC/ECE 517 Fall 2014/ch1a 3 zq: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
 
(51 intermediate revisions by 2 users not shown)
Line 1: Line 1:
'''CherryPy Framework'''
'''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>
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>


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 of applications using it can be found here.<ref>http://docs.cherrypy.org/en/latest/intro.html#websites-running-atop-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> Python comes with a rich library support, so this typically is not an issue.


== Background ==
It is distributed under the BSD License<ref>https://bitbucket.org/cherrypy/cherrypy/src/697c7af588b8/cherrypy/LICENSE.txt</ref>. The latest stable version is 3.6 as of August 19, 2014<ref>https://pypi.python.org/pypi/CherryPy</ref>.
Object-oriented, python based<br>
Basic RFC 7321 (HTTP)<br>
Built-in profiling<br>
complete test suite<br>
No built-in templating or database engines, use external tools<br>


Why, when, where and by whom was it developed ?<br>
Some of the well known websites using CherryPy 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 [http://docs.cherrypy.org/en/latest/intro.html#websites-running-atop-cherrypy here].
Basic Philosophy Behind the project ?<br>
Which companies are using it ?<br>
Total number of active users, latest release version number etc.<br>


== Basic Example ==
== Basic Example ==


The following code demonstrates the most basic webserver using the CherryPy framework.
The following code demonstrates a very simple web server using the CherryPy framework.


'''WebApp.py'''
<pre>
<pre>
import cherrypy
import cherrypy
Line 32: Line 29:
</pre>
</pre>


Run the application, and open your web browser to [http://localhost:8080 localhost:8080].  The following page is displayed
The line <code>cherrypy.quickstart(WebApp())</code> tells the CherryPy framework to start the HTTP server, which hosts the application class <code>WebApp</code>.  The method <code>index</code> is exposed as a URL handler by the <code>@cherrypy.expose</code> statement.  The return value of the method is what is sent as the HTTP response.
 
Start the application by running the above Python file "WebApp.py" and open your web browser to http://localhost:8080.  The following page is displayed


[[File:Screenshot_-_09132014_-_03-26-32_PM.png]]
[[File:Screenshot_-_09132014_-_03-26-32_PM.png]]


== Features ==
== Features ==
=== 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 <code>cherrypy.quickstart()</code> function. The function takes at least one argument.
<pre>cherrypy.quickstart(WebApp())</pre>
This starts the application 'WebApp' at http://localhost:8080/.
It can also take 2 more arguments.
<pre>cherrypy.quickstart(WebApp(), '/hello', {'/': {'tools.gzip.on': True}})</pre>
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 <code>cherrypy.tree.mount</code> is used to host multiple applications.
<pre>
cherrypy.tree.mount(MyApp1(), '/app1', app1_conf)
cherrypy.tree.mount(MyApp2(), '/app2', app2_conf)
cherrypy.engine.start()
cherrypy.engine.block()
</pre>
This will host two applications having paths http://localhost:8080/app1 and http://localhost:8080/app2.
=== Logging ===
CherryPy provides the following method for application logging
<pre>
cherrypy.log("Hello, CherryPy!")
</pre>
By default, all logging is written to the console.  The configuration keys <tt>log.access_file</tt> and <tt>log.error_file</tt> are also available for writing logging and errors to a text file.


=== Query Strings ===
=== Query Strings ===
Line 92: Line 52:
</pre>
</pre>


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


[[File:Screenshot_-_09132014_-_06-37-27_PM.png]]
[[File:Screenshot_-_09132014_-_06-37-27_PM.png]]
Line 98: Line 58:
=== Cookies ===
=== Cookies ===


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


<pre>
<pre>
Line 118: Line 78:
</pre>
</pre>


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


[[File:CherryPyCookieTest.png]]
[[File:CherryPyCookieTest.png]]


=== Sessions ===
=== Logging ===
 
CherryPy provides the following method for application logging
 
<pre>
cherrypy.log("Hello, CherryPy!")
</pre>
 
By default, all logging is written to the console.  The configuration keys <tt>log.access_file</tt> and <tt>log.error_file</tt> are also available for writing logging and errors to a text file.
 
=== Starting the HTTP Server ===
CherryPy provides two ways to start the HTTP server, depending on the developer's needs.
 
==== Single Application ====
The simplest way is to call the <tt>cherrypy.quickstart()</tt> function. This function takes at least one argument.
 
<pre>cherrypy.quickstart(WebApp())</pre>
This starts the application class 'WebApp' at http://localhost:8080/.
 
It can also take 2 more arguments.
<pre>cherrypy.quickstart(WebApp(), '/app', {'/': {'tools.gzip.on': True}})</pre>
This starts the application class 'WebApp' at http://localhost:8080/app.
The third argument defines the configuration for the application. It can either be a Python dictionary object or a configuration file.


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


Session variables can be accessed with <tt>cherrypy.session</tt>, which is a python dictionary object.
The function <tt>cherrypy.tree.mount</tt> is used to host multiple application classes.


<pre>
<pre>
import cherrypy
cherrypy.tree.mount(MyApp1(), '/app1', app1_conf)
cherrypy.tree.mount(MyApp2(), '/app2', app2_conf)


class WebApp(object):
cherrypy.engine.start()
    @cherrypy.expose
cherrypy.engine.block()
    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())
</pre>
</pre>


This example shows a number that increments by 1 every time the user navigates to [http://localhost:8080 localhost:8080].
This will host two applications classes having paths http://localhost:8080/app1 and http://localhost:8080/app2.


=== Server Configuration ===
=== Server Configuration ===


The <code>cherrypy.config.update</code> function can be used to configure the HTTP server.
The <tt>cherrypy.config.update</tt> function can be used to configure the CherryPy framework


<pre>
<pre>
Line 158: Line 132:
         return "Hello, CherryPy!"
         return "Hello, CherryPy!"


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


</pre>
</pre>


This will start the server on port 9999 instead of the default port 8080. The application can then be accessed at http://localhost:9999/.
This will start the HTTP 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.
A configuration file path instead can be passed as an argument to this function.
<pre>
<pre>
cherrypy.config.update("WebAppServer.conf")
cherrypy.config.update("WebAppServer.conf")
Line 176: Line 150:
</pre>
</pre>


=== Serve Static Content ===
=== Sessions ===
Static contents like files, images, stylesheets etc. can be easily served by adding the following lines in the the application configuration file.
 
In CherryPy, sessions are disabled by default.  To enable sessions, set the configuration <tt>tools.sessions.on</tt> to <tt>True</tt>. <ref>http://docs.cherrypy.org/en/latest/basics.html#using-sessions</ref>
 
Session variables can be accessed with <tt>cherrypy.session</tt>, which is a Python dictionary object.
 
<pre>
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())
</pre>
 
This example shows a number that increments by 1 every time the user navigates to http://localhost:8080.
 
=== Static Content ===
Files with static content, such as binaries, images, or stylesheets, can be served by the HTTP server by adding the following lines to the application configuration file.


<pre>
<pre>
Line 185: Line 183:
</pre>
</pre>


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.
This will allow the user 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 ===
=== REST APIs ===


It allows to expose our APIs as Restful Web Services.
CherryPy can be used to expose the APIs as RESTful Web Services. This allows third party applications to easily communicate with the system.


<pre>
<pre>
Line 212: Line 210:
</pre>
</pre>


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


=== Multiple HTTP Servers ===
=== Multiple Ports ===


It is possible to host the application with multiple servers, where each server runs on a different port.
The default HTTP server started by CherryPy can be used to host the application only on one socket port (default 8080). However, it is possible to host the application on multiple ports.


<pre>
<pre>
Line 228: Line 226:
</pre>
</pre>


The above code hosts our application with one more server which runs on port 443. We can create any number of additional servers.
The above code hosts the application with one more HTTP server which runs on port 443. It is possible to create any number of additional HTTP servers.
 
=== Authentication ===
 
CherryPy provides two authentication mechanisms: Simple and Digest. It follows the specification defined by [http://tools.ietf.org/html/rfc2617.html RFC 2617]
 
=== WSGI Support ===
 
CherryPy supports the WSGI (Web Server Gateway Interface) specification defined by [http://www.python.org/dev/peps/pep-0333 PEP 0333] and [http://www.python.org/dev/peps/pep-3333 PEP 3333].
 
This allows two things:
* Instead of using the default CherryPy server, a CherryPy application can be hosted on an external WSGI server.
* The CherryPy server can be used independently to host an external WSGI application.


=== Test Suite ===
=== Test Suite ===
The CherryPy framework provides a class, named <tt>helper</tt> which can be used as a base class for writing functional tests.
Running a test will start the complete application and thus can be used to simulate the scenario when a user actually tries to access the server on web.
The sample code to run a test can be found [http://docs.cherrypy.org/en/latest/advanced.html#testing-your-application here]


== References ==
== References ==
<references/>
<references/>

Latest revision as of 01:28, 20 September 2014

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> Python comes with a rich library support, so this typically is not an issue.

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

Some of the well known websites using CherryPy 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 a very simple web server using the CherryPy framework.

WebApp.py

import cherrypy

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

The line cherrypy.quickstart(WebApp()) tells the CherryPy framework to start the HTTP server, which hosts the application class WebApp. The method index is exposed as a URL handler by the @cherrypy.expose statement. The return value of the method is what is sent as the HTTP response.

Start the application by running the above Python file "WebApp.py" and open your web browser to http://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 http://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 http://localhost:8080/set?value=test followed by http://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.

Starting the HTTP Server

CherryPy provides two ways to start the HTTP server, depending on the developer's needs.

Single Application

The simplest way is to call the cherrypy.quickstart() function. This function takes at least one argument.

cherrypy.quickstart(WebApp())

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

It can also take 2 more arguments.

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

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

Multiple Applications

The function cherrypy.tree.mount is used to host multiple application classes.

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 classes having paths http://localhost:8080/app1 and http://localhost:8080/app2.

Server Configuration

The cherrypy.config.update function can be used to configure the CherryPy framework

import cherrypy

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

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

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

A configuration file path instead can be passed 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 http://localhost:8080.

Static Content

Files with static content, such as binaries, images, or stylesheets, can be served by the HTTP server by adding the following lines to the application configuration file.

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

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

REST APIs

CherryPy can be used to expose the APIs as RESTful Web Services. This allows third party applications to easily communicate with the system.

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)

The above code exposes the GET API with url http://localhost:8080/. The API returns the string "Hello, CherryPy!".

Multiple Ports

The default HTTP server started by CherryPy can be used to host the application only on one socket port (default 8080). However, it is possible to host the application on multiple ports.

from cherrypy._cpserver import Server

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

cherrypy.quickstart(WebApp())

The above code hosts the application with one more HTTP server which runs on port 443. It is possible to create any number of additional HTTP servers.

Authentication

CherryPy provides two authentication mechanisms: Simple and Digest. It follows the specification defined by RFC 2617

WSGI Support

CherryPy supports the WSGI (Web Server Gateway Interface) specification defined by PEP 0333 and PEP 3333.

This allows two things:

  • Instead of using the default CherryPy server, a CherryPy application can be hosted on an external WSGI server.
  • The CherryPy server can be used independently to host an external WSGI application.

Test Suite

The CherryPy framework provides a class, named helper which can be used as a base class for writing functional tests.

Running a test will start the complete application and thus can be used to simulate the scenario when a user actually tries to access the server on web.

The sample code to run a test can be found here

References

<references/>