146

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

__init__.py

from flask import Blueprint
api_blueprint = Blueprint("xxx.api", __name__, None)
from api import 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)
4

8 回答 8

176

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

from flask import current_app

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

current_app代理仅在请求的上下文中可用。

于 2016-07-08T09:04:03.747 回答
23

重载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()])
于 2014-11-01T18:17:24.640 回答
15

为了建立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__)

还有一个使用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)
于 2014-04-12T22:49:50.317 回答
7

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

于 2013-08-14T07:51:16.437 回答
4

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

with app.test_request_context('/'):

在这个current_app电话之前。

RuntimeError: working outside of application context相反,您将拥有。

于 2014-02-20T19:02:11.333 回答
2

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

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)
于 2013-08-13T18:48:05.553 回答
1

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

蓝图:

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

主要的:

from . import my_blueprint
app.register_blueprint(my_blueprint.get_blueprint(app))
于 2016-06-29T12:03:46.243 回答
1

我知道这是一个旧线程。但是在编写烧瓶服务时,我使用了这样的方法来做到这一点。它比上面的解决方案更长,但它使您可以自己使用自定义类。坦率地说,我喜欢编写这样的服务。

步骤1:

我在不同的模块文件中添加了一个结构,我们可以在其中使类结构单例。我从已经讨论过的这个线程中得到了这个类结构。在 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]

第2步:

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

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)

第 3 步:

现在我们在项目根目录的应用程序中包含该服务。此过程应在路由之前应用。

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")
于 2021-08-19T13:51:57.733 回答