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

我试图在一个蓝图 authorisation.py中访问应用程序配置,它在一个包 api 中。我在 __init__.py中初始化蓝图,这是在 authorisation.py中使用的。

不,不,不,不,不,不,不,不,不,不,不,不,不

from flask import Blueprint
api_blueprint = Blueprint("xxx.api", __name__, None)
from api import authorisation

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)

我得到了 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)
87589 次浏览

您需要导入由 Flask()返回的主 app变量(或者不管您如何称呼它) :

from someplace import app
app.config.get('CLIENT_ID')

或者在请求中这样做:

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

蓝图有 register,当你 注册图则时它会调用。因此,您可以重写此方法或使用 record室内设计师来描述依赖于 app的逻辑。

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

with app.test_request_context('/'):

在这通 current_app电话之前。

取而代之的是 RuntimeError: working outside of application context

为了建立在 Tbicr’s答案的基础上,这里有一个覆盖 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__)

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)

重载 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()])

您还可以将蓝图包装在一个函数中,并将 app作为参数传递:

蓝图:

def get_blueprint(app):
bp = Blueprint()
return bp

主要内容:

from . import my_blueprint
app.register_blueprint(my_blueprint.get_blueprint(app))

在蓝图视图中使用 flask.current_app代替 app

from flask import current_app


@api.route("/info")
def get_account_num():
num = current_app.config["INFO"]

current_app代理只能在 请求的上下文中使用。

我知道这是条老线索。但是在编写烧瓶服务时,我使用了类似的方法。它比上面的解决方案要长,但是它给了你自己使用定制类的可能性。坦白地说,我喜欢写这样的服务。

第一步:

我在一个不同的模块文件中添加了一个 struct,我们可以在其中创建类结构单例。我从已经讨论过的线程中得到了这个类结构。在 Python 中创建单例

class Singleton(type):
_instances = {}


def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
else:
cls._instances[cls].__init__(*args, **kwargs)


return cls._instances[cls]

第二步:

然后,我从上面定义的 Singleton 类中创建了一个 Singleton Environment Service 类,这只是为了我们的目的。与其重新创建这样的类,不如只创建一次,然后在其他模块、路由等导入中使用它们。我们可以使用相同的引用访问该类。

from flask import Config
from src.core.metaclass.Singleton import Singleton




class EnvironmentService(metaclass=Singleton):
__env: Config = None


def initialize(self, env):
self.__env = env
return EnvironmentService()


def get_all(self):
return self.__env.copy()


def get_one(self, key):
return self.__env.get(key)

第三步:

现在,我们将该服务包含在项目根目录中的应用程序中

from flask import Flask
from src.services.EnvironmentService import EnvironmentService


app = Flask(__name__)


# Here is our service
env = EnvironmentService().initialize(app.config)


# Your routes...

用法:

是的,我们现在可以从其他路线访问我们的服务。

from src.services.EnvironmentService import EnvironmentService


key = EnvironmentService().get_one("YOUR_KEY")