फ्लास्क से अधिक सीएलआई की सिफारिश क्यों की जाती है?


13

फ्लास्क में 0.11 एक flaskCLI पेश किया गया था। डॉक्स और चैंज स्टेट दोनों की सिफारिश की जाती है।

विकास सर्वर डॉक्स :

फ्लास्क 0.11 से शुरू होकर एक डेवलपमेंट सर्वर को चलाने के कई तरीके हैं। सबसे अच्छा एक फ्लास्क कमांड लाइन उपयोगिता है, लेकिन आप Flask.run()विधि का उपयोग करना भी जारी रख सकते हैं ।

कमांड लाइन

कुप्पी कमांड लाइन स्क्रिप्ट (कमांड लाइन इंटरफेस) दृढ़ता से यह कैसे आवेदन लोड करता है की वजह से विकास के लिए सिफारिश की है क्योंकि यह एक बेहतर पुनः लोड अनुभव प्रदान करता है। मूल उपयोग इस प्रकार है:

$ export FLASK_APP=my_application
$ export FLASK_DEBUG=1
$ flask run

चांगेलॉग :

  • जोड़ा flaskऔर flask.cliक्लिक सीएलआई सिस्टम के माध्यम से स्थानीय डिबग सर्वर शुरू करने के लिए मॉड्यूल। यह पुरानी flask.run()पद्धति से अधिक की सिफारिश की जाती है क्योंकि यह एक अलग डिजाइन के कारण तेजी से और अधिक विश्वसनीय काम करता है और प्रतिस्थापित भी करता है Flask-Script

अब तक मैंने इस "बेहतर पुनः लोड अनुभव" को नोटिस नहीं किया था। मैं कस्टम स्क्रिप्ट पर CLI का उपयोग करने के बिंदु को देखने में विफल रहता हूं।

यदि उपयोग किया जाता है Flask.run, तो मैं बस एक अजगर फ़ाइल लिखूंगा:

#!/usr/bin/env python3
from my_app import app


if __name__ == '__main__':
    app.run(debug=True)

यदि सीएलआई का उपयोग कर रहे हैं, तो किसी को पर्यावरण चर निर्दिष्ट करना होगा। CLI डॉक्स में कहा गया है कि यह activatevirtualenvwrapper की स्क्रिप्ट में एकीकृत किया जा सकता है । व्यक्तिगत रूप से मैं इसे एप्लिकेशन का हिस्सा मानता हूं और सोचता हूं कि यह संस्करण नियंत्रण में होना चाहिए। काश, एक स्क्रिप्ट की जरूरत होती है:

#!/usr/bin/env bash
export FLASK_APP=my_app:app
export FLASK_DEBUG=1

flask run

बेशक यह एक अतिरिक्त बैट स्क्रिप्ट के साथ होगा जैसे ही कोई विंडोज उपयोगकर्ता सहयोग करना शुरू करते हैं।

इसके अलावा पहला विकल्प वास्तविक ऐप को शुरू करने से पहले अजगर में लिखा सेटअप देता है।

यह उदाहरण के लिए अनुमति देता है

  • पायथन में कमांड लाइन तर्कों को पार्स करने के लिए
  • ऐप को चलाने से पहले लॉग इन करना

उन्हें लगता है कि कस्टम कमांड जोड़ना संभव है। मैं यह देखने में विफल हूं कि यह सरल पायथन स्क्रिप्ट लिखने से बेहतर क्यों है, वैकल्पिक रूप से प्रवेश बिंदुओं के माध्यम से उजागर किया गया है।

उदाहरण लॉगिंग आउटपुट जब पायथन रन स्क्रिप्ट का उपयोग करके कॉन्फ़िगर लकड़हारा का उपयोग कर रहा है:

$ ./run.py 
   DEBUG 21:51:22 main.py:95) Configured logging
    INFO 21:51:22 _internal.py:87)  * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    INFO 21:51:22 _internal.py:87)  * Restarting with inotify reloader
   DEBUG 21:51:22 main.py:95) Configured logging
 WARNING 21:51:22 _internal.py:87)  * Debugger is active!
    INFO 21:51:22 _internal.py:87)  * Debugger pin code: 263-225-431
   DEBUG 21:51:25 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
   DEBUG 21:51:25 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
    INFO 21:51:25 _internal.py:87)  * Detected change in 'my_app/main.py', reloading
    INFO 21:51:26 _internal.py:87)  * Restarting with inotify reloader
   DEBUG 21:51:26 main.py:95) Configured logging
 WARNING 21:51:26 _internal.py:87)  * Debugger is active!
    INFO 21:51:26 _internal.py:87)  * Debugger pin code: 263-225-431

उदाहरण लॉगिंग आउटपुट सीएलआई का उपयोग करके एक कॉन्फ़िगर लकड़हारा का उपयोग करते समय:, ध्यान दें कि रूट लकड़हारा प्रक्रिया में पर्याप्त जल्दी सेटअप नहीं किया जा सकता है।

$ ./run.sh 
 * Serving Flask app "appsemble.api.main:app"
 * Forcing debug mode on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with inotify reloader
   DEBUG 21:51:33 main.py:95) Configured logging
 * Debugger is active!
 * Debugger pin code: 187-758-498
   DEBUG 21:51:34 main.py:95) Configured logging
   DEBUG 21:51:37 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
   DEBUG 21:51:37 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
 * Detected change in 'my_app/main.py', reloading
    INFO 21:51:37 _internal.py:87)  * Detected change in 'my_app/main.py', reloading
 * Restarting with inotify reloader
    INFO 21:51:38 _internal.py:87)  * Restarting with inotify reloader
 * Debugger is active!
 * Debugger pin code: 187-758-498
   DEBUG 21:51:38 main.py:95) Configured logging

मेरा वास्तविक प्रश्न बस है:

फ्लास्क सीएलआई की सिफारिश क्यों की जाती है Flask.run?

जवाबों:


11

विकास सर्वर डॉक्स में, वे कहते हैं कि कॉल रन () और स्वचालित रूप से कोड लोड करने के मुद्दे हैं:

यह सामान्य मामले के लिए अच्छी तरह से काम करता है लेकिन यह विकास के लिए अच्छी तरह से काम नहीं करता है यही कारण है कि फ्लास्क 0.11 से फ्लास्क विधि की सिफारिश की जाती है। इसका कारण यह है कि पुनः लोड तंत्र कैसे काम करता है, इसके कारण कुछ विचित्र दुष्परिणाम होते हैं (जैसे कुछ कोड को दो बार निष्पादित करना, कभी-कभी संदेश के बिना दुर्घटनाग्रस्त हो जाना या वाक्यविन्यास या आयात त्रुटि होने पर मर जाना)।

वे दावा करते हैं कि सीएलआई इस समस्या से ग्रस्त नहीं है।

इस मुद्दे पर स्पर्श करने वाली पहली प्रतिबद्धता यह है: https://github.com/pallets/flask/commit/3bdb90f06b9d3167320180d4a5055dcd949bfff

और वहाँ अर्मिन Ronacher ने लिखा:

यह स्वचालित रूप से पुनः लोड करने के साथ विकास के लिए इस फ़ंक्शन का उपयोग करने के लिए अनुशंसित नहीं है क्योंकि यह बुरी तरह से समर्थित है। इसके बजाय आपको flaskकमांड लाइन स्क्रिप्ट के runserverसमर्थन का उपयोग करना चाहिए ।

जैसा कि आरोन हॉल द्वारा उल्लेख किया गया है, ऐसा लगता है कि रन का उपयोग () इस तथ्य के कारण समस्याग्रस्त हो सकता है कि सभी ऑब्जेक्ट जो मॉड्यूल में परिभाषित वर्गों के उदाहरण हैं, उन्हें फिर से स्थापित नहीं किया जाएगा, और जब भी कोई मॉड्यूल लोड किया जाता है, तो मॉड्यूल जो आयात करता है उसे फिर से लोड नहीं किया जाता है।

इसके बारे में विवरण पायथन 3 के लिए: https://docs.python.org/3/library/importlib.html?highlight=importlib#module-importlib पर पाया जा सकता है

य़ह कहता है:

पाइथन की अन्य सभी वस्तुओं की तरह ही पुरानी वस्तुओं को भी उनके संदर्भ के शून्य में गिराए जाने के बाद ही पुनः प्राप्त किया जाता है।

पुरानी वस्तुओं (जैसे मॉड्यूल के बाहरी नाम) के अन्य संदर्भ नई वस्तुओं को संदर्भित करने के लिए पलटाव नहीं करते हैं और प्रत्येक नामस्थान में अपडेट किया जाना चाहिए जहां वे वांछित हैं।

जब एक मॉड्यूल पुनः लोड किया जाता है, तो इसका शब्दकोश (मॉड्यूल के वैश्विक चर युक्त) को बरकरार रखा जाता है। नामों की पुनर्निर्धारण पुरानी परिभाषाओं को पार कर जाएगी, इसलिए यह आमतौर पर कोई समस्या नहीं है। यदि मॉड्यूल का नया संस्करण पुराने नाम द्वारा परिभाषित नाम को परिभाषित नहीं करता है, तो पुरानी परिभाषा बनी हुई है।

इसलिए, एक नई प्रक्रिया बनाकर और पुराने को मारकर, आप स्वाभाविक रूप से सभी अप्रचलित संदर्भों को समाप्त कर देते हैं।

इसके अलावा, फ्लास्क का सीएलआई 'क्लिक' मॉड्यूल का उपयोग करता है, जिससे कस्टम कमांड को जोड़ना बहुत आसान हो जाता है, लेकिन सबसे महत्वपूर्ण बात यह है कि रीलोडिंग बग को ठीक करने के अलावा, सीएलआई अनुप्रयोगों को चलाने और कस्टम कमांड को जोड़ने के लिए एक मानकीकृत तरीका प्रदान करता है। यह एक बहुत अच्छी बात लगती है, क्योंकि यह फ्लास्क के साथ अलग-अलग टीमों और अनुप्रयोगों के बीच अधिक हस्तांतरणीय होने के साथ-साथ एक ही चीज़ करने के कई तरीके होने के कारण परिचित बनाता है।

ऐसा लगता है कि पायथन के ज़ेन के अनुसार फ्लास्क को अधिक बनाने का एक वास्तविक तरीका है:

वहाँ एक होना चाहिए - और अधिमानतः यह करने के लिए केवल एक ही - स्पष्ट तरीका।


2
यहां मुझे लगता है कि आर्मिन का मतलब "बुरी तरह से समर्थित" है: पायथन में, मॉड्यूल को फिर से लोड करने से मॉड्यूल आयात नहीं करता है, और न ही अन्य मॉड्यूल में पुराने ऑब्जेक्ट्स को नए मॉड्यूल से इंगित करने के लिए अन्य मॉड्यूल में नामों को फिर से लोड करता है - एक ही प्रक्रिया में एक नए मॉड्यूल को गर्म करना समस्याग्रस्त है। जब आप एक कोड परिवर्तन करना चाहते हैं तो एक नई प्रक्रिया शुरू करने से आप बेहतर हैं।
आरोन हॉल

अब जब आप इसका उल्लेख करते हैं, तो मैं आपके द्वारा वर्णित व्यवहार को याद करता हूं, स्पष्टीकरण के लिए धन्यवाद! मैं तदनुसार उत्तर संपादित करूंगा।
मार्टिन जुंगब्लेट श्राइनर

ठीक है, प्लस 1 मुझे उद्धृत करने के लिए। :)
एरन हॉल

हारून हॉल के अलावा ने मेरे लिए इसे स्पष्ट किया। धन्यवाद। :)
रेमको हस्ज़िंग

7
हमें पर्यावरण चर का उपयोग क्यों करना है FLASK_APP? क्या यह आंतरिक है कि यह कैसे काम करता है? मैं उत्सुक हूं कि flask runएक तर्क के रूप में क्यों स्वीकार नहीं करता है, जो नए लोगों को आसान बना देगा। धन्यवाद।
जॉन व्हीलर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.