如何根据我的项目结构在应用程序上下文之外访问flask配置变量?

时间:2018-07-02 06:55:02

标签: python python-3.x python-2.7 flask

spinngod.py-烧瓶应用程序入门代码

from app import create_app
import sys

run_profile = str(sys.argv[1]) if len(sys.argv) >= 2 else 'development'
app = create_app(run_profile)

print("App Root Path:" + app.root_path)

if __name__ == '__main__':
    print sys.path
    app.run(debug=True, host='0.0.0.0')

app / init .py-创建烧瓶应用程序

def create_app(profile_name):
    print "currently active profile:" + profile_name
    app = Flask(__name__)

    ############# configurations ####################
    app.config.from_object(config[profile_name])
    configure_app(app)
    configure_app_logger(app)

    #################### blueprint registration and rest_plus namespace additions ###############
    from api_1_0 import api as api_1_0_blueprint
    from api_1_0.restplus import api_restplus

    # ************************************************** #
    api_restplus.init_app(api_1_0_blueprint)
    api_restplus.add_namespace(application_namespace)
    api_restplus.add_namespace(pipeline_template_namespace)
    api_restplus.add_namespace(loadbalancer_namespace)
    api_restplus.add_namespace(servergroup_namespace)
    api_restplus.add_namespace(task_namespace)
    # ************************************************** #

    app.register_blueprint(api_1_0_blueprint)

    ##############################################################
    return app

我想在应用程序上下文之外的其他一些文件中访问config.py中定义的flask配置变量。应用程序的配置取决于从哪个配置文件开始(开发,阶段或生产),而配置文件是从命令行作为arg传递的。

我想在应用程序上下文之外访问配置变量的唯一方法是将配置文件(dev,stage或prod)设置为环境变量,然后 然后直接从配置文件导入。

我尝试的第二种方法是将烧瓶应用程序的创建移至app / init .py外部方法中。

这是我尝试访问另一个类中的配置变量的方式。

import requests


class Client(object):
    def __init__(self):
        from app import app
        print "fjaijflkajsf" + app.config['SPINNAKER_BASE_URL']
        pass

在烧瓶中有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

来自docs

  

而不是将应用程序传递给每个函数,而是访问current_app和g代理。

     

Flask应用程序对象具有一些属性,例如config,可用于在视图和CLI命令中进行访问。但是,在项目的模块内导入应用程序实例容易出现循环导入问题。

     

Flask通过应用程序上下文解决了此问题。您可以使用current_app代理,而不是直接引用应用,该代理指向处理当前活动的应用。

您可以这样导入current_app:

from flask import current_app

,然后访问配置或其他类似属性:

config = current_app.config

示例:

src / application.py(其中在上下文中设置配置)

create_app():
  app = Flask('app')
  app.config.from_object(some_class)
  return app

src / module / another_module.py

from flask import current_app

def function_that_requires_config():
    config = current_app.config

我希望这会有所帮助!

答案 1 :(得分:0)

不确定将其放在此处是否合适,因为它可能无法直接回答问题,但这是我想在请求外使用配置值而不必将config作为参数传递的最干净的方法。

该解决方案实际上非常简单,只需将代码的一部分视为flask_extension。 我的示例是使用外部api,配置文件中包含ROOT_URL,并且我不想从我的路由中进行api调用,因此api在其自己的模块中。

在我的create_app功能中:


from flask import Flask

from .api import api
from .configmodule import Config
from .model import db

def create_app(environment):
    app = Flask(__name__)
    app.config.from_object(Config.get_config(environment))
    db.init_app(app)
    api.init_app(app) # here i use api.init_app the same way i do for sqlalchemy

和api / init .py

class Api:
    def init_app(self, app):
        self.config = app.config


api = Api()

现在我可以在api模式下的任何文件中编写

from . import api

def foo():
   print(api.config.get("API_ROOT_URL"))

如果您觉得有必要从模块中访问其他一些全局应用程序变量,甚至可以改善这一点。