繁体   English   中英

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

[英]How to access flask config variables outside application context according to my project structure?

spinngod.py -flask 应用程序启动代码

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

我想在应用程序上下文之外的其他一些文件中访问 c​​onfig.py 中定义的烧瓶配置变量。 应用程序配置取决于从命令行作为参数传递的配置文件(开发、阶段或生产)。

我能想到在应用程序上下文之外访问配置变量的唯一方法是将配置文件(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

有没有更好的方法在烧瓶中做到这一点?

文档

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

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

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

你像这样导入 current_app :

from flask import current_app

然后像这样访问配置或其他属性:

config = current_app.config

例子:

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

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

选择:

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

APP = create_app(os.environ.get('FLASK_ENV'))

src/module/another_module.py

from src.application import APP

def function_that_requires_config():
   config_value = APP.config.get(config_key, default_value)

不确定把它放在这里是否好,因为它可能不会直接回答问题,但这是我认为在请求之外使用配置值的最干净的方式,而不必将配置作为参数传递。

解决方案实际上非常简单,只需将您的代码部分视为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"))

如果您觉得需要从您的模块访问一些其他全局应用程序变量,这甚至可以改进。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM