I'm trying to make CherryPy to handle request to /api via cherrypy.dispatch.MethodDispatcher() and all other request (like /) to some default dispatcher.
After reading CherryPy's doc I have no idea how to do this. They use both routing methods only separately but this is such a basic thing that I believe it has to work together.
#!/usr/local/bin/python2.7
import cherrypy
class Root(object):
@cherrypy.expose
def index(self):
return 'Hello world'
class RestAPI(object):
@cherrypy.expose
def POST(self, blah):
return 'ok'
cherrypy.config.update({
'global': {
'environment': 'production',
'server.socket_host': '127.0.0.1',
'server.socket_port': 8080,
}
})
root = Root()
root.api = RestAPI()
conf = {
'/api': {
'request.dispatch': cherrypy.dispatch.MethodDispatcher()
}
}
cherrypy.quickstart(root, '', config=conf)
By calling curl 'http://localhost:8080/' it gives me Hello world which is correct.
But calling curl -X POST 'http://localhost:8080/api' returns just 404.
By the way, the're eaxctly the same question without any answer CherryPy MethodDispatcher with multiple url paths.
Finally I solved it. The weird thing was that I had to expose index method (and all other methods in Root class) using annotation @cherrypy.expose and not just by setting exposed = True like in RestAPI class. I don't know why.
To properly test POST handler I didn't have to pass any variables but still I had to set Content-length: 0 header.
class Root(object):
@cherrypy.expose
def index(self):
return 'Hello world'
class RestAPI(object):
exposed = True
def POST(self):
return 'post'
def GET(self):
return 'get'
cherrypy.config.update({
'global': {
'environment': 'test_suite',
'server.socket_host': '127.0.0.1',
'server.socket_port': 8080,
}
})
cherrypy.tree.mount(Root())
cherrypy.tree.mount(RestAPI(), '/api',
{'/':
{'request.dispatch': cherrypy.dispatch.MethodDispatcher()}
}
)
cherrypy.engine.start()
cherrypy.engine.block()
Proper way to test POST using cURL:
curl -X POST --header "Content-length: 0" http://localhost:8080/api
I'm late, perhaps you already found the error. Your class RestApi must be exposed. That decorator doesn't work with MethodDispatcher.
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