我不是从Flask文档中得到的。此外,我可以看到类似的堆栈溢出问题,但我仍然没有得到我的答案,因此问。
我有一个使用gunicorn+gevent的flask应用程序。Gunicorn工作进程在启动时创建一个Flask应用程序。然后它导入一些文件来设置一些全局设置,比如到statsd服务器的udp连接等。设置只需要完成一次,即在工作进程启动时,而不是每次客户端请求时。导入文件中的设置代码需要访问配置变量。
我知道,在处理请求时,我可以使用current_app代理,但不能在请求之外使用。
一种方法是:将Flask应用程序创建代码放在单独的文件中,并将其包含在需要访问配置的任何位置。
例如:文件: mywsgi.py
from flask import Flask
application = Flask(__name__)
application.config.from_pyfile('myconfig.cfg')文件: mygunicornapp.py
from mywsgi import application
import file1
import file2
# import more files文件: file1.py
from mywsgi import application
# use the application config to setup something文件: file2.py
from mywsgi import application
# use the application config to setup something这是首选的方式吗?
Flask文档说我可以显式地创建应用程序上下文。
我是否可以在创建flask应用程序后推送应用程序上下文,并且永远不会弹出它。这样,只要我的进程运行,应用程序上下文就一直在那里,即使没有请求被处理,current_app代理也将在整个应用程序中可用?
例如:
from flask import Flask
application = Flask(__name__)
application.config.from_pyfile('myconfig.cfg')
application.app_context().push()现在我应该能够在我的代码中的任何地方使用current_app代理了。请大家想一想!
==更新==
导入file1.py、file2.py等文件,以便向应用程序添加路由。它们提供处理我的api请求的函数。因此,文件mygunicornapp.py看起来更像是:
文件: mygunicornapp.py
from mywsgi import application
from file1 import API1
@application.route("/api1")
def handle_api1():
return API1.handler()
from file2 import API2
@application.route("/api2")
def handle_api2():
return API2.handler()
# many more routes现在,file1导入了许多其他文件,而它们又导入了更多的文件。这些导入的文件中的任何一个都可能需要访问我在应用程序对象上设置的配置参数。问题是:如何使应用程序对象对所有这些文件可用?您是否建议我将应用程序对象传递给每个文件?
是否可以只延迟添加路由?我的意思是在current_app上下文本地可用后设置路由。这意味着文件将在current_app可用后导入。我尝试在'before_first_request‘回调中向本地current_app上下文添加路由。问题是,第一个请求返回404。随后的返回会给出正确的响应。
发布于 2017-09-08 21:59:56
为什么不在file1和file2中创建函数,并将参数app传递给它们呢?然后,您可以使用刚刚创建的app对象作为参数,在mywsgi.py的设置代码中调用这些函数。
这应该比你建议的其他一些方法效果更好。不同的文件相互导入接近于循环导入。推送应用程序上下文也会让你很难理解bug。
如果您在一个文件中创建对象app,并从该文件中的任何位置导入它,那么您基本上就拥有了一个全局变量(使用名称空间)。当你想要测试你的应用程序设置代码,或者出于其他原因创建多个版本的应用程序时,这将会导致问题。还有一个问题是,如果不创建应用程序对象,您将无法导入任何file1、file2。在测试这些代码时,或者可能在Flask之外重用一些代码,这将是一件痛苦的事情。
创建一次app对象并传递它会更好。有一个函数可以返回新创建的应用程序,可以从任何地方导入和调用,这是组织flask应用程序的一种常见方式。此文件通常称为factory.py。它使创建零个、一个或多个应用程序副本变得更容易,而不是使其变得更加困难。
https://stackoverflow.com/questions/46117592
复制相似问题