Flask:访问其他文件中的应用程序配置(任何地方,而不仅仅是在提供请求时)

时间:2017-09-08 13:26:10

标签: python-2.7 flask

我没有从Flask docs中清楚地看到它。此外,我可以看到类似的stackoverflow问题,但我仍然没有得到我的答案,因此要求。

我使用gunicorn + gevent提供了一个烧瓶应用程序。 Gunicorn工作流程一开始就创建了一个Flask应用程序。然后它导入一些设置一些全局事物的文件,例如与statsd服务器的udp连接等。设置只需要进行一次,即在工作进程启动时,而不是每个客户端请求。导入文件中的设置代码需要访问配置变量。

我知道在提供请求时我可以使用current_app代理,但不能在请求之外。

一种方法是:将Flask应用创建代码放在一个单独的文件中,并将其包含在您需要访问配置的任何位置。

例: file:mywsgi.py

from flask import Flask
application = Flask(__name__)
application.config.from_pyfile('myconfig.cfg')

file:mygunicornapp.py

from mywsgi import application
import file1
import file2
# import more files

file:file1.py

from mywsgi import application
# use the application config to setup something

file:file2.py

from mywsgi import application
# use the application config to setup something

这是首选方式吗?

Flask doc说我可以明确地创建应用程序上下文。

我可以在创建我的烧瓶应用程序之后推送应用程序上下文,并且永远不会弹出它。因此,只要我的进程运行并且即使没有提供请求,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看起来更像是:

file: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 context local可用之后设置路由。这意味着在current_app可用后将导入文件。我尝试将路由添加到< before_first_request'的本地current_app上下文中。打回来。问题是,第一个请求返回404.后续返回给出正确的响应。

1 个答案:

答案 0 :(得分:1)

为什么不在file1file2中创建函数,并将参数app传递给它们?然后,您可以在mywsgi.py中的设置代码中调用这些函数,并使用您刚创建的app对象作为参数。

这应该比你建议的其他一些东西好得多。导入彼此的不同文件接近循环导入。推动应用程序上下文也可能导致您最终遇到难以理解的错误。

如果在一个文件中创建对象app并从该文件中的任何位置导入它,则基本上有一个全局变量(使用命名空间)。当您想要测试应用程序设置代码或出于其他原因创建应用程序的多个版本时,这会导致问题。还有一个问题是,如果没有创建应用对象,您将无法导入任何file1file2 。在测试这些,或者可能在Flask之外重新使用某些代码时,这将是一种痛苦。

创建app对象并将其传递出去要好得多。拥有一个返回新创建的app的功能,可以从任何地方导入和调用,这是组织一个烧瓶应用程序的常用方法。此文件通常称为factory.py。它可以更轻松地创建应用程序的零个,一个或多个副本,而不是让它变得更加困难。