使用Flask服务器的面向对象的Python?

sol*_*les 16 python flask

我正在使用Flask将一些数据处理代码暴露为Web服务.我想要一些我的Flask函数可以访问的类变量.

让我带你走过我被困的地方:

from flask import Flask
app = Flask(__name__)

class MyServer:
  def __init__(self):
    globalData = json.load(filename)

  @app.route('/getSomeData')
  def getSomeData():
    return random.choice(globalData) #select some random data to return

if __name__ == "__main__":
  app.run(host='0.0.0.0')
Run Code Online (Sandbox Code Playgroud)

当我跑到getSomeData()Flask外面时,它工作正常.但是,当我用Flask运行时,我得到了500 internal server error.这里没有魔法,Flask不知道它应该初始化一个MyServer对象.如何将MyServer实例提供给app.run()命令?

可以承认失败并投入globalData数据库.但是,还有另外一种方法吗?

Mun*_*med 11

您可以创建一个MyServer超出端点范围的实例并访问其属性.这对我有用:

class MyServer:
    def __init__(self):
        self.globalData = "hello"

from flask import Flask
app = Flask(__name__)

my_server = MyServer()

@app.route("/getSomeData")
def getSomeData():
    return my_server.globalData

if __name__ == "__main__":
    app.run(host="0.0.0.0")
Run Code Online (Sandbox Code Playgroud)


小智 10

我知道这是一个迟到的回复,但我在遇到类似问题时遇到了这个问题。我发现flask-classful 非常好。您从 FlaskView 继承您的类并使用 MyServer 类注册 Flask 应用程序

http://flask-classful.teracy.org/#

在这种情况下,使用flask-classful,您的代码将如下所示:

from flask import Flask
from flask_classful import FlaskView, route

app = Flask(__name__)

class MyServer(FlaskView):
  def __init__(self):
    globalData = json.load(filename)

  @route('/getSomeData')
  def getSomeData():
    return random.choice(globalData) #select some random data to return


MyServer.register(app, base_route="/")


if __name__ == "__main__":
  app.run(host='0.0.0.0')
Run Code Online (Sandbox Code Playgroud)


web*_*rc2 6

耦合最少的解决方案是在运行时(而不是在加载时)应用路由:

def init_app(flask_app, database_interface, filesystem_interface):
    server = MyServer(database_interface, filesystem_interface)
    flask_app.route('get_data', methods=['GET'])(server.get_data)
Run Code Online (Sandbox Code Playgroud)

这是非常可测试的——只需init_app()在你的测试代码中调用模拟/伪造的依赖项(database_interfacefilesystem_interface)和一个已经配置为测试(app.config["TESTING"]=True或类似的东西)的烧瓶应用程序,你就可以编写覆盖你的测试了整个应用程序(包括烧瓶路由)。

唯一的缺点是这不是很“Flasky”(或者我被告知);Flask 的习惯用法是使用@app.route(),它在加载时应用并且必然是紧密耦合的,因为依赖项被硬编码到实现中,而不是注入到某些构造函数或工厂方法中(因此测试起来很复杂)。