使用Flask和CherryPy来提供静态文件

时间:2014-01-30 08:06:40

标签: python flask cherrypy

首次使用网络框架,希望得到正确方法的建议。

我的目标是拥有一个可以根据传入的URL返回静态文件的服务器。我使用Flask作为我的Web框架,我打算使用CherryPy作为我的Web服务器。网络介绍了使用CherryPy设置Flask的许多方法,我不确定我是否正确使用它。

我一直在使用的资源:

我的Flask应用程序的简化版本,test.py:

from flask import Flask
from flask import request
from flask import send_from_directory
import os

FOLDER='contents'
ROOT=os.path.abspath(os.path.join('.', FOLDER))

@app.route("/get")
def route_3():
    return flask.send_from_directory(os.path.join(ROOT, 'p01', 'p02'), 'file12.zip', as_attachment=True)

if __name__ == "__main__":
    app.config.update(DEBUG=True)
    app.run()

我运行CherryPy的脚本:

import os
import cherrypy
from test import app
from cherrypy import wsgiserver

def option_1():
    cherrypy.tree.graft(app, '/')

    # If I comment this out, the server works
    #cherrypy.tree.mount(None, '/', config={
    #        '/': {
    #                'tools.staticdir.on': True,
    #                'tools.staticdir.dir': app.static_folder
    #            },
    #    })

    cherrypy.config.update({'server.socket_port': 5000})

    cherrypy.engine.start()
    cherrypy.engine.block()


def option2():
    d = wsgiserver.WSGIPathInfoDispatcher({'/': app})
    server = wsgiserver.CherryPyWSGIServer(('127.0.0.1', 5000), d)
    try:
       server.start()
    except KeyboardInterrupt:
       server.stop()

 if __name__ == '__main__':
    #option_1()
    option_2()

我有两个问题:

  1. 在设置CherryPy以运行Flask方面,option_1和option_2都有效,那么这两者之间有什么区别?
  2. 建议让Web服务器提供静态文件而不是Web框架。我这样做了吗?当我读取响应头时,服务器不是' Werkzeug',所以我假设CherryPy服务器正在发送它。

2 个答案:

答案 0 :(得分:7)

选项1是高级别的CherryPy

option_1实际上使用整个CherryPy Web框架(他们的文档refers to as the APPLICATION layer)来安装您的WSGI应用程序 - 插件,工具等可以充分利用。要使用CherryPy提供静态文件,您可能希望将注释掉的代码更改为:

cherrypy.tree.mount(None, '/static', config={
    '/': {
        'tools.staticdir.on': True,
        'tools.staticdir.dir': app.static_folder
    },
})

选项2是低级别的CherryPy

另一方面,

option_2只是利用CherryPy的WSGI服务器实现(the CORE layer)来为您的Flask应用程序提供服务 - 它不使用任何更像框架的CherryPy方面。如果你也可以通过Flask的路由层提供静态文件,你甚至可以删除WSGIPathInfoDispatcher中间件并在app下直接挂载CherryPyWSGIServer。如果您希望CherryPy管理/static路由服务,那么您需要在cherrypy.tools.staticdir.handler路由下安装/static的实例,如下所示:

static_handler = tools.staticdir.handler(section='/', dir=app.static_folder)
d = wsgiserver.WSGIPathInfoDispatcher({'/': app, '/static': static_handler})

答案 1 :(得分:0)

如果要替换Werkzeug中提供的开发服务器,我在Flask-Script中使用以下内容来替换runserver()。但是,这将在__main__

def runserver():
    """
    Overwriting the Flask Script runserver() default.
    CherryPy is much more stable than the built-in Flask dev server
    """
    debug_app = DebuggedApplication(app, True)
    cherrypy.tree.graft(debug_app, '/')
    cherrypy.config.update({
        'engine.autoreload_on': True,
        'server.socket_port': 5000,
        'server.socket_host': '0.0.0.0'
    })
    try:
        cherrypy.engine.start()
        cherrypy.engine.block()
    except KeyboardInterrupt:
        cherrypy.engine.stop()

如果您没有DebuggedApplication包装器,DEBUG = True将无效。您可能需要根据应用程序稍微调整一下。它还将提供Ctrl+C