Как получить доступ к app.config в проекте?
Я пытаюсь получить доступ к конфигурации приложения доступа внутри чертежа authorisation.py
, который в пакете api. Я инициализирую проект в __init__.py
, который используется в authorisation.py
.
__ __ INIT. Ру
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)
Ответы
Ответ 1
Вы можете использовать flask.current_app
, чтобы заменить приложение в проекте.
from flask import current_app as app
@api.route('/info/', methods = ['GET'])
def get_account_num():
num = app.config["INFO"]
Примечание., что прокси-сервер current_app
доступен только в контексте запроса.
Ответ 2
Перегрузка метода 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()])
Ответ 3
Чтобы построить ответ 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
decorator:
from flask import Blueprint
from api import api_blueprint as api
auth = None
# Note there 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)
Ответ 4
В чертежах есть register
method, который вызывается при форме регистрации. Таким образом, вы можете переопределить этот метод или использовать record
decorator для описания логики, которая зависит от app
.
Ответ 5
Вам либо нужно импортировать основную переменную 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)
Ответ 6
Подход current_app
хорош, но у вас должен быть некоторый контекст запроса. Если у вас его нет (например, для предварительной работы, например, для тестирования, лучше разместить
with app.test_request_context('/'):
перед этим вызовом current_app
.
Вместо этого у вас будет RuntimeError: working outside of application context
.
Ответ 7
Вы также можете обернуть проект в функцию и передать app
в качестве аргумента:
Blueprint:
def get_blueprint(app):
bp = Blueprint()
return bp
Main:
from . import my_blueprint
app.register_blueprint(my_blueprint.get_blueprint(app))