使用Flask服务器的面向对象Python?
我使用Flask将一些数据处理代码公开为web服务。 我想要一些我的Flask函数可以访问的类变量 让我带你走过我被困的地方:使用Flask服务器的面向对象Python?,python,flask,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 ra
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')
当我在烧瓶外部运行getSomeData()
时,它工作正常。但是,当我使用Flask运行此操作时,会出现500内部服务器错误
。这里没有魔法,Flask也不知道它应该初始化一个MyServer
对象。如何将MyServer实例馈送到app.run()
命令
我可以承认失败并将
globalData
放入数据库。但是,还有别的办法吗 您可以在端点范围之外创建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")
最少耦合的解决方案是在运行时(而不是在加载时)应用路由: 这是非常可测试的——只需在测试代码中使用模拟/伪造的依赖项(
database\u interface
和filesystem\u interface
)调用init\u app()您已经准备好编写覆盖整个应用程序(包括烧瓶路由)的测试
唯一的缺点是这不是很“Flasky”(或者我已经被告知);Flask习惯用法是使用@app.route()
,这是在加载时应用的,并且必然是紧密耦合的,因为依赖关系是硬编码到实现中的,而不是注入到某些构造函数或工厂方法中(因此测试起来很复杂).有点晚,但这里有一个快速实现,我使用它在初始化时注册路由
from flask import Flask,request,render_template
from functools import partial
registered_routes = {}
def register_route(route=None):
#simple decorator for class based views
def inner(fn):
registered_routes[route] = fn
return fn
return inner
class MyServer(Flask):
def __init__(self,*args,**kwargs):
if not args:
kwargs.setdefault('import_name',__name__)
Flask.__init__(self,*args ,**kwargs)
# register the routes from the decorator
for route,fn in registered_routes.items():
partial_fn = partial(fn,self)
partial_fn.__name__ = fn.__name__
self.route(route)(partial_fn)
@register_route("/")
def index(self):
return render_template("my_template.html")
if __name__ == "__main__":
MyServer(template_folder=os.path.dirname(__file__)).run(debug=True)
如果您希望将MyServer类作为一种资源进行访问
我相信这可以帮助你:
from flask import Flask
from flask_restful import Resource, Api
import json
import numpy as np
app = Flask(__name__)
api = Api(app)
class MyServer(Resource):
def __init__(self):
self.globalData = json.load(filename)
def get(self):
return np.random.choice(self.globalData)
api.add_resource(MyServer, '/')
if __name__ == '__main__':
app.run()
我知道这是一个迟来的答复,但我在面对类似问题时遇到了这个问题。我发现这瓶酒真的很好。
您从FlaskView继承类,并向MyServer类注册Flask应用程序
在本例中,使用flask classful,您的代码如下所示:
从烧瓶导入烧瓶
从flask_classful导入FlaskView,路线
app=烧瓶(名称)
类MyServer(FlaskView):
定义初始化(自):
globalData=json.load(文件名)
@路由(“/getSomeData”)
def getSomeData():
return random.choice(globalData)#选择一些要返回的随机数据
MyServer.register(应用程序,base_route=“/”)
如果名称=“\uuuuu main\uuuuuuuu”:
app.run(host='0.0.0.0')
这是一个不错的选择,但您仍然无法编写端到端测试和模拟依赖项(如网络或文件系统IO),因为您的依赖项没有被注入。你可以做一些像unittest.mock.patch
这样的黑客行为,但是你必须像构建测试服务器一样小心构建真正的服务器(当然除了mock之外)。这基本上是服务器中传递的单例反模式flask。获取MyServer实例的\u数据,但请求数据在哪里?请将flask classful
替换为flask\u classful
(请参阅)
from flask import Flask
from flask_restful import Resource, Api
import json
import numpy as np
app = Flask(__name__)
api = Api(app)
class MyServer(Resource):
def __init__(self):
self.globalData = json.load(filename)
def get(self):
return np.random.choice(self.globalData)
api.add_resource(MyServer, '/')
if __name__ == '__main__':
app.run()