paint-brush
3 प्रमुख पायथन समस्याएं और उन्हें कैसे हल करेंद्वारा@dave01
3,896 रीडिंग
3,896 रीडिंग

3 प्रमुख पायथन समस्याएं और उन्हें कैसे हल करें

द्वारा David Finson18m2023/01/21
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

जटिल विकास परिवेशों के प्रबंधन ने अक्सर कुछ चुनौतियों का सामना किया है क्योंकि परियोजनाओं को बढ़ाया गया है। समाधान कंटेनरीकरण का उपयोग है, जो किसी एप्लिकेशन और उसकी निर्भरता को एक स्व-निहित इकाई में पैकेजिंग का एक तरीका है जिसे आसानी से तैनात किया जा सकता है और किसी भी प्लेटफॉर्म पर चलाया जा सकता है। मैं प्रदर्शित करूँगा कि डॉकर और डॉकर कंपोज़ का उपयोग करके एक कंटेनरीकृत विकास वातावरण कैसे सेट अप और उपयोग किया जाए।
featured image - 3 प्रमुख पायथन समस्याएं और उन्हें कैसे हल करें
David Finson HackerNoon profile picture

पायथन के साथ काम करते समय, अधिक बार नहीं, मेरे लिए एक शानदार अनुभव रहा है, जटिल विकास के वातावरण का प्रबंधन अक्सर कुछ चुनौतियों का सामना करता है क्योंकि परियोजनाओं को बढ़ाया जाता है।

केवल कुछ उदाहरणों को नाम देने के लिए, यहाँ पायथन के साथ 3 प्रमुख मुद्दे हैं, जिनमें मैंने भाग लिया है:

1. अनुप्रयोग जो पर्यावरण चर पर निर्भर करते हैं, उन्हें ऐप चलाने से पहले सेट करने के लिए इन चरों की आवश्यकता हो सकती है।

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

3. एक ही प्रोजेक्ट के भीतर विभिन्न माइक्रोसर्विसेज के बीच डिपेंडेंसी वर्जनिंग क्लैश हो सकता है।

कई माइक्रोसर्विसेज के साथ काम करते समय चीजें विशेष रूप से अजीब हो सकती हैं, जो एक दूसरे पर निर्भर करती हैं, और स्पष्ट रूप से, एक डेवलपर के रूप में, मैं वास्तव में उठने और चलने के लिए इस ओवरहेड का प्रबंधन नहीं करना चाहता हूं। यह विशेष रूप से सच है अगर मैं सिर्फ एक नई परियोजना पर जा रहा हूं।

पायथन ऐप विकसित करते समय मैंने देखा है कि एक सामान्य समाधान, पायथन वर्चुअल वातावरण का उपयोग करना है, जो अलग-अलग वातावरण हैं जिनमें पायथन इंस्टॉलेशन और आवश्यक पैकेज होते हैं। हालाँकि, कई आभासी वातावरण और अन्य पर्यावरण-संबंधी कॉन्फ़िगरेशन का प्रबंधन अभी भी समय लेने वाला और बोझिल हो सकता है, क्योंकि आभासी वातावरण केवल पायथन दुभाषिया स्तर पर अलगाव प्रदान करता है। इसका मतलब यह है कि अन्य पर्यावरण से संबंधित सेटअप, जैसे कि पर्यावरण चर और बंदरगाह आवंटन, अभी भी सभी परियोजना घटकों के लिए विश्व स्तर पर साझा किया जाता है।

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

 docker-compose.yml
). हालांकि मिनिक्यूब जैसे वैकल्पिक समाधान हैं, सादगी के लिए, मैं इस उदाहरण में डॉकर और डॉकर कंपोज़ का उपयोग करना जारी रखूंगा।

मैं प्रदर्शित करूँगा कि डॉकर और डॉकर कंपोज़ का उपयोग करके एक कंटेनरीकृत विकास वातावरण कैसे सेट अप और उपयोग किया जाए। मैं एक कंटेनरीकृत विकास परिवेश का उपयोग करने की कुछ चुनौतियों पर भी चर्चा करूँगा, और एक प्रभावी विकास परिवेश के लिए निम्नलिखित प्रमुख आवश्यकताओं को पूरा करने के लिए डॉकर और डॉकर कंपोज़ को कॉन्फ़िगर करके उन्हें कैसे दूर किया जाए:

1. रन - एंड-टू-एंड परिदृश्य चलाना जो लक्ष्य उत्पादन वातावरण पर निष्पादन का अनुकरण करता है।

2. डिप्लॉय - कोड में बदलाव करना और जल्दी से फिर से डिप्लॉय करना, जैसा कि एक गैर-कंटेनरीकृत एप्लिकेशन रनटाइम स्टैक के साथ होता है।

3. डिबग - त्रुटियों को पहचानने और ठीक करने के लिए, एक गैर-कंटेनरीकृत एप्लिकेशन रनटाइम स्टैक के साथ, कोड के माध्यम से कदम उठाने के लिए ब्रेकप्वाइंट सेट करना और डीबगर का उपयोग करना।

प्रोजेक्ट सेटअप

उदाहरण के द्वारा इसे स्पष्ट करने के लिए, मैं एक साधारण पायथन एप्लिकेशन को परिभाषित करूँगा जो हल्के पायथन वेब फ्रेमवर्क, फ्लास्क का उपयोग करता है, जिससे लेखकों और उनके पदों के बारे में जानकारी के लिए एक RESTful API बनाया जा सके। एपीआई का एक एकल समापन बिंदु है,

 /authors/{author_id}
, जिसका उपयोग पथ पैरामीटर के रूप में उनकी आईडी निर्दिष्ट करके किसी विशेष लेखक के बारे में जानकारी प्राप्त करने के लिए किया जा सकता है। एप्लिकेशन तब एक अलग पोस्ट सेवा के लिए HTTP अनुरोध करने के लिए अनुरोध मॉड्यूल का उपयोग करता है, जिससे उस लेखक द्वारा पोस्ट की सूची प्रदान करने की उम्मीद की जाती है। कोड को संक्षिप्त रखने के लिए, Faker लाइब्रेरी का उपयोग करके सभी डेटा को बेतरतीब ढंग से उत्पन्न किया जाएगा।

शुरू करने के लिए, मैं आरंभ करूँगा और फिर परियोजना के लिए एक खाली निर्देशिका खोलूँगा। अगला, मैं दो उप-निर्देशिकाएँ बनाऊँगा: पहली को बुलाया जाएगा

 authors_service
, और दूसरा
 posts_service
. इनमें से प्रत्येक निर्देशिका के अंदर, मैं 3 फाइलें बनाऊंगा:

1.

 app.py
: फ्लास्क ऐप के लिए मुख्य प्रवेश बिंदु, जो ऐप को परिभाषित करता है, मार्गों को सेट करता है, और उन मार्गों के लिए अनुरोध किए जाने पर बुलाए जाने वाले कार्यों को निर्दिष्ट करता है।

2.

 requirements.txt
: एक सादा पाठ फ़ाइल जो पायथन पैकेज को निर्दिष्ट करती है जो कि एप्लिकेशन को चलाने के लिए आवश्यक है।

3.

 Dockerfile
: एक टेक्स्ट फ़ाइल जिसमें डॉकर छवि बनाने के लिए निर्देश हैं, जो कि, जैसा कि ऊपर उल्लेख किया गया है, एक हल्का, स्टैंड-अलोन और निष्पादन योग्य पैकेज है जिसमें कोड, रनटाइम, लाइब्रेरी, पर्यावरण चर सहित एप्लिकेशन को चलाने के लिए आवश्यक सब कुछ शामिल है। और काफी कुछ और।

सभी में

 app.py
फ़ाइल, मैं वांछित तर्क के साथ एक फ्लास्क माइक्रोसेवा लागू करूँगा।

के लिए

 authors_service
, द
 app.py
फ़ाइल इस प्रकार दिखती है:

 import os import flask import requests from faker import Faker app = flask.Flask(__name__) @app.route( "/authors/<string:author_id>" , methods=[ "GET" ] )
def get_author_by_id ( author_id: str ):
 author = {        "id" : author_id,        "name" : Faker().name(),        "email" : Faker().email(),        "posts" : _get_authors_posts(author_id) }    return flask.jsonify(author) def _get_authors_posts ( author_id: str ):
 response = requests.get(        f' {os.environ[ "POSTS_SERVICE_URL" ]} / {author_id} '
 )    return response.json() if __name__ == "__main__" : app.run( host=os.environ[ 'SERVICE_HOST' ], port= int (os.environ[ 'SERVICE_PORT' ]) )


यह कोड एक फ्लास्क ऐप सेट करता है और समापन बिंदु पर GET अनुरोधों को संभालने के लिए एक मार्ग को परिभाषित करता है

 /authors/{author_id}
. जब इस समापन बिंदु तक पहुँचा जाता है, तो यह प्रदान की गई आईडी के साथ एक लेखक के लिए नकली डेटा उत्पन्न करता है और उस लेखक के लिए अलग-अलग पोस्ट सेवा से पदों की एक सूची प्राप्त करता है। यह तब फ्लास्क ऐप चलाता है, होस्टनाम और संबंधित पर्यावरण चर में निर्दिष्ट पोर्ट को सुनता है।

ध्यान दें कि उपरोक्त तर्क पर निर्भर करता है
 flask
,
 requests
और
 Faker
संकुल। इसे ध्यान में रखते हुए, मैं उन्हें लेखकों की सेवा में जोड़ दूँगा
 requirements.txt
फ़ाइल, इस प्रकार है:

 flask == 2 . 2 . 2
requests == 2 . 28 . 1
Faker == 15 . 3 . 4

ध्यान दें कि इस गाइड में संदर्भित किसी भी निर्भरता के लिए कोई विशिष्ट पैकेज वर्जनिंग आवश्यकताएं नहीं हैं। उपयोग किए गए संस्करण लेखन के समय नवीनतम उपलब्ध थे।

के लिए

 posts_service
,
 app.py
इस प्रकार दिखता है:

 import os import uuid from random import randint import flask from faker import Faker app = flask.Flask(__name__) @app.route( '/posts/<string:author_id>' , methods=[ 'GET' ] )
def get_posts_by_author_id ( author_id: str ):
 posts = [ {            "id:" : str (uuid.uuid4()),            "author_id" : author_id,            "title" : Faker().sentence(),            "body" : Faker().paragraph() }        for _ in range (randint( 1 , 5 )) ]    return flask.jsonify(posts) if __name__ == '__main__' : app.run( host=os.environ[ 'SERVICE_HOST' ], port= int (os.environ[ 'SERVICE_PORT' ]) )


इस कोड में, जब एक क्लाइंट (यानी

 authors_service
) मार्ग के लिए एक GET अनुरोध भेजता है
 /posts/{author_id}
, कार्यक्रम
 get_posts_by_author_id
निर्दिष्ट के साथ कहा जाता है
 author_id
एक पैरामीटर के रूप में। फ़ंक्शन फ़ेकर लाइब्रेरी का उपयोग करके लेखक द्वारा लिखी गई 1 से 5 पोस्ट के बीच नकली डेटा उत्पन्न करता है, और क्लाइंट को JSON प्रतिक्रिया के रूप में पोस्ट की सूची देता है।

मुझे पोस्ट सेवा में फ्लास्क और फ़ेकर पैकेज भी जोड़ने होंगे

 requirements.txt
फ़ाइल, इस प्रकार है:

 flask == 2 . 2 . 2
Faker == 15 . 3 . 4

इन सेवाओं को कंटेनरीकृत करने से पहले, आइए एक उदाहरण पर विचार करें कि मैं पहली बार में एक-दूसरे से अलगाव में उन्हें पैकेज और चलाना क्यों चाहूंगा।

दोनों सेवाएं पर्यावरण चर का उपयोग करती हैं

 SERVICE_HOST
और
 SERVICE_PORT
सॉकेट को परिभाषित करने के लिए जिस पर फ्लास्क सर्वर लॉन्च किया जाएगा। जबकि
 SERVICE_HOST
कोई समस्या नहीं है (एक ही होस्ट पर कई सेवाएं सुन सकती हैं),
 SERVICE_PORT
समस्याएँ पैदा कर सकता है। यदि मैं एक स्थानीय पायथन वातावरण में सभी निर्भरताएँ स्थापित करता और दोनों सेवाओं को चलाता, तो शुरू होने वाली पहली सेवा निर्दिष्ट पोर्ट का उपयोग करती, जिससे दूसरी सेवा क्रैश हो जाती क्योंकि यह उसी पोर्ट का उपयोग नहीं कर सकती थी। एक सरल समाधान अलग पर्यावरण चर का उपयोग करना है (उदाहरण के लिए,
 AUTHORS_SERVICE_PORT
और
 POSTS_SERVICE_PORT
) बजाय। हालाँकि, पर्यावरणीय बाधाओं के अनुकूल होने के लिए स्रोत कोड को संशोधित करना स्केलिंग करते समय जटिल हो सकता है।

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

 SERVICE_PORT
प्रत्येक सेवा के लिए एक अलग मूल्य के लिए पर्यावरण चर, और प्रत्येक सेवा अन्य सेवाओं के हस्तक्षेप के बिना अपने स्वयं के पोर्ट का उपयोग करने में सक्षम होगी।

सेवाओं को कंटेनरीकृत करने के लिए, मैं नाम की एक नई फ़ाइल बनाऊँगा
 Dockerfile
प्रत्येक सेवा की निर्देशिका में। इस फ़ाइल की सामग्री (दोनों सेवाओं के लिए) इस प्रकार हैं:

 FROM python: 3.8
RUN mkdir /app WORKDIR /app COPY requi rements.txt /app/
RUN pip install -r requi rements.txt
COPY . /app/ CMD [ "python" , "app.py" ]

यह

 Dockerfile
एक पायथन 3.8 मूल छवि का निर्माण करता है और कंटेनर में एप्लिकेशन के लिए एक निर्देशिका स्थापित करता है। यह फिर कॉपी करता है
 requirements.txt
फ़ाइल को होस्ट मशीन से कंटेनर में डालें और उस फ़ाइल में सूचीबद्ध निर्भरताओं को स्थापित करें। अंत में, यह होस्ट मशीन से शेष एप्लिकेशन कोड को कंटेनर में कॉपी करता है और कंटेनर शुरू होने पर मुख्य एप्लिकेशन स्क्रिप्ट चलाता है।

आगे, मैं नाम की एक फ़ाइल बनाऊँगा

 docker-compose.yml
रूट प्रोजेक्ट डायरेक्टरी में। जैसा कि संक्षेप में ऊपर उल्लेख किया गया है, इस फ़ाइल का उपयोग मल्टी-कंटेनर डॉकर एप्लिकेशन को परिभाषित करने और चलाने के लिए किया जाता है। में
 docker-compose.yml
फ़ाइल, मैं उन सेवाओं को परिभाषित कर सकता हूं जो एप्लिकेशन बनाती हैं, उनके बीच निर्भरता निर्दिष्ट करती हैं, और कॉन्फ़िगर करती हैं कि उन्हें कैसे बनाया और चलाया जाना चाहिए। इस मामले में, यह इस प्रकार दिखता है:

 ---
# Specify the version of the Docker Compose file format
version: '3.9'
services:
  # Define the authors_service service
  authors_service:
    # This service relies on, and is therefor dependent on, the below `posts_service` service
    depends_on:
      - posts_service
    # Specify the path to the Dockerfile for this service
    build:
      context: ./authors_service
      dockerfile: Dockerfile
    # Define environment variables for this service
    environment:
      - SERVICE_HOST=0.0.0.0
      - PYTHONPATH=/app
      - SERVICE_PORT=5000
      - POSTS_SERVICE_URL=http://posts_service:6000/posts
    # Map port 5000 on the host machine to port 5000 on the container
    ports:
      - "5000:5000"
    # Mount the authors_service source code directory on the host to the working directory on the container
    volumes:
      - ./authors_service:/app
  # Define the posts_service service
  posts_service:
    # Specify the path to the Dockerfile for this service
    build:
      context: ./posts_service
      dockerfile: Dockerfile
    # Define environment variables for this service
    environment:
      - PYTHONPATH=/app
      - SERVICE_HOST=0.0.0.0
      - SERVICE_PORT=6000
    # Mount the posts_service source code directory on the host to the working directory on the container
    volumes:
      - ./posts_service:/app


एप्लिकेशन चलाना

कंटेनरों के साथ शुरू किया जा सकता है

 docker-compose up
आज्ञा। पहली बार इसे चलाने पर डॉकर इमेज अपने आप बन जाएगी।

यह "रन" की पहली उपरोक्त मूल आवश्यकता को पूरा करता है।

पुनर्तैनाती

ध्यान दें कि में

 docker-compose.yml
फ़ाइल, वॉल्यूम माउंट का उपयोग स्रोत कोड निर्देशिकाओं को साझा करने के लिए किया जाता है
 authors_service
और
 posts_service
मेजबान मशीन और कंटेनरों के बीच सेवाएं। यह कंटेनरों (और इसके विपरीत) में स्वचालित रूप से परिलक्षित परिवर्तनों के साथ होस्ट मशीन पर कोड को संपादित करने की अनुमति देता है।

उदाहरण के लिए, निम्न पंक्ति माउंट करती है

 ./authors_service
होस्ट मशीन पर निर्देशिका को
 /app
निर्देशिका में
 authors_service
कंटेनर:

 volumes: - . /authors_service:/ app

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

डिबगिंग

यहीं पर यह थोड़ा और जुड़ जाता है। पायथन में डिबगर्स दुभाषिया द्वारा प्रदान किए गए डिबगिंग टूल का उपयोग प्रोग्राम के निष्पादन को रोकने के लिए करते हैं और कुछ बिंदुओं पर इसकी स्थिति का निरीक्षण करते हैं। इसमें ट्रेस फ़ंक्शन सेट करना शामिल है

 sys.settrace()
कोड की प्रत्येक पंक्ति पर और ब्रेकप्वाइंट के लिए जाँच, साथ ही कॉल स्टैक और चर निरीक्षण जैसी सुविधाओं का उपयोग करना। एक कंटेनर के अंदर चलने वाले पायथन दुभाषिया को डिबग करना संभावित रूप से एक मेजबान मशीन पर चल रहे पायथन दुभाषिया को डीबग करने की तुलना में जटिलता जोड़ सकता है। ऐसा इसलिए है क्योंकि कंटेनर पर्यावरण होस्ट मशीन से अलग है।

इसे दूर करने के लिए, निम्नलिखित दो सामान्य ट्रैक्स में से एक लिया जा सकता है: कोड को कंटेनर के भीतर से ही डीबग किया जा सकता है, या इसे रिमोट डीबग सर्वर का उपयोग करके डीबग किया जा सकता है।

सबसे पहले, मैं VSCode का उपयोग पसंद के संपादक के रूप में यह प्रदर्शित करने के लिए करूँगा कि इसके बारे में कैसे जाना जाए। बाद में, मैं समझाऊंगा कि कैसे JetBrains PyCharm के साथ इसी तरह काम करना है।

कंटेनर के भीतर से ही कोड डिबग करना

VSCode का उपयोग करके चल रहे डॉकटर कंटेनर के भीतर से कोड विकसित और डिबग करने के लिए, मैं:

1. सुनिश्चित करें कि VSCode के लिए डॉकर एक्सटेंशन स्थापित और सक्षम है।

2. सुनिश्चित करें कि मैं जिस कंटेनर से जुड़ना चाहता हूं वह ऊपर और चल रहा है।

3. बाएं साइडबार में डॉकर आइकन पर क्लिक करके डॉकर एक्सटेंशन का एक्सप्लोरर व्यू खोलें।

4. एक्सप्लोरर दृश्य में, "चल रहे कंटेनर" अनुभाग का विस्तार करें और उस कंटेनर का चयन करें जिससे मैं संलग्न करना चाहता हूं।

5. कंटेनर पर राइट-क्लिक करें और संदर्भ मेनू से "विज़ुअल स्टूडियो कोड संलग्न करें" विकल्प चुनें।

यह विज़ुअल स्टूडियो कोड को चयनित कंटेनर से जोड़ देगा और कंटेनर के भीतर एक नई VSCode विंडो खोलेगा। इस नई विंडो में, मैं कोड लिख, चला और डिबग कर सकता हूं जैसा कि मैं आमतौर पर स्थानीय वातावरण पर करता हूं।

कंटेनर के पुनरारंभ होने पर हर बार पायथन जैसे VSCode एक्सटेंशन को स्थापित करने से बचने के लिए, मैं कंटेनर के अंदर एक वॉल्यूम माउंट कर सकता हूं जो VSCode एक्सटेंशन को स्टोर करता है। इस तरह, जब कंटेनर को पुनरारंभ किया जाता है, तब भी एक्सटेंशन उपलब्ध रहेंगे क्योंकि वे होस्ट मशीन पर संग्रहीत हैं। इस डेमो प्रोजेक्ट में डॉकर कंपोज़ का उपयोग करके ऐसा करने के लिए,

 docker-compose.yml
फ़ाइल को निम्नानुसार संशोधित किया जा सकता है:

 ---
# Specify the version of the Docker Compose file format
version: '3.9'
services:
  # Define the authors_service service
  authors_service:
    ...
    # Mount the authors_service source code directory on the host to the working directory on the container
    volumes:
      - ./authors_service:/app
      # Mount the vscode extension directory on the host to the vscode extension directory on the container
      - /path/to/host/extensions:/root/.vscode/extensions
  # Define the posts_service service
  posts_service:
    ...

ध्यान दें कि VSCode एक्सटेंशन आमतौर पर यहां पाए जा सकते हैं

 ~/.vscode/extensions
Linux और macOS पर, या
 %USERPROFILE%\.vscode\extensions
विंडोज पर।

रिमोट पायथन डीबग सर्वर का उपयोग करना

डिबगिंग की उपरोक्त विधि स्टैंडअलोन स्क्रिप्ट या लिखने, चलाने और डिबगिंग परीक्षणों के लिए अच्छी तरह से काम करती है। हालाँकि, विभिन्न कंटेनरों में चल रही कई सेवाओं से जुड़े तार्किक प्रवाह को डीबग करना अधिक जटिल है।

जब एक कंटेनर शुरू किया जाता है, तो उसमें मौजूद सेवा आमतौर पर तुरंत शुरू हो जाती है। इस स्थिति में, दोनों सेवाओं पर फ्लास्क सर्वर पहले से ही VSCode संलग्न होने के समय से चल रहे हैं, इसलिए "रन और डिबग" पर क्लिक करना और फ्लास्क सर्वर का एक और उदाहरण लॉन्च करना व्यावहारिक नहीं है क्योंकि इसके परिणामस्वरूप एक ही सेवा के कई उदाहरण चलेंगे एक ही कंटेनर पर और एक दूसरे के साथ प्रतिस्पर्धा, जो आमतौर पर एक विश्वसनीय डिबगिंग प्रवाह नहीं है।

यह मुझे विकल्प संख्या दो पर लाता है; एक दूरस्थ पायथन डिबग सर्वर का उपयोग करना। एक दूरस्थ पायथन डिबग सर्वर एक पायथन दुभाषिया है जो एक दूरस्थ होस्ट पर चल रहा है और एक डीबगर से कनेक्शन स्वीकार करने के लिए कॉन्फ़िगर किया गया है। यह एक डिबगर के उपयोग की अनुमति देता है जो स्थानीय रूप से चल रहा है, एक दूरस्थ वातावरण पर चलने वाली पायथन प्रक्रिया की जांच और नियंत्रण करने के लिए।

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

आरंभ करने के लिए, पहला कदम डीबगी पैकेज को इसमें जोड़ना है

 requirements.txt
दोनों सेवाओं के लिए फ़ाइलें। डिबगपी एक उच्च-स्तरीय, ओपन-सोर्स पायथन डिबगर है जिसका उपयोग स्थानीय या दूरस्थ रूप से पायथन प्रोग्राम को डीबग करने के लिए किया जा सकता है। मैं दोनों के लिए निम्न पंक्ति जोड़ दूँगा
 requirements.txt
फ़ाइलें:

 debugpy == 1 . 6 . 4

अब मुझे प्रत्येक सेवा के लिए डॉकर छवियों पर डिबगपी स्थापित करने के लिए छवियों को पुनर्निर्माण करने की आवश्यकता है। मैं चलाऊंगा

 docker-compose build
ऐसा करने की आज्ञा। तो मैं दौड़ूंगा
 docker-compose up
कंटेनरों को लॉन्च करने के लिए।

इसके बाद, मैं VSCode को रनिंग कंटेनर से जोड़ूंगा जिसमें वह प्रक्रिया है जिसे मैं डीबग करना चाहता हूं, जैसा कि मैंने ऊपर किया था।

चल रहे पायथन एप्लिकेशन में डीबगर संलग्न करने के लिए, मुझे उस बिंदु पर कोड में निम्न स्निपेट जोड़ना होगा जहां से मैं डीबगिंग शुरू करना चाहता हूं:

 import debugpy; debugpy.listen( 5678 )

यह स्निपेट डीबगपी मॉड्यूल आयात करता है और कॉल करता है

 listen
फ़ंक्शन, जो एक डिबगपी सर्वर शुरू करता है जो निर्दिष्ट पोर्ट नंबर (इस मामले में, 5678) पर डिबगर से कनेक्शन के लिए सुनता है।

अगर मैं डिबग करना चाहता था

 authors_service
, मैं उपरोक्त स्निपेट को ठीक पहले रख सकता हूं
 get_author_by_id
समारोह घोषणा के भीतर
 app.py
फ़ाइल - इस प्रकार है:

 import os import flask import requests from faker import Faker app = flask.Flask(__name__) import debugpy; debugpy.listen( 5678 ) @app.route( "/authors/<string:author_id>" , methods=[ "GET" ] )
def get_author_by_id ( author_id: str ):
...

यह एप्लिकेशन स्टार्टअप पर एक डिबगपी सर्वर शुरू करेगा

 app.py
स्क्रिप्ट निष्पादित है

अगला कदम एप्लिकेशन को डिबग करने के लिए VSCode लॉन्च कॉन्फ़िगरेशन बनाना है। सेवा के लिए रूट डायरेक्टरी में जिसका कंटेनर मैंने संलग्न किया है (और जिस पर मैं VSCode विंडो चला रहा हूं), मैं नाम का एक फोल्डर बनाऊंगा

 .vscode
. फिर, इस फोल्डर के भीतर, मैं नाम की एक फाइल बनाऊंगा
 launch.json
, निम्नलिखित सामग्री के साथ:

 {    "version" : "0.2.0" ,    "configurations" : [ {            "name" : "Python: Remote Attach" ,            "type" : "python" ,            "request" : "attach" ,            "connect" : {                "host" : "localhost" ,                "port" : 5678
 } } ] }

यह कॉन्फ़िगरेशन निर्दिष्ट करता है कि VSCode को पोर्ट 5678 पर स्थानीय मशीन (यानी वर्तमान कंटेनर) पर चलने वाले पायथन डीबगर से जुड़ा होना चाहिए - जो महत्वपूर्ण रूप से कॉल करते समय निर्दिष्ट पोर्ट था।

 debugpy.listen
ऊपर समारोह।

फिर मैं सभी परिवर्तनों को सहेज लूंगा। डॉकर एक्सटेंशन के एक्सप्लोरर व्यू में, मैं वर्तमान में संलग्न कंटेनर पर राइट-क्लिक करूंगा और संदर्भ मेनू से "रीस्टार्ट कंटेनर" का चयन करूंगा (स्थानीय वीएससीओडी उदाहरण पर किया गया)। कंटेनर को पुनरारंभ करने के बाद, कंटेनर के भीतर VSCode विंडो एक डायलॉग प्रदर्शित करेगी जो पूछेगी कि क्या मैं विंडो को फिर से लोड करना चाहता हूं-सही उत्तर हां है।

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

 debugpy.listen
समारोह कहा जाता है। डीबग टैब में डीबगर नियंत्रण का उपयोग अब कोड के माध्यम से आगे बढ़ने, ब्रेकप्वाइंट सेट करने और चर का निरीक्षण करने के लिए किया जा सकता है।

यह उपरोक्त "डीबग" आवश्यकता को पूरा करता है।

Jetbrains Pycharm IDE के साथ दूरस्थ विकास और डिबगिंग

आधिकारिक डॉक्स के अनुसार, PyCharm का उपयोग करते समय इसके बारे में जाने के दो तरीके हैं: एक दुभाषिया को दूरस्थ दुभाषिया सुविधा और / या एक दूरस्थ डीबग सर्वर कॉन्फ़िगरेशन का उपयोग करके डॉकर छवि से पुनर्प्राप्त किया जा सकता है। ध्यान दें कि ये दो विकल्प परस्पर अनन्य नहीं हैं। मैं व्यक्तिगत रूप से मुख्य रूप से विकास के लिए दूरस्थ दुभाषिया सुविधा पर निर्भर करता हूं, और यदि आवश्यक हो तो दूरस्थ डीबग सर्वर कॉन्फ़िगरेशन का उपयोग करता हूं।



एक दूरस्थ दुभाषिया की स्थापना

PyCharm पर एक दूरस्थ दुभाषिया स्थापित करने के लिए, मैं:

1. IDE विंडो के निचले दाएं कोने में दुभाषिया टैब पॉप-अप मेनू पर क्लिक करें।

2. नया दुभाषिया जोड़ें पर क्लिक करें, और फिर पॉप अप मेनू से डॉकर कंपोज़ पर... चुनें।

3. अगली पॉप अप विंडो में, संबंधित डॉकर कंपोज़ फ़ाइल का चयन करें, और फिर ड्रॉपडाउन से संबंधित सेवा का चयन करें। PyCharm अब डॉकटर छवि से जुड़ने और उपलब्ध अजगर दुभाषियों को पुनः प्राप्त करने का प्रयास करेगा।

4. अगली विंडो में, उस अजगर दुभाषिया का चयन करें जिसका मैं उपयोग करना चाहता हूं (उदाहरण के लिए

 /usr/local/bin/python
). दुभाषिया चुने जाने के बाद, "बनाएँ" पर क्लिक करें।

PyCharm तब नए दुभाषिया को अनुक्रमित करेगा, जिसके बाद मैं हमेशा की तरह कोड चला या डिबग कर सकता हूं - जब भी मैं ऐसा करना चाहता हूं, तो PyCharm मेरे लिए पर्दे के पीछे की रचना को ऑर्केस्ट्रेट करेगा।

दूरस्थ डिबग सर्वर कॉन्फ़िगरेशन सेट करना

दूरस्थ डिबग सर्वर कॉन्फ़िगरेशन सेट करने के लिए, मुझे पहले प्रासंगिक में दो निर्भरताएँ जोड़ने की आवश्यकता है

 requirements.txt
फ़ाइल (ओं): pydevd , और pydevd_pycharm । ये ऊपर दिखाए गए डिबगपी पैकेज के कार्य के समान हैं, लेकिन, जैसा कि इसके नाम से पता चलता है, pydevd_pycharm विशेष रूप से PyCharm के साथ डिबगिंग के लिए डिज़ाइन किया गया है। इस डेमो प्रोजेक्ट के संदर्भ में, मैं दोनों में निम्नलिखित दो पंक्तियां जोड़ूंगा
 requirements.txt
फ़ाइलें:

 pydevd ~= 2 . 9 . 1
pydevd -pycharm== 223 . 8214 . 17

एक बार यह हो जाने के बाद और डॉकर छवियों को फिर से बनाया गया है, फिर मैं कोड में निम्न कोड स्निपेट को कोड में उस बिंदु पर एक pydevd_pycharm डीबग सर्वर शुरू करने के लिए एम्बेड कर सकता हूं जिससे मैं डिबगिंग शुरू करना चाहता हूं:

 import pydevd_pycharm; pydevd_pycharm.settrace( 'host.docker.internal' , 5678 )

ध्यान दें कि डीबगपी के विपरीत, यहां मैंने "host.docker.internal" मान के साथ एक होस्टनाम पता निर्दिष्ट किया है, जो एक DNS नाम है जो होस्ट मशीन के आंतरिक आईपी पते को डॉकर कंटेनर के भीतर हल करता है। ऐसा इसलिए है क्योंकि मैं कंटेनर पर PyCharm नहीं चला रहा हूं; इसके बजाय, मैं होस्ट मशीन के पोर्ट 5678 पर सुनने के लिए डिबग सर्वर को प्रभावी ढंग से कॉन्फ़िगर कर रहा हूं।

यह विकल्प डिबगपी के साथ भी मौजूद है, लेकिन उस मामले में मैं कंटेनर पर ही VSCode का एक उदाहरण चला रहा था, इसने चीजों को सरल बना दिया ताकि होस्टनाम पता डिफ़ॉल्ट रूप से "लोकलहोस्ट" (यानी कंटेनर का लूपबैक इंटरफ़ेस ही हो, न कि मेजबान मशीन)।

अंतिम चरण एक रन कॉन्फ़िगरेशन सेट करना है जिसे PyCharm दूरस्थ डिबग सर्वर से कनेक्ट करने के लिए उपयोग कर सकता है।

ऐसा करने के लिए, मैं:

1. मुख्य मेनू से रन > एडिट कॉन्फ़िगरेशन का चयन करके रन/डीबग कॉन्फ़िगरेशन डायलॉग खोलें।

2. डायलॉग के ऊपरी-बाएँ कोने में + बटन पर क्लिक करें और ड्रॉप-डाउन मेनू से Python Remote Debug चुनें।

3. नाम फ़ील्ड में, रन कॉन्फ़िगरेशन के लिए एक नाम दर्ज करें।

4. स्क्रिप्ट पथ फ़ील्ड में, उस स्क्रिप्ट का पथ निर्दिष्ट करें जिसे मैं डीबग करना चाहता हूं।

5. होस्ट फ़ील्ड में, होस्ट मशीन का IP पता दर्ज करें जहाँ डिबगर सर्वर चलेगा। इस उदाहरण में, यह "लोकलहोस्ट" है।

6. पोर्ट फ़ील्ड में, वह पोर्ट नंबर दर्ज करें जिस पर डीबगर सर्वर सुनेगा। इस उदाहरण में, यह 5678 है।

7. पाथ मैपिंग सेक्शन में, मैं यह निर्दिष्ट कर सकता हूं कि होस्ट मशीन के पथ कंटेनर के भीतर पथों को कैसे मैप करते हैं। यह उपयोगी है अगर मैं डिबगिंग कोड हूं जो होस्ट से कंटेनर में आरोहित है, क्योंकि पथ दोनों वातावरणों में समान नहीं हो सकते हैं। इस उदाहरण में, मैं मैप करना चाहता हूँ

 path/to/project/on/host/authors_service
मेजबान मशीन पर, करने के लिए
 /app
लेखकों_सेवा को डिबग करने के लिए कंटेनर में, या
 path/to/project/on/host/posts_service
को
 /app
डिबगिंग के लिए कंटेनर पर post_service (इन्हें दो अलग-अलग रन कॉन्फ़िगरेशन की आवश्यकता होगी)।

8. रन कॉन्फिगरेशन को सेव करने के लिए ओके पर क्लिक करें।

डिबगिंग शुरू करने के लिए, मैं रन ड्रॉप-डाउन मेनू से उपरोक्त रन कॉन्फ़िगरेशन का चयन करूँगा और डीबग बटन पर क्लिक करूँगा, और फिर संबंधित कंटेनर को

 docker-compose up
आज्ञा। PyCharm डिबगर स्क्रिप्ट से जुड़ जाएगा और उस लाइन पर निष्पादन को रोक देगा जहां
 pydevd_pycharm.settrace
फ़ंक्शन को कॉल किया जाता है, जिससे मुझे उन बग्स को तोड़ना शुरू करने की अनुमति मिलती है।

संक्षेप में

इस गाइड में मैंने एक सामान्य, फिर भी व्यावहारिक अवलोकन दिया है कि कंटेनरीकृत अजगर विकास वातावरण क्या हैं, वे क्यों उपयोगी हैं, और उनका उपयोग करके अजगर कोड लिखने, तैनात करने और डीबग करने के बारे में कैसे जाना जाए। कृपया ध्यान दें कि यह किसी भी तरह से इन वातावरणों के साथ काम करने के लिए एक व्यापक मार्गदर्शिका नहीं है। यह केवल एक प्रारंभिक बिंदु है जहाँ से विस्तार करना है। इसके लिए यहां कुछ उपयोगी लिंक दिए गए हैं:

1. रेडहैट द्वारा कंटेनरीकरण का अवलोकन

3. आधिकारिक डॉकर डॉक्स

4. रिमोट डिबगिंग के लिए आधिकारिक जेटब्रेन पाइचार्म डॉक्स

5. देव कंटेनरों पर पायथन विकसित करने के लिए आधिकारिक VSCode डॉक्स

मुझे आशा है कि आपको यह मार्गदर्शिका मददगार लगी होगी - पढ़ने के लिए धन्यवाद!