When I do this and try to access "/api" than cherryPy throws "TypeError: 'ApiStringGenerator' object is not callable" error
'''
Created on Jan 11, 2016
@author: ankurjat
'''
import cherrypy
import random
import string
import os
conf = {'/': {'tools.sessions.on': True,
'tools.staticdir.root': os.path.abspath(os.getcwd())},
'/static': {'tools.staticdir.on': True,
'tools.staticdir.dir': './resources'},
'/api': {'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
'tools.sessions.on': True,
'tools.response_headers.on': True,
'tools.response_headers.headers': [('Content-Type', 'text/plain')]}
}
class ApiStringGenerator(object):
exposed = True
@cherrypy.tools.accept(media='text/plain')
def GET(self, length=8):
value = cherrypy.session['mystring']
return value
def POST(self, length=8):
value = ''.join(random.sample(string.hexdigits, int(length)))
cherrypy.session['mystring'] = value
return value
def PUT(self, value):
cherrypy.session['mystring'] = value
def DELETE(self):
cherrypy.session.pop('mystring', None)
class StringGenerator(object):
@cherrypy.expose
def index(self):
return file('templates/index.html')
if __name__ == '__main__':
cherrypy.tree.mount(ApiStringGenerator(), '/api', conf)
cherrypy.tree.mount(StringGenerator(), '/', conf)
cherrypy.engine.start()
cherrypy.engine.block()
But when I change below lines
cherrypy.tree.mount(ApiStringGenerator(), '/api', conf)
cherrypy.tree.mount(StringGenerator(), '/', conf)
cherrypy.engine.start()
cherrypy.engine.block()
By the code
webapp = StringGenerator()
webapp.api = ApiStringGenerator()
cherrypy.quickstart(webapp, '/', conf)
Then no error and everything works fine. Please help.
The problem is that the configuration in cherrypy is relative to the mountpoint.
So when you are configuring the MethodDispatcher
in /api
inside the mount point /api
. You are activating the MethodDispatcher
inside /api/api
and the dispatcher that's gets used in /api
it's the default one, hence trying to call the object because the object has the exposed
attribute but it's not callable. Which is the behavior of the default dispatcher.
If you want to do:
cherrypy.tree.mount(ApiStringGenerator(), '/api', conf)
The configuration needs to be relative to the /api
:
{'/': {'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
'tools.sessions.on': True,
'tools.response_headers.on': True,
'tools.response_headers.headers': [('Content-Type', 'text/plain')]}}