问题
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.
回答1:
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
回答2:
I'm late, perhaps you already found the error. Your class RestApi must be exposed. That decorator doesn't work with MethodDispatcher.
来源:https://stackoverflow.com/questions/21536057/combining-rest-dispatcher-with-the-default-one-in-a-single-cherrypy-app