Tuesday, November 14, 2017

Cherry Blossoms with CherryPy

CherryPy is a python web framework which I really like. It is minimalistic in nature, is very pleasant to work with, and still we can accomplish much. Below I will detail a basic web app setup with CherryPy demonstrating basic usage which one can expand further.
# blossoms.py
"""A blossoms server with CherryPy."""

import cherrypy
import os

class CherryBlossom(object):
"""The server route handler methods."""

def __init__(self):

def index(self):
"""The root url, when not mapped to static response, this action will be invoked."""
return self.about()

def about(self):
return 'Enjoy cherry blossoms.'

def get_greeting_message(self, name):
"""Return greetings to the given name in JSON format."""
return {'msg': 'Greetings %s' % name'}

@cherrypy.tools.register('before_finalize', priority=60)
def secureheaders():
"""Update server response headers."""
headers = cherrypy.response.headers
headers['X-Frame-Options'] = 'DENY'
headers['X-XSS-Protection'] = '1; mode=block'
headers['X-Powered-By'] = 'Cherry Blossoms'
headers['Server'] = 'Sakura'

class Blossoms(object):
"""Server configuration and initialisation."""

def __init__(self):

def start(self):
"""Start the service."""
blossom = CherryBlossom()
# routes
dispatcher = cherrypy.dispatch.RoutesDispatcher()
dispatcher.explicit = False
dispatcher.connect('home', '/', blossom.index)
dispatcher.connect('about', '/about/', controller=blossom, action='about', conditions=dict(method=['GET']))
dispatcher.connect('greetings', '/greet/{name}/', controller=blossom, action='greet', conditions=dict(method=['GET']))
# config
root_dir = os.path.dirname(os.path.abspath(__file__))
global_conf = root_dir + '/blossoms.conf'
conf = {
'/': {
'request.dispatch' : dispatcher,
'tools.staticdir.dir': root_dir
app = cherrypy.tree.mount(None, '/', global_conf)
if hasattr(cherrypy.engine, "signal_handler"):
if hasattr(cherrypy.engine, "console_control_handler"):
# pyserver.py
from blossoms import Blossoms

blossom = Blossoms()
The configuration are present in the blossoms.conf file.
server.socket_host: ''
server.socket_port: 1729
server.thread_pool: 8

tools.gzip.on: True
tools.staticdir.on: True
tools.staticdir.index: 'index.html'
tools.staticdir.debug: True,
tools.secureheaders.on = True,
tools.response_headers.on: True,
tools.response.stream: True,
tools.sessions.on = True
tools.sessions.secure = True
tools.sessions.httponly = True
log.screen: True
Calling the /, FQDN alone is configured to serve static content. The GET endpoints are /greet/{name} and /about/. The RoutesDispatcher uses routes package to do the dispatch. The requirements.txt is below.
We load the config and merge it with few updated setting from the code before starting the server. We have a server that handles static content, does REST based routing, custom response headers, JSON, html responses, with configurable settings. Enjoy cherry blossoms.