问题
For three simple apps: let us use a different port than 8080:
cherrypy.config.update({'server.socket_host': '127.0.0.1',
'server.socket_port': 28130
})
Let us set up three apps:
fusionConf = { '/fusion':{}} mobileConf = { r"/mobile_to_fusion":{}} adminConf = { '/admin':{}}
cherrypy.tree.mount(fusionListener, r"/fusion",fusionConf) cherrypy.tree.mount(mobileListener, r"/mobile_to_fusion",mobileConf) cherrypy.tree.mount(adminListener, r"/admin",adminConf) #
cherrypy.engine.start() cherrypy.engine.block()
We can see it running on the correct port:
$netstat -an | grep 28130
tcp4 0 0 127.0.0.1.28130 *.* LISTEN
The application logging agrees:
CherryPy Checker:
The application mounted at '/fusion' has config entries that start with its script name: '/fusion'
CherryPy Checker:
The application mounted at '/mobile_to_fusion' has config entries that start with its script name: '/mobile_to_fusion'
CherryPy Checker:
The application mounted at '/admin' has config entries that start with its script name: '/admin'
But when accessing the url: http://localhost:28130/admin - It is not found?
404 Not Found
The path '/admin' was not found.
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/cherrypy/_cprequest.py", line 638, in respond
self._do_respond(path_info)
File "/usr/local/lib/python3.8/site-packages/cherrypy/_cprequest.py", line 697, in _do_respond
response.body = self.handler()
File "/usr/local/lib/python3.8/site-packages/cherrypy/lib/encoding.py", line 219, in __call__
self.body = self.oldhandler(*args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/cherrypy/_cperror.py", line 416, in __call__
raise self
cherrypy._cperror.NotFound: (404, "The path '/admin' was not found.")
Powered by CherryPy 18.5.0
Why is Cherrypy
not finding the paths?
回答1:
The AdminListener
class is mounted under /admin
and AdminListener
does not have a default
or index
method to be able to mount an instance of AdminListener
under /admin
and expect it to work. For instance, with your current implementation/admin/admin
should work.
You can either:
- Define
def default(self)
ordef index(self)
inAdminListener
(replace theadmin
method) or - Mount an instance of
AdminListener
under''
. Likecherrypy.tree.mount(adminListener, "",adminConf)
, this will have the side effect of having theadminConf
apply to all the sub-application, so I suppose the right approach would be option1
.
For example, for option 1:
class AdminListener(object):
@cherrypy.expose
def index(self, param=None):
return "Hello from Admin"
alternatively
class AdminListener(object):
@cherrypy.expose
def default(self, param=None):
return "Hello from Admin"
The main difference is that the index
method does not consume url fragments like positional parameters, for example /admin/one
would not work, but /admin/?param=one
will work with index
and default
(notice the second /
, is important).
The default
method is like a catch-all alternative, it will be called for any undefined path under the mountpoint of the app.
来源:https://stackoverflow.com/questions/60841848/404-for-path-served-by-cherrypy