【问题标题】:KeyError with CherryPy WSGIServer serving static files服务静态文件的 CherryPy WSGIServer 的 KeyError
【发布时间】:2015-03-30 20:58:46
【问题描述】:

我正在尝试使用 CherryPy 的 WSGI 服务器来提供静态文件,例如 Using Flask with CherryPy to serve static files。已接受答案的选项 2 看起来与我想做的完全一样,但是当我尝试使用静态目录处理程序时,我得到了 KeyError

我尝试过的:

>>>> import cherrypy
>>>> from cherrypy import wsgiserver
>>>> import os
>>>> static_handler = cherrypy.tools.staticdir.handler(section='/', dir=os.path.abspath('server_files')
>>>> d = wsgiserver.WSGIPathInfoDispatcher({'/': static_handler})
>>>> server = wsgiserver.CherryPyWSGIServer(('localhost', 12345), d)
>>>> server.start()

然后,当我尝试访问服务器时,我在控制台中收到 500 响应和以下错误:

KeyError('tools',)
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/cherrypy/wsgiserver/wsgiserver2.py", line 1353, in communicate
    req.respond()
  File "/Library/Python/2.7/site-packages/cherrypy/wsgiserver/wsgiserver2.py", line 868, in respond
    self.server.gateway(self).respond()
  File "/Library/Python/2.7/site-packages/cherrypy/wsgiserver/wsgiserver2.py", line 2267, in respond
    response = self.req.server.wsgi_app(self.env, self.start_response)
  File "/Library/Python/2.7/site-packages/cherrypy/wsgiserver/wsgiserver2.py", line 2477, in __call__
    return app(environ, start_response)
  File "/Library/Python/2.7/site-packages/cherrypy/_cptools.py", line 175, in handle_func
    handled = self.callable(*args, **self._merged_args(kwargs))
  File "/Library/Python/2.7/site-packages/cherrypy/_cptools.py", line 102, in _merged_args
    tm = cherrypy.serving.request.toolmaps[self.namespace]
KeyError: 'tools'

每次我尝试点击服务器应该能够显示的任何内容时,都会显示两次。当我将 Flask 应用程序连接到服务器时,Flask 应用程序按预期工作,但静态文件服务仍然给出相同的错误。

我需要做什么才能让staticdir.handler 工作?

【问题讨论】:

  • 我遇到了同样的问题,你解决了吗?
  • @ThomasTurner 目前我正在让我的 Flask 应用程序提供静态文件,例如 this SO answer。答案说这不如直接从服务器(在这种情况下为 CherryPy)提供它,所以我仍然希望有人能够回答这个问题。

标签: python python-2.7 cherrypy


【解决方案1】:

我已经尝试了各种方法来让它工作,直到今天还遇到了你一直看到的 KeyError(以及其他问题)。

我终于通过改编this gist(包括在下面)中的代码,让 CherryPy 与 Django 应用程序一起提供静态服务。

import os
import cherrypy
from cherrypy import wsgiserver

from my_wsgi_app import wsgi

PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), 'public'))


class Root(object):
    pass

def make_static_config(static_dir_name):
    """
    All custom static configurations are set here, since most are common, it
    makes sense to generate them just once.
    """
    static_path = os.path.join('/', static_dir_name)
    path = os.path.join(PATH, static_dir_name)
    configuration = {static_path: {
        'tools.staticdir.on': True,
        'tools.staticdir.dir': path}
    }
    print configuration
    return cherrypy.tree.mount(Root(), '/', config=configuration)

# Assuming your app has media on diferent paths, like 'c', 'i' and 'j'
application = wsgiserver.WSGIPathInfoDispatcher({
    '/': wsgi.application,
    '/c': make_static_config('c'),
    '/j': make_static_config('j'),
    '/i': make_static_config('i')})

server = wsgiserver.CherryPyWSGIServer(('0.0.0.0', 8070), application,
                                       server_name='www.cherrypy.example')
try:
    server.start()
except KeyboardInterrupt:
    print "Terminating server..."
    server.stop()

希望包装一个 Flask 应用程序会非常相似。

对我来说,关键是在虚拟类上使用 cherrypy.tree.mount,而不是尝试直接使用 staticdir.handler。

出于好奇 - 我使用 gist 中的代码自定义 django-cherrypy 的 runcpserver 管理命令的一个版本,尽管事后看来,从头开始创建新命令可能更容易。

祝你好运(感谢Alfredo Deza)!

【讨论】:

  • 您应该在答案中包含相关代码。链接到源很好,但你永远不知道它什么时候会消失。
  • 现在包含代码以供参考。
猜你喜欢
  • 2012-07-02
  • 2012-01-02
  • 2010-10-20
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-23
  • 1970-01-01
相关资源
最近更新 更多