Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running more than one class in Cherrypy

I'm trying to build a small site with an index etc. and an api that I want in /api.

For example:

class Site(object):
    @cherrypy.expose
    def index(self):
        return "Hello, World!"
    @cherrypy.expose
    def contact(self):
        return "Email us at..."
    @cherrypy.expose
    def about(self):
        return "We are..."

class Api(object):
    @cherrypy.expose
    def getSomething(self, something):
        db.get(something)
    @cherrypy.expose
    def putSomething(self, something)

So, I'd like to be able to go to mysite.com/contact and mysite.com/Api/putSomething

If I use cherrypy.quickstart(Site()), I'll only get the pages under Site.

I think there's a way of mapping the class Api under /Api, but I can't find it.

like image 616
joedborg Avatar asked Feb 02 '13 11:02

joedborg


People also ask

Is CherryPy a MVC?

Bird's-Eye View of CherryPyIt also takes a modular approach, following the Model View Controller (MVC) pattern to build web services; therefore, it's fast and developer-friendly.

Is CherryPy a web server?

CherryPy comes with its own web (HTTP) server. That is why CherryPy is self-contained and allows users to run a CherryPy application within minutes of getting the library. The web server acts as the gateway to the application with the help of which all the requests and responses are kept in track.

What is CherryPy framework?

CherryPy is an object-oriented web application framework using the Python programming language. It is designed for rapid development of web applications by wrapping the HTTP protocol but stays at a low level and does not offer much more than what is defined in RFC 7231.


2 Answers

Update (13th March, 2017): The original answer below is quite outdated but am leaving it as it is to reflect the original question that was asked.

The official documentation now has a proper guide on how to achieve it.


Original Answer:

Look at the default dispatcher. The entire documentation for Dispatching.

Quoting from the docs:

root = HelloWorld()
root.onepage = OnePage()
root.otherpage = OtherPage()

In the example above, the URL http://localhost/onepage will point at the first object and the URL http://localhost/otherpage will point at the second one. As usual, this search is done automatically.

This link gives even more detail on it with a complete example shown below.

import cherrypy

class Root:
    def index(self):
        return "Hello, world!"
    index.exposed = True

class Admin:
    def user(self, name=""):
        return "You asked for user '%s'" % name
    user.exposed = True

class Search:
    def index(self):
        return search_page()
    index.exposed = True

cherrypy.root = Root()
cherrypy.root.admin = Admin()
cherrypy.root.admin.search = Search()
like image 60
Nandeep Mali Avatar answered Oct 21 '22 07:10

Nandeep Mali


As fumanchu mentioned, you can create different subsections to your site with multiple calls to cherrypy.tree.mount. Below is a simplified version of a site that I'm working on that consists of both a front-end web app and a restful API:

import cherrypy
import web

class WebService(object):

    def __init__(self):
        app_config = {
            '/static': {
                # enable serving up static resource files
                'tools.staticdir.root': '/static',
                'tools.staticdir.on': True,
                'tools.staticdir.dir': "static",
            },
        }

        api_config = {
            '/': {
                # the api uses restful method dispatching
                'request.dispatch': cherrypy.dispatch.MethodDispatcher(),

                # all api calls require that the client passes HTTP basic authentication
                'tools.authorize.on': True,
            }
        }

        cherrypy.tree.mount(web.Application(), '/', config=app_config)
        cherrypy.tree.mount(web.API(), '/api', config=api_config)

    # a blocking call that starts the web application listening for requests
    def start(self, port=8080):
        cherrypy.config.update({'server.socket_host': '0.0.0.0', })
        cherrypy.config.update({'server.socket_port': port, })
        cherrypy.engine.start()
        cherrypy.engine.block()

    # stops the web application
    def stop(self):
        cherrypy.engine.stop()

Creating an instance of WebService initializes two different web applications. The first is my front-end application, which lives at web.Application and will be served up at /. The second is my restful API, which lives at web.API and will be served up at /api.

The two views have different configurations too. For instance, I've specified that the api uses method dispatching, and that access to it is governed by HTTP Basic authentication.

Once you create an instance of WebService, you can call start or stop on it as necessary, and it takes care of all of the cleanup.

Pretty cool stuff.

like image 32
MusikPolice Avatar answered Oct 21 '22 05:10

MusikPolice