Blueprint에서 app.config에 액세스하는 방법은 무엇입니까?


114

authorisation.py패키지 API에있는 청사진 내에서 애플리케이션 구성에 액세스하려고합니다 . .NET에서 __init__.py사용되는 청사진을 초기화하고 authorisation.py있습니다.

__init__.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 : working outside of application context

왜 그런지 이해하지만 해당 구성 설정에 액세스하는 올바른 방법은 무엇입니까?

---- 업데이트 ---- 일시적으로 이렇게했습니다.

@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)

답변:


133

청사진보기 flask.current_app에서 대신 사용 app합니다.

from flask import current_app

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

current_app프록시는의 맥락에서만 사용할 수 있습니다 요청 .


25
점을 유의 current_app프록시가 요청의 컨텍스트에서만 사용할 수 있습니다.
sepehr

1
@sephr 다른 위치에서 요청 컨텍스트에 액세스하는 방법에 대한 팁이 있습니까 (매개 변수로 전달하지 않고 일종의 전역 매개 변수로 전달)?
carkod

21

오버로딩 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()])

1
Python 3의 경우 : app.config.iteritems () 대신 app.config.items ()
DhoTjai

1
안녕하세요, record_params를 호출하거나 등록해야합니까? 시도했지만 작동하지 않았습니다. 감사합니다.
mrblue

앱에 액세스해야하는 경우 (예 : 청사진 설정을위한 구성 가져 오기) 이것은 훌륭합니다!
Peter Lada

12

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)

'@ api.record'는 나를 위해 작동하지 않습니다. 'api'의 이름 공간은 무엇입니까?
Tim Richardson

죄송합니다 질문에 라인에서 해당 복사하지 않았다from api import api_blueprint as api
카일 제임스 워커


4

current_app접근 방식은 괜찮습니다하지만 당신은 몇 가지 요청 컨텍스트를 가지고 있어야합니다. 없는 경우 (예 : 테스트와 같은 사전 작업) 배치하는 것이 좋습니다.

with app.test_request_context('/'):

이 전에 current_app 전화 .

RuntimeError: working outside of application context대신 을 갖게 됩니다.


3
공장에서 앱이 만들어 져서 '앱'(또는 플라스크 앱이라고 부르는 모든 것)을 가져올 수없는 경우는 어떻습니까? 요청 중에는 앱 컨텍스트가 있기 때문에 요청 내부에는 문제가 없지만 앱 구성이 필요한 요청 로직 외부의 부분을 정의 할 때 문제가되지 않습니다. 앱을 사용하여 컨텍스트를 만들 수없는 경우 어떻게 앱 구성에 액세스 할 수 있습니까?
RobertoCuba


3

다음에서 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)

4
네, 둘 중 어느 것도하고 싶지 않았습니다. 첫 번째는 상호 참조를 만드는 것이고 두 번째 방법은 DRY가 아닙니다.
Chirdeep Tomar 2013-08-13

2
@ChirdeepTomar 첫 번째 접근 방식이 순환 가져 오기 (앱을 중단 함)를 만드는 것이라면 앱의 구조에 문제가있는 것입니다.
Daniel Chatfield

13
@DanielChatfield는 단순히 사실이 아닙니다. 앱 객체는 블루 프린트를 등록하는 객체입니다. 청사진에 맞다고 제안한 다음 앱 개체를 가져 오면 항상 순환 종속성이 발생합니다. 올바른 전략은 다른 답변을 참조하십시오.
sholsapp 2014-07-04

@sholsapp 나는 그것이 순환 가져 오기를 만들 것이라는 것을 알고 있습니다 (플라스크 문서 : flask.pocoo.org/docs/patterns/packages에서와 마찬가지로 ), 앱을 망가 뜨리는 순환 가져 오기 만들었다면 말했습니다 .
Daniel Chatfield

1

청사진을 함수로 래핑하고 app 인수로 .

청사진:

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

본관:

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

시도했지만 "내부 서버 오류"가 발생했습니다.
MD004

이 접근 방식의 단점은 무엇입니까?
Tuukka Mustonen

@Tuukka : 특정 단점을 기억하지 못합니다. 사용한 이후로 너무 오래되었습니다. flask.current_app여러 앱에서 청사진을 사용할 때 사용 하면 몇 가지 이점이있을 수 있습니다 . 이 접근 방식이 문제를 해결하면 Flask가 특정 접근 방식을 시행하지 않는 것이 좋습니다.
Georg Schölly
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.