Search code examples
pythoncherrypy

"TypeError: object is not callable" using `cherrypy.dispatch.MethodDispatcher()`


I'm following along with the cherrypy tutorial "Give it a REST", except I wanted to have my cherrypy server start two classes: One to serve some static files, and another one for the RESTful API:

api.py:

import cherrypy

class TestApi(object):
    conf = {
        '/api/v1/test': {
            'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
        }
    }
    exposed = True

    def GET(self):
        return "Test GET!"

server.py:

import cherrypy

import api

server_conf = {
    'server.socket_port': 1313,
}


class Root(object):
    conf = {
        '/': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': "/some/path",
            'tools.staticdir.debug': True
        }
    }

    @cherrypy.expose
    def index(self):
        return "Hello world!"


if __name__ == '__main__':
    cherrypy.config.update(server_conf)
    cherrypy.tree.mount(Root(), '/', Root.conf)

    cherrypy.tree.mount(api.TestApi(), '/api/v1/test',
                        api.TestApi.conf)
    cherrypy.engine.start()
    cherrypy.engine.block()

However, when I start the server (python server.py) and do a GET on http://localhost:1313/api/v1/test I get this error:

500 Internal Server Error

The server encountered an unexpected condition which prevented it from fulfilling the request.

Traceback (most recent call last): File "/usr/local/lib/python2.7/site-packages/cherrypy/_cprequest.py", line 670, in respond response.body = self.handler() File "/usr/local/lib/python2.7/site-packages/cherrypy/lib/encoding.py", line 217, in call self.body = self.oldhandler(*args, **kwargs) File "/usr/local/lib/python2.7/site-packages/cherrypy/_cpdispatch.py", line 68, in call raise x TypeError: 'TestApi' object is not callable

I looked up similar questions and came upon how to use multiple dispatchers in same cherrypy application?, but it's not clear if the answer there is really applicable to me. Any pointers would be appreciated!


Solution

  • Just realized the issue is with the TestApi.conf:

    Need to change the path for the config from '/api/v1/test' to '/' in the section below.

    class TestApi(object):
        conf = {
            '/api/v1/test': {
                'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
            }
        }
    

    I guess this is because I already pass in the mount path in server.py so the config path is relative from that point on.