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.
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.
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.
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.
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 URLhttp://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()
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With