簡體   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