कैसे एक खाका में app.config का उपयोग करने के लिए?


114

मैं एक ब्लूप्रिंट के अंदर एक्सेस एप्लिकेशन कॉन्फ़िगरेशन को एक्सेस करने की कोशिश कर रहा हूं authorisation.pyजो एक पैकेज एपी में है। मैं उस ब्लूप्रिंट को इनिशियलाइज़ कर रहा हूँ __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प्रॉक्सी केवल एक अनुरोध के संदर्भ में उपलब्ध है।
सेफ़र

1
@sephr अन्य स्थानों से उस अनुरोध के संदर्भ को एक्सेस करने के तरीके के बारे में कोई सुझाव (एक पैरामीटर के रूप में इसे पारित किए बिना, लेकिन वैश्विक पैरामीटर के कुछ प्रकार के रूप में)?
कर्क

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
पायथन 3 उपयोग के लिए: app.config.items () के बजाय app.config.iteritems ()
DhoTjai

1
नमस्ते, क्या मुझे रिकॉर्ड करने या पंजीकरण करने की आवश्यकता है_परम, मैंने कोशिश की है, लेकिन यह काम नहीं किया। बहुत बहुत धन्यवाद।
मर्बल जू

यदि आपको किसी एप्लिकेशन तक पहुंचने की आवश्यकता है (उदाहरण के लिए ब्लूप्रिंट को सेट करने के लिए कॉन्फिगरेशन प्राप्त करना) तो यह बहुत अच्छा है!
पीटर लाडा

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' मेरे लिए कारगर नहीं है, Ap आपी ’किस नाम स्थान से है?
टिम रिचर्डसन

क्षमा करें कि प्रश्न में रेखा से कॉपी नहीं किया गयाfrom api import api_blueprint as api
काइल जेम्स वॉकर

7

ब्लूप्रिंट में वह registerविधि होती है जिसे आप ब्लूप्रिंट दर्ज करते समय कहते हैं । तो आप इस विधि को ओवरराइड कर सकते हैं या तर्क का वर्णन करने के लिए recordडेकोरेटर का उपयोग कर सकते हैं जो निर्भर करता है app


4

current_appदृष्टिकोण ठीक है लेकिन आप कुछ अनुरोध संदर्भ होना आवश्यक है। यदि आपके पास एक नहीं है (कुछ पूर्व काम जैसे परीक्षण, जैसे) तो आप बेहतर स्थान पर होंगे

with app.test_request_context('/'):

इस current_appकॉल से पहले ।

RuntimeError: working outside of application contextइसके बजाय आपके पास होगा ।


3
जब किसी कारखाने में ऐप बनाया जाता है और इसलिए 'ऐप' (या जो भी फ्लास्क ऐप कहता है) आयात होने के लिए उपलब्ध नहीं है तो क्या होगा? अनुरोधों के अंदर यह कोई समस्या नहीं है, क्योंकि अनुरोधों के दौरान एक ऐप संदर्भ होता है, लेकिन जब अनुरोध लॉजिक के बाहर के हिस्सों को परिभाषित करते हैं, जिसमें एप्लिकेशन कॉन्फ़िगरेशन की आवश्यकता होती है। यदि आप संदर्भ बनाने के लिए ऐप का उपयोग नहीं कर सकते हैं तो ऐप कॉन्फ़िगरेशन कैसे एक्सेस कर सकते हैं?
रॉबर्टो क्यूबा


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 नहीं है।
चिरदीप तोमर

2
@ChirdeepTomar अगर पहला तरीका सर्कुलर इंपोर्ट (जो कि ऐप को तोड़ता है) बना रहा है तो आपके ऐप के संरचित होने में कुछ गड़बड़ है।
डेनियल चैटफील्ड

13
@ डैनियलचैटफील्ड यह सच नहीं है। एप्लिकेशन ऑब्जेक्ट ब्लूप्रिंट को पंजीकृत करने वाली वस्तु है। यह सुझाव देना कि यह ब्लूप्रिंट के लिए सही है, फिर एप्लिकेशन ऑब्जेक्ट को आयात करना हमेशा एक परिपत्र निर्भरता का कारण होगा । सही रणनीति के लिए अन्य उत्तर देखें।
शोलेप्स

@ शॉलसैप मुझे पता है कि यह एक सर्कुलर इंपोर्ट बनाएगा (जैसा कि यह फ्लास्क डॉक्स में होता है: फ्लास्क। pocoo.org/docs/patterns/packages ), मैंने कहा कि अगर इसने एक सर्कुलर इंपोर्ट बनाया जिसने ऐप को तोड़ दिया
डैनियल चैटफील्ड

1

आप किसी फ़ंक्शन में खाका भी लपेट सकते हैं और appतर्क के रूप में पास कर सकते हैं:

खाका:

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

मुख्य:

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

मैंने यह कोशिश की, लेकिन मुझे "आंतरिक सर्वर त्रुटि" मिली।
MD004

इस दृष्टिकोण के साथ कोई कमियां?
तुक्का मुस्तोनन

@ तुकका: मुझे कोई विशेष कमियां याद नहीं हैं, जब से मैंने इसका इस्तेमाल किया है, यह बहुत लंबा है। flask.current_appजब आप कई ऐप्स में ब्लूप्रिंट का उपयोग करते हैं तो कुछ फायदे हो सकते हैं। मैं यह सुझाव दूंगा कि यदि यह दृष्टिकोण इसे उपयोग करने के लिए आपके मुद्दों को हल करता है, तो फ्लास्क एक विशिष्ट दृष्टिकोण को लागू नहीं करता है।
जॉर्ज शॉली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.