如何在蓝图中访问app.config?

Chi*_*mar 94 flask

我试图authorisation.py在包api中的蓝图内访问访问应用程序配置.我正在初始化__init__.py其中使用的蓝图authorisation.py.

__init__.py

from flask import Blueprint
api_blueprint = Blueprint("xxx.api", __name__, None)
from api import authorisation
Run Code Online (Sandbox Code Playgroud)

authorisation.py

from flask import request, jsonify, current_app

from ..oauth_adapter import OauthAdapter
from api import api_blueprint as api

client_id = current_app.config.get('CLIENT_ID')
client_secret = current_app.config.get('CLIENT_SECRET')
scope = current_app.config.get('SCOPE')
callback = current_app.config.get('CALLBACK')

auth = OauthAdapter(client_id, client_secret, scope, callback)


@api.route('/authorisation_url')
def authorisation_url():
    url = auth.get_authorisation_url()
    return str(url)
Run Code Online (Sandbox Code Playgroud)

我得到RuntimeError:在应用程序上下文之外工作

我明白为什么会这样,但是访问这些配置设置的正确方法是什么?

----更新----暂时,我已经这样做了.

@api.route('/authorisation_url')
def authorisation_url():
    client_id, client_secret, scope, callback = config_helper.get_config()
    auth = OauthAdapter(client_id, client_secret, scope, callback)
    url = auth.get_authorisation_url()
    return str(url)
Run Code Online (Sandbox Code Playgroud)

小智 104

您可以用flask.current_app蓝图代替app.

from flask import current_app as app
@api.route('/info/', methods = ['GET'])
def get_account_num():
    num = app.config["INFO"]
Run Code Online (Sandbox Code Playgroud)

注:current_app代理仅在的情况下可要求.

  • 请注意,`current_app`代理仅在请求的上下文中可用. (23认同)
  • @sephr有关如何从其他地方访问该请求上下文的任何提示(不将其作为参数传递,而是作为某种全局参数传递)? (5认同)

Ash*_*ynd 19

重载record方法似乎很容易:

api_blueprint = Blueprint('xxx.api',  __name__, None)
api_blueprint.config = {}

@api_blueprint.record
def record_params(setup_state):
  app = setup_state.app
  api_blueprint.config = dict([(key,value) for (key,value) in app.config.iteritems()])
Run Code Online (Sandbox Code Playgroud)

  • 对于 Python 3 使用: app.config.items() 而不是 app.config.iteritems() (2认同)
  • 如果您需要访问应用程序(例如获取用于设置蓝图的配置),这非常棒! (2认同)

Kyl*_*ker 10

tbicr的答案的基础上,这是一个覆盖register方法示例的示例:

from flask import Blueprint

auth = None

class RegisteringExampleBlueprint(Blueprint):
    def register(self, app, options, first_registration=False):
        global auth

        config = app.config
        client_id = config.get('CLIENT_ID')
        client_secret = config.get('CLIENT_SECRET')
        scope = config.get('SCOPE')
        callback = config.get('CALLBACK')

        auth = OauthAdapter(client_id, client_secret, scope, callback)

        super(RegisteringExampleBlueprint,
              self).register(app, options, first_registration)

the_blueprint = RegisteringExampleBlueprint('example', __name__)
Run Code Online (Sandbox Code Playgroud)

以及使用record装饰器的示例:

from flask import Blueprint
from api import api_blueprint as api

auth = None

# Note there's also a record_once decorator
@api.record
def record_auth(setup_state):
    global auth

    config = setup_state.app.config
    client_id = config.get('CLIENT_ID')
    client_secret = config.get('CLIENT_SECRET')
    scope = config.get('SCOPE')
    callback = config.get('CALLBACK')

    auth = OauthAdapter(client_id, client_secret, scope, callback)
Run Code Online (Sandbox Code Playgroud)


tbi*_*icr 7

蓝图有注册蓝图时调用的register方法.因此,您可以覆盖此方法或使用装饰器来描述依赖于的逻辑.recordapp


Ben*_*man 5

current_app方法很好,但是您必须具有一些请求上下文。如果您没有(例如一些前期工作,例如测试),最好放置

with app.test_request_context('/'):

在这个current_app电话之前。

您将拥有RuntimeError: working outside of application context

  • 当应用程序是在工厂中创建的,因此无法导入“应用程序”(或任何称为烧瓶应用程序的应用程序)时,该怎么办?在请求内部没有问题,因为在请求期间有一个应用程序上下文,但是在定义请求逻辑之外需要应用程序配置的部分时。如果您不能使用应用程序创建上下文,如何访问应用程序配置? (4认同)

Dan*_*eld 1

您需要导入app由以下命令返回的主变量(或您所称的任何名称)Flask()

from someplace import app
app.config.get('CLIENT_ID')
Run Code Online (Sandbox Code Playgroud)

或者从请求中执行此操作:

@api.route('/authorisation_url')
def authorisation_url():
    client_id = current_app.config.get('CLIENT_ID')
    url = auth.get_authorisation_url()
    return str(url)
Run Code Online (Sandbox Code Playgroud)

  • @DanielChatfield 这根本不是真的。app对象是注册蓝图的对象。建议蓝图正确然后导入应用程序对象将_总是_导致循环依赖。请参阅其他答案以获得正确的策略。 (22认同)
  • 是的,我两个都不想做。第一种是创建交叉引用,第二种方法不是 DRY。 (4认同)
  • @ChirdeepTomar 如果第一种方法是创建循环导入(这会破坏应用程序),那么您的应用程序的结构就有问题。 (2认同)