ブループリントでapp.configにアクセスする方法は?


114

authorisation.pyパッケージapiのブループリント内のアクセスアプリケーション構成にアクセスしようとしています。__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:アプリケーションコンテキスト外での作業

その理由は理解していますが、それらの構成設定にアクセスする正しい方法は何ですか?

----更新----一時的に、私はこれを行いました。

@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プロキシはリクエストのコンテキストでのみ使用できることに注意してください。
2016

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

1
こんにちは、record_paramsを呼び出すか登録する必要がありますか。試してみましたが、機能しませんでした。どうもありがとう。
mrblue 2018

アプリにアクセスする必要がある場合(たとえば、設計図を設定するための構成を取得するなど)、これはすばらしいことです。
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 2016年


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
ええ、私はどちらもやりたくありませんでした。1つ目は相互参照を作成することで、2つ目はDRYではありません。
Chirdeep Tomar 2013

2
@ChirdeepTomar最初のアプローチが循環インポートの作成(アプリを壊す)である場合、アプリの構造に問題があります。
Daniel Chatfield 2013

13
@DanielChatfieldそれは単に真実ではありません。アプリオブジェクトは、設計図を登録するオブジェクトです。ブループリントに適していることを示唆してからアプリオブジェクトをインポートすると、常に循環依存関係が発生します。正しい戦略については、他の回答を参照してください。
sholsapp 14

@sholsapp私はそれが循環インポートを作成することを知っています(フラスコのドキュメントでそうであるように:フラスコ.pocoo.org / docs / patterns / packages)、それはアプリを壊す循環インポート作成したかどうかを述べました。
Daniel Chatfield 14

1

ブループリントを関数にラップしappて、引数として渡すこともできます。

ブループリント:

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

メイン:

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

これを試しましたが、「内部サーバーエラー」が発生しました。
MD004 2017

このアプローチの欠点はありますか?
Tuukka Mustonen 2017

@トゥッカ:私は特定の欠点を覚えていません、私がそれを使用して以来、それは少し長すぎます。flask.current_app複数のアプリでブループリントを使用する場合、いくつかの利点があるかもしれません。このアプローチが問題を解決して使用する場合、Flaskは特定のアプローチを強制しません。
GeorgSchölly2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.