2015-03-30 90 views
1

我想使用CherryPy的WSGI服務器來提供靜態文件,如Using Flask with CherryPy to serve static files。接受答案的選項2看起來完全像我想要做的,但是當我嘗試使用靜態目錄處理程序時,我得到了一個KeyErrorKeyError與CherryPy WSGIServer服務靜態文件

我已經試過:

>>>> 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正常工作?

+0

我有同樣的問題,你設法解決它? – 2015-04-02 11:17:41

+0

@ThomasTurner目前我有我的Flask應用程序服務靜態文件,就像在[這個SO回答](http://stackoverflow.com/a/20648053/2216621)。答案是這不如從服務器直接提供服務(CherryPy在這種情況下),所以我仍然希望有人能夠回答這個問題。 – 2015-04-02 17:20:24

回答

1

我已經嘗試過各種方法來獲得這個工作,直到今天還擊中了你已經看到的KeyError(以及其他問題)。

我終於設法讓CherryPy通過修改this gist(下面包含)中的代碼來爲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。

對於好奇 - 我在要點中使用代碼來定製django-cherrypy的runcpserver管理命令的一個版本,儘管事後看來它可能會更容易從頭開始創建新命令。

祝你好運(並感謝Alfredo Deza)!

+0

你應該在你的答案中包含相關的代碼。鏈接到源代碼很好,但你永遠不知道它何時會消失。 – 2015-04-07 14:56:59

+0

代碼現包含以供參考。 – robashdown 2015-04-07 15:32:44