পাইথনের সাথে ইনারলুপ ডেভেলপমেন্ট

১. সংক্ষিপ্ত বিবরণ

এই ল্যাবটি এমন সব ফিচার ও সক্ষমতা প্রদর্শন করে, যা কন্টেইনারাইজড পরিবেশে পাইথন অ্যাপ্লিকেশন তৈরির দায়িত্বে থাকা সফটওয়্যার ইঞ্জিনিয়ারদের জন্য ডেভেলপমেন্ট ওয়ার্কফ্লোকে সহজ ও সাবলীল করার উদ্দেশ্যে ডিজাইন করা হয়েছে। সাধারণ কন্টেইনার ডেভেলপমেন্টের জন্য ব্যবহারকারীকে কন্টেইনার এবং কন্টেইনার বিল্ড প্রসেসের খুঁটিনাটি বিষয়গুলো বুঝতে হয়। এছাড়াও, ডেভেলপারদের প্রায়শই তাদের কাজের ধারাবাহিকতা ভেঙে দূরবর্তী পরিবেশে অ্যাপ্লিকেশন পরীক্ষা ও ডিবাগ করার জন্য IDE থেকে বেরিয়ে যেতে হয়। এই টিউটোরিয়ালে উল্লিখিত টুলস এবং প্রযুক্তিগুলোর সাহায্যে ডেভেলপাররা তাদের IDE না ছেড়েই কন্টেইনারাইজড অ্যাপ্লিকেশন নিয়ে কার্যকরভাবে কাজ করতে পারবেন।

আপনি যা শিখবেন

এই ল্যাবে আপনি GCP-তে কন্টেইনার ব্যবহার করে ডেভেলপ করার পদ্ধতিগুলো শিখবেন, যার মধ্যে অন্তর্ভুক্ত রয়েছে:

  • একটি নতুন পাইথন স্টার্টার অ্যাপ্লিকেশন তৈরি করা
  • উন্নয়ন প্রক্রিয়াটি ধাপে ধাপে বর্ণনা করুন
  • একটি সহজ CRUD রেস্ট সার্ভিস তৈরি করুন

২. সেটআপ এবং প্রয়োজনীয়তা

স্ব-গতিতে পরিবেশ সেটআপ

  1. Google Cloud Console- এ সাইন-ইন করুন এবং একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন। যদি আপনার আগে থেকে Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তবে আপনাকে অবশ্যই একটি তৈরি করতে হবে।

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • প্রজেক্টের নামটি হলো এই প্রজেক্টের অংশগ্রহণকারীদের প্রদর্শিত নাম। এটি একটি ক্যারেক্টার স্ট্রিং যা গুগল এপিআই ব্যবহার করে না, এবং আপনি যেকোনো সময় এটি আপডেট করতে পারেন।
  • সমস্ত গুগল ক্লাউড প্রজেক্ট জুড়ে প্রজেক্ট আইডি অবশ্যই অনন্য হতে হবে এবং এটি অপরিবর্তনীয় (একবার সেট করার পর পরিবর্তন করা যায় না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত এটি কী তা নিয়ে আপনার মাথা ঘামানোর দরকার নেই। বেশিরভাগ কোডল্যাবে, আপনাকে প্রজেক্ট আইডি উল্লেখ করতে হবে (এবং এটি সাধারণত PROJECT_ID হিসাবে চিহ্নিত করা হয়), তাই যদি এটি আপনার পছন্দ না হয়, তবে এলোমেলোভাবে অন্য একটি তৈরি করুন, অথবা, আপনি নিজের আইডি দিয়ে চেষ্টা করে দেখতে পারেন যে সেটি উপলব্ধ আছে কিনা। এরপর প্রজেক্ট তৈরি হয়ে গেলে এটি "স্থির" হয়ে যায়।
  • তৃতীয় আরেকটি ভ্যালু আছে, যা হলো প্রজেক্ট নম্বর এবং কিছু এপিআই এটি ব্যবহার করে। এই তিনটি ভ্যালু সম্পর্কে আরও জানতে ডকুমেন্টেশন দেখুন।
  1. এরপরে, ক্লাউড রিসোর্স/এপিআই ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং চালু করতে হবে। এই কোডল্যাবটি সম্পন্ন করতে খুব বেশি খরচ হওয়ার কথা নয়, এমনকি আদৌ কোনো খরচ নাও হতে পারে। এই টিউটোরিয়ালের পর যাতে কোনো বিলিং না হয়, সেজন্য রিসোর্সগুলো বন্ধ করতে কোডল্যাবের শেষে দেওয়া যেকোনো "ক্লিন-আপ" নির্দেশাবলী অনুসরণ করুন। গুগল ক্লাউডের নতুন ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়াল প্রোগ্রামের জন্য যোগ্য।

ক্লাউডশেল এডিটর শুরু করুন

এই ল্যাবটি গুগল ক্লাউড শেল এডিটর-এর সাথে ব্যবহারের জন্য ডিজাইন ও পরীক্ষা করা হয়েছে। এডিটরটি অ্যাক্সেস করতে,

  1. আপনার গুগল প্রজেক্টটি https://console.cloud.google.com -এ অ্যাক্সেস করুন।
  2. উপরের ডান কোণায় ক্লাউড শেল এডিটর আইকনে ক্লিক করুন

8560cc8d45e8c112.png

  1. আপনার জানালার নিচের দিকে একটি নতুন কাচ খুলবে।
  2. ওপেন এডিটর বোতামে ক্লিক করুন

9e504cb98a6a8005.png

  1. এডিটরটি ডানদিকে একটি এক্সপ্লোরার এবং মাঝখানে এডিটর সহ খুলবে।
  2. স্ক্রিনের নীচে একটি টার্মিনাল পেইনও থাকা উচিত।
  3. টার্মিনাল খোলা না থাকলে, নতুন টার্মিনাল উইন্ডো খোলার জন্য `ctrl+` কী-সংমিশ্রণটি ব্যবহার করুন।

পরিবেশ সেটআপ

ক্লাউড শেলে, আপনার প্রজেক্টের জন্য প্রজেক্ট আইডি এবং প্রজেক্ট নম্বর সেট করুন। এগুলোকে PROJECT_ID এবং PROJECT_ID ভেরিয়েবল হিসেবে সংরক্ষণ করুন।

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
    --format='value(projectNumber)')

সোর্স কোডটি নিন

  1. এই ল্যাবের সোর্স কোডটি গিটহাবের GoogleCloudPlatform-এর `container-developer-workshop`-এ অবস্থিত। নিচের কমান্ডটি দিয়ে এটি ক্লোন করুন, তারপর ডিরেক্টরিতে প্রবেশ করুন।
git clone https://github.com/GoogleCloudPlatform/container-developer-workshop.git &&
cd container-developer-workshop/labs/python
mkdir music-service && cd music-service 
cloudshell workspace .

টার্মিনাল খোলা না থাকলে, নতুন টার্মিনাল উইন্ডো খোলার জন্য `ctrl+` কী-সংমিশ্রণটি ব্যবহার করুন।

এই ল্যাবে ব্যবহৃত অবকাঠামো সরবরাহ করুন।

এই ল্যাবে আপনি GKE-তে কোড ডেপ্লয় করবেন এবং স্প্যানার ডেটাবেসে সংরক্ষিত ডেটা অ্যাক্সেস করবেন। নিচের সেটআপ স্ক্রিপ্টটি আপনার জন্য এই পরিকাঠামো প্রস্তুত করে দেবে। প্রোভিশনিং প্রক্রিয়াটি সম্পন্ন হতে ১০ মিনিটের বেশি সময় লাগবে। সেটআপটি চলাকালীন আপনি পরবর্তী কয়েকটি ধাপ চালিয়ে যেতে পারেন।

../setup.sh

৩. একটি নতুন পাইথন স্টার্টার অ্যাপ্লিকেশন তৈরি করুন

  1. requirements.txt নামে একটি ফাইল তৈরি করুন এবং নিম্নলিখিত বিষয়বস্তুগুলো এর মধ্যে কপি করুন।
Flask
gunicorn
google-cloud-spanner
ptvsd==4.3.2
  1. app.py নামে একটি ফাইল তৈরি করুন এবং এতে নিম্নলিখিত কোডটি পেস্ট করুন।
import os
from flask import Flask, request, jsonify
from google.cloud import spanner

app = Flask(__name__)

@app.route("/")
def hello_world():
    message="Hello, World!"
    return message

if __name__ == '__main__':
    server_port = os.environ.get('PORT', '8080')
    app.run(debug=False, port=server_port, host='0.0.0.0')

  1. Dockerfile নামে একটি ফাইল তৈরি করুন এবং এর মধ্যে নিম্নলিখিত বিষয়বস্তু পেস্ট করুন।
FROM python:3.8
ARG FLASK_DEBUG=0
ENV FLASK_DEBUG=$FLASK_DEBUG
ENV FLASK_APP=app.py
WORKDIR /app
COPY requirements.txt .
RUN pip install --trusted-host pypi.python.org -r requirements.txt
COPY . .
ENTRYPOINT ["python3", "-m", "flask", "run", "--port=8080", "--host=0.0.0.0"]

দ্রষ্টব্য : FLASK_DEBUG=1 একটি পাইথন ফ্লাস্ক অ্যাপে কোডের পরিবর্তনগুলো স্বয়ংক্রিয়ভাবে রিলোড করতে দেয়। এই ডকারফাইলটি আপনাকে এই মানটিকে একটি বিল্ড আর্গুমেন্ট হিসেবে পাস করার সুযোগ দেয়।

ম্যানিফেস্ট তৈরি করুন

আপনার টার্মিনালে একটি ডিফল্ট skaffold.yaml এবং deployment.yaml ফাইল তৈরি করতে নিম্নলিখিত কমান্ডটি চালান।

  1. নিম্নলিখিত কমান্ডের সাহায্যে Skaffold চালু করুন।
skaffold init --generate-manifests

নির্দেশিত হলে কার্সার সরাতে অ্যারো কী এবং অপশনগুলো নির্বাচন করতে স্পেসবার ব্যবহার করুন।

বেছে নিন:

  • বন্দরের জন্য 8080
  • কনফিগারেশন সংরক্ষণ করতে y চাপুন

স্ক্যাফোল্ড কনফিগারেশন আপডেট করুন

  • ডিফল্ট অ্যাপ্লিকেশনের নাম পরিবর্তন করুন
  • skaffold.yaml খুলুন
  • বর্তমানে dockerfile-image হিসেবে সেট করা ইমেজের নামটি নির্বাচন করুন।
  • ডান ক্লিক করুন এবং সমস্ত ঘটনা পরিবর্তন করুন নির্বাচন করুন
  • নতুন নামটি python-app হিসেবে টাইপ করুন।
  • বিল্ড বিভাগটি আরও সম্পাদনা করুন
  • FLASK_DEBUG=1 পাস করার জন্য docker.buildArgs যোগ করুন
  • IDE থেকে চলমান কন্টেইনারে *.py ফাইলগুলির যেকোনো পরিবর্তন লোড করতে সেটিংস সিঙ্ক করুন।

সম্পাদনাগুলোর পর, skaffold.yaml ফাইলের বিল্ড সেকশনটি নিম্নরূপ হবে:

build:
 artifacts:
 - image: python-app
   docker:
     buildArgs:
       FLASK_DEBUG: 1
     dockerfile: Dockerfile
   sync:
     infer:
     - '**/*.py'

কুবারনেটিস কনফিগারেশন ফাইল পরিবর্তন করুন

  1. ডিফল্ট নাম পরিবর্তন করুন
  • deployment.yaml ফাইলটি খুলুন
  • বর্তমানে dockerfile-image হিসেবে সেট করা ইমেজের নামটি নির্বাচন করুন।
  • ডান ক্লিক করুন এবং সমস্ত ঘটনা পরিবর্তন করুন নির্বাচন করুন
  • নতুন নামটি python-app হিসেবে টাইপ করুন।

৪. উন্নয়ন প্রক্রিয়াটি পর্যালোচনা করা

বিজনেস লজিক যোগ করার পর আপনি এখন আপনার অ্যাপ্লিকেশনটি ডেপ্লয় এবং টেস্ট করতে পারবেন। পরবর্তী অংশে ক্লাউড কোড প্লাগইনের ব্যবহার তুলে ধরা হবে। অন্যান্য কাজের পাশাপাশি, এই প্লাগইনটি আপনার ডেভেলপমেন্ট প্রক্রিয়াকে আরও সহজ করতে স্ক্যাফোল্ডের সাথে ইন্টিগ্রেট করে। পরবর্তী ধাপগুলোতে যখন আপনি GKE-তে ডেপ্লয় করবেন, ক্লাউড কোড এবং স্ক্যাফোল্ড স্বয়ংক্রিয়ভাবে আপনার কন্টেইনার ইমেজ বিল্ড করবে, সেটিকে একটি কন্টেইনার রেজিস্ট্রি-তে পুশ করবে এবং তারপর আপনার অ্যাপ্লিকেশনটি GKE-তে ডেপ্লয় করবে। এই পুরো প্রক্রিয়াটি নেপথ্যে সম্পন্ন হয়, যা ডেভেলপারের কাজের ধারা থেকে এর খুঁটিনাটি বিষয়গুলো আড়াল করে রাখে।

কুবারনেটিসে ডিপ্লয় করুন

  1. Cloud Shell Editor-এর নিচের প্যানে, Cloud Code নির্বাচন করুন।

fdc797a769040839.png

  1. উপরে প্রদর্শিত প্যানেলে, ‘Run on Kubernetes ’ নির্বাচন করুন। অনুরোধ করা হলে, বর্তমান Kubernetes কনটেক্সট ব্যবহার করার জন্য ‘Yes’ নির্বাচন করুন।

cfce0d11ef307087.png

এই কমান্ডটি সোর্স কোডের একটি বিল্ড শুরু করে এবং তারপর টেস্টগুলো চালায়। বিল্ড এবং টেস্টগুলো চলতে কয়েক মিনিট সময় লাগবে। এই টেস্টগুলোর মধ্যে ইউনিট টেস্ট এবং একটি ভ্যালিডেশন ধাপ অন্তর্ভুক্ত রয়েছে, যা ডেপ্লয়মেন্ট এনভায়রনমেন্টের জন্য সেট করা নিয়মগুলো যাচাই করে। এই ভ্যালিডেশন ধাপটি আগে থেকেই কনফিগার করা থাকে, এবং এটি নিশ্চিত করে যে আপনি আপনার ডেভেলপমেন্ট এনভায়রনমেন্টে কাজ করার সময়েও ডেপ্লয়মেন্ট সংক্রান্ত সমস্যার সতর্কতা পাবেন।

  1. প্রথমবার কমান্ডটি চালালে স্ক্রিনের উপরে একটি প্রম্পট আসবে, যেখানে জিজ্ঞাসা করা হবে আপনি বর্তমান কুবারনেটিস কনটেক্সটটি চান কিনা। বর্তমান কনটেক্সটটি গ্রহণ ও ব্যবহার করতে 'Yes' নির্বাচন করুন।
  2. এরপর কোন কন্টেইনার রেজিস্ট্রি ব্যবহার করতে হবে তা জানতে চেয়ে একটি প্রম্পট প্রদর্শিত হবে। প্রদত্ত ডিফল্ট মানটি গ্রহণ করতে এন্টার চাপুন।
  3. অগ্রগতি এবং বিজ্ঞপ্তি দেখতে নিচের প্যানেলে আউটপুট ট্যাবটি নির্বাচন করুন।

f95b620569ba96c5.png

  1. কন্টেইনারগুলো থেকে সরাসরি সম্প্রচারিত অতিরিক্ত বিবরণ এবং লগ দেখতে ডানদিকের চ্যানেল ড্রপ-ডাউন থেকে 'Kubernetes: Run/Debug - Detailed' নির্বাচন করুন।

94acdcdda6d2108.png

বিল্ড এবং টেস্ট সম্পন্ন হলে, আউটপুট ট্যাবে লেখা থাকে: Attached debugger to container "python-app-8476f4bbc-h6dsl" successfully. , এবং http://localhost:8080 ইউআরএলটি তালিকাভুক্ত থাকে।

  1. ক্লাউড কোড টার্মিনালে, আউটপুটের প্রথম URL-টির (http://localhost:8080) উপর মাউস রাখুন এবং তারপরে যে টুল টিপটি প্রদর্শিত হবে, সেখান থেকে 'Open Web Preview' নির্বাচন করুন।
  2. একটি নতুন ব্রাউজার ট্যাব খুলবে এবং তাতে Hello, World! বার্তাটি প্রদর্শিত হবে।

হট রিলোড

  1. app.py ফাইলটি খুলুন
  2. শুভেচ্ছা বার্তাটি পরিবর্তন করে Hello from Python

অবিলম্বে লক্ষ্য করুন যে Output উইন্ডোর Kubernetes: Run/Debug ভিউতে, ওয়াচারটি Kubernetes-এর কন্টেইনারের সাথে আপডেট হওয়া ফাইলগুলো সিঙ্ক করে।

Update initiated
Build started for artifact python-app
Build completed for artifact python-app

Deploy started
Deploy completed

Status check started
Resource pod/python-app-6f646ffcbb-tn7qd status updated to In Progress
Resource deployment/python-app status updated to In Progress
Resource deployment/python-app status completed successfully
Status check succeeded
...
  1. আপনি যদি Kubernetes: Run/Debug - Detailed view-তে যান, তাহলে লক্ষ্য করবেন যে এটি ফাইলের পরিবর্তন শনাক্ত করে অ্যাপটি বিল্ড ও রিডিপ্লয় করে।
files modified: [app.py]
Syncing 1 files for gcr.io/veer-pylab-01/python-app:3c04f58-dirty@sha256:a42ca7250851c2f2570ff05209f108c5491d13d2b453bb9608c7b4af511109bd
Copying files:map[app.py:[/app/app.py]]togcr.io/veer-pylab-01/python-app:3c04f58-dirty@sha256:a42ca7250851c2f2570ff05209f108c5491d13d2b453bb9608c7b4af511109bd
Watching for changes...
[python-app] * Detected change in '/app/app.py', reloading
[python-app] * Restarting with stat
[python-app] * Debugger is active!
[python-app] * Debugger PIN: 744-729-662
  1. হালনাগাদ ফলাফল দেখতে আপনার ব্রাউজার রিফ্রেশ করুন।

ডিবাগিং

  1. ডিবাগ ভিউতে যান এবং বর্তমান থ্রেডটি বন্ধ করুন। 647213126d7a4c7b.png .
  2. অ্যাপ্লিকেশনটি debug মোডে চালানোর জন্য নিচের মেনুতে থাকা Cloud Code -এ ক্লিক করুন এবং Debug on Kubernetes নির্বাচন করুন।
  • Kubernetes Run/Debug - Detailed view of Output উইন্ডোতে লক্ষ্য করুন যে, skaffold এই অ্যাপ্লিকেশনটি ডিবাগ মোডে ডেপ্লয় করবে।
  1. প্রথমবার এটি চালানোর সময় একটি প্রম্পট জিজ্ঞাসা করবে যে কন্টেইনারের ভিতরে সোর্সটি কোথায় আছে। এই মানটি Dockerfile-এর ডিরেক্টরিগুলোর সাথে সম্পর্কিত।

ডিফল্ট গ্রহণ করতে এন্টার চাপুন।

583436647752e410.png

অ্যাপ্লিকেশনটি বিল্ড এবং ডেপ্লয় হতে কয়েক মিনিট সময় লাগবে।

  1. প্রক্রিয়াটি সম্পন্ন হলে, আপনি একটি ডিবাগার সংযুক্ত দেখতে পাবেন।
Port forwarding pod/python-app-8bd64cf8b-cskfl in namespace default, remote port 5678 -> http://127.0.0.1:5678
  1. নিচের স্ট্যাটাস বারটির রঙ নীল থেকে কমলায় পরিবর্তিত হলে তা ডিবাগ মোডে থাকার ইঙ্গিত দেয়।
  2. Kubernetes Run/Debug ভিউতে লক্ষ্য করুন যে একটি Debuggable কন্টেইনার চালু হয়েছে।
**************URLs*****************
Forwarded URL from service python-app: http://localhost:8080
Debuggable container started pod/python-app-8bd64cf8b-cskfl:python-app (default)
Update succeeded
***********************************

ব্রেকপয়েন্ট ব্যবহার করুন

  1. app.py ফাইলটি খুলুন
  2. যে স্টেটমেন্টটিতে return message লেখা আছে, সেটি খুঁজে বের করুন।
  3. লাইন নম্বরের বাম পাশের ফাঁকা জায়গায় ক্লিক করে ওই লাইনে একটি ব্রেকপয়েন্ট যোগ করুন। ব্রেকপয়েন্ট সেট করা হয়েছে তা বোঝাতে একটি লাল ইন্ডিকেটর দেখা যাবে।
  4. আপনার ব্রাউজারটি রিলোড করুন এবং লক্ষ্য করুন যে ডিবাগারটি ব্রেকপয়েন্টে প্রসেসটিকে থামিয়ে দেয় এবং আপনাকে GKE-তে দূরবর্তীভাবে চলমান অ্যাপ্লিকেশনটির ভেরিয়েবল ও অবস্থা খতিয়ে দেখার সুযোগ করে দেয়।
  5. VARIABLES বিভাগে ক্লিক করুন
  6. Locals-এ ক্লিক করুন, সেখানে আপনি "message" ভেরিয়েবলটি খুঁজে পাবেন।
  7. 'message' ভেরিয়েবল নামের উপর ডাবল ক্লিক করুন এবং পপ-আপে, মানটি পরিবর্তন করে "Greetings from Python"
  8. ডিবাগ কন্ট্রোল প্যানেলে থাকা কন্টিনিউ বাটনে ক্লিক করুন। 607c33934f8d6b39.png
  9. আপনার ব্রাউজারে প্রাপ্ত প্রতিক্রিয়াটি পর্যালোচনা করুন, যেখানে এখন আপনার এইমাত্র প্রবেশ করানো হালনাগাদ মানটি দেখাচ্ছে।
  10. স্টপ বাটন টিপে 'ডিবাগ' মোড বন্ধ করুন। 647213126d7a4c7b.png এবং ব্রেকপয়েন্টটিতে আবার ক্লিক করে সেটি সরিয়ে ফেলুন।

৫. একটি সহজ CRUD রেস্ট সার্ভিস তৈরি করা

এই পর্যায়ে আপনার অ্যাপ্লিকেশনটি কন্টেইনারাইজড ডেভেলপমেন্টের জন্য সম্পূর্ণরূপে কনফিগার করা হয়েছে এবং আপনি ক্লাউড কোড ব্যবহার করে বেসিক ডেভেলপমেন্ট ওয়ার্কফ্লোটি সম্পন্ন করেছেন। পরবর্তী বিভাগগুলিতে, আপনি গুগল ক্লাউডের একটি ম্যানেজড ডেটাবেসের সাথে সংযোগকারী রেস্ট সার্ভিস এন্ডপয়েন্ট যুক্ত করার মাধ্যমে আপনার শেখা বিষয়গুলো অনুশীলন করবেন।

রেস্ট সার্ভিস কোড করুন

নিচের কোডটি একটি সাধারণ রেস্ট সার্ভিস তৈরি করে, যা অ্যাপ্লিকেশনটির ডেটাবেস হিসেবে স্প্যানার (Spanner) ব্যবহার করে। নিচের কোডটি আপনার অ্যাপ্লিকেশনে কপি করে অ্যাপ্লিকেশনটি তৈরি করুন।

  1. app.py নিম্নলিখিত বিষয়বস্তু দিয়ে প্রতিস্থাপন করে মূল অ্যাপ্লিকেশনটি তৈরি করুন।
import os
from flask import Flask, request, jsonify
from google.cloud import spanner


app = Flask(__name__)


instance_id = "music-catalog"

database_id = "musicians"

spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)


@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

@app.route('/singer', methods=['POST'])
def create():
    try:
        request_json = request.get_json()
        singer_id = request_json['singer_id']
        first_name = request_json['first_name']
        last_name = request_json['last_name']
        def insert_singers(transaction):
            row_ct = transaction.execute_update(
                f"INSERT Singers (SingerId, FirstName, LastName) VALUES" \
                f"({singer_id}, '{first_name}', '{last_name}')"
            )
            print("{} record(s) inserted.".format(row_ct))

        database.run_in_transaction(insert_singers)

        return {"Success": True}, 200
    except Exception as e:
        return e



@app.route('/singer', methods=['GET'])
def get_singer():

    try:
        singer_id = request.args.get('singer_id')
        def get_singer():
            first_name = ''
            last_name = ''
            with database.snapshot() as snapshot:
                results = snapshot.execute_sql(
                    f"SELECT SingerId, FirstName, LastName FROM Singers " \
                    f"where SingerId = {singer_id}",
                    )
                for row in results:
                    first_name = row[1]
                    last_name = row[2]
                return (first_name,last_name )
        first_name, last_name = get_singer()  
        return {"first_name": first_name, "last_name": last_name }, 200
    except Exception as e:
        return e


@app.route('/singer', methods=['PUT'])
def update_singer_first_name():
    try:
        singer_id = request.args.get('singer_id')
        request_json = request.get_json()
        first_name = request_json['first_name']
        
        def update_singer(transaction):
            row_ct = transaction.execute_update(
                f"UPDATE Singers SET FirstName = '{first_name}' WHERE SingerId = {singer_id}"
            )

            print("{} record(s) updated.".format(row_ct))

        database.run_in_transaction(update_singer)
        return {"Success": True}, 200
    except Exception as e:
        return e


@app.route('/singer', methods=['DELETE'])
def delete_singer():
    try:
        singer_id = request.args.get('singer')
    
        def delete_singer(transaction):
            row_ct = transaction.execute_update(
                f"DELETE FROM Singers WHERE SingerId = {singer_id}"
            )
            print("{} record(s) deleted.".format(row_ct))

        database.run_in_transaction(delete_singer)
        return {"Success": True}, 200
    except Exception as e:
        return e

port = int(os.environ.get('PORT', 8080))
if __name__ == '__main__':
    app.run(threaded=True, host='0.0.0.0', port=port)

ডাটাবেস কনফিগারেশন যোগ করুন

স্প্যানারের সাথে নিরাপদে সংযোগ করতে, অ্যাপ্লিকেশনটিকে ওয়ার্কলোড আইডেন্টিটি ব্যবহার করার জন্য সেট আপ করুন। এটি আপনার অ্যাপ্লিকেশনকে নিজস্ব সার্ভিস অ্যাকাউন্ট হিসেবে কাজ করতে এবং ডেটাবেস অ্যাক্সেস করার সময় স্বতন্ত্র অনুমতি পেতে সক্ষম করে।

  1. deployment.yaml আপডেট করুন। ফাইলের শেষে নিম্নলিখিত কোডটি যোগ করুন (নিচের উদাহরণে দেওয়া ট্যাব ইন্ডেন্টগুলো অবশ্যই বজায় রাখবেন)।
      serviceAccountName: python-ksa
      nodeSelector:
        iam.gke.io/gke-metadata-server-enabled: "true" 

অ্যাপ্লিকেশন স্থাপন এবং যাচাই করুন

  1. Cloud Shell Editor-এর নিচের প্যানে Cloud Code নির্বাচন করুন, তারপর স্ক্রিনের উপরে Debug on Kubernetes নির্বাচন করুন।
  2. যখন বিল্ড এবং টেস্ট সম্পন্ন হয়, তখন আউটপুট ট্যাবে লেখা থাকে: Resource deployment/python-app status completed successfully , এবং একটি ইউআরএল তালিকাভুক্ত হয়: "Forwarded URL from service python-app: http://localhost:8080"
  3. দুটি এন্ট্রি যোগ করুন।

ক্লাউডশেল টার্মিনাল থেকে নিচের কমান্ডটি চালান।

curl -X POST http://localhost:8080/singer -H 'Content-Type: application/json' -d '{"first_name":"Cat","last_name":"Meow", "singer_id": 6}'
  1. টার্মিনালে নিচের কমান্ডটি চালিয়ে GET অনুরোধটি পরীক্ষা করুন।
curl -X GET http://localhost:8080/singer?singer_id=6
  1. টেস্ট ডিলিট: এখন নিচের কমান্ডটি চালিয়ে একটি এন্ট্রি ডিলিট করার চেষ্টা করুন। প্রয়োজনে আইটেম-আইডি (item-id)-এর মান পরিবর্তন করুন।
curl -X DELETE http://localhost:8080/singer?singer_id=6
    This throws an error message
500 Internal Server Error

সমস্যাটি চিহ্নিত করুন এবং সমাধান করুন

  1. ডিবাগ মোডে গিয়ে সমস্যাটি খুঁজে বের করুন। এখানে কিছু পরামর্শ দেওয়া হলো:
  • আমরা জানি DELETE-এ কোনো সমস্যা আছে, কারণ এটি কাঙ্ক্ষিত ফলাফল দিচ্ছে না। তাই আপনাকে app.py ফাইলের delete_singer মেথডে ব্রেকপয়েন্ট সেট করতে হবে।
  • ধাপে ধাপে প্রোগ্রামটি চালান এবং বাম দিকের উইন্ডোতে লোকাল ভেরিয়েবলগুলোর মান পর্যবেক্ষণ করতে প্রতিটি ধাপে ভেরিয়েবলগুলো লক্ষ্য করুন।
  • singer_id এবং request.args এর মতো নির্দিষ্ট মান পর্যবেক্ষণ করতে, এই ভেরিয়েবলগুলো ওয়াচ উইন্ডোতে যোগ করুন।
  1. লক্ষ্য করুন যে singer_id তে None মানটি নির্ধারিত আছে। সমস্যাটি সমাধান করতে কোডটি পরিবর্তন করুন।

সংশোধিত কোড স্নিপেটটি দেখতে এইরকম হবে।

@app.route('/delete-singer', methods=['DELETE', 'GET'])
def delete_singer():
    try:
        singer_id = request.args.get('singer_id')
  1. অ্যাপ্লিকেশনটি পুনরায় চালু করার পর, ডিলিট করার চেষ্টা করে আবার পরীক্ষা করুন।
  2. ডিবাগ টুলবারের লাল বর্গক্ষেত্রটিতে ক্লিক করে ডিবাগিং সেশনটি বন্ধ করুন। 647213126d7a4c7b.png

৬. পরিষ্কার-পরিচ্ছন্নতা

অভিনন্দন! এই ল্যাবে আপনি একেবারে শুরু থেকে একটি নতুন পাইথন অ্যাপ্লিকেশন তৈরি করেছেন এবং এটিকে কন্টেইনারের সাথে কার্যকরভাবে কাজ করার জন্য কনফিগার করেছেন। এরপর আপনি প্রচলিত অ্যাপ্লিকেশন স্ট্যাকে পাওয়া ডেভেলপার ফ্লো অনুসরণ করে আপনার অ্যাপ্লিকেশনটি একটি রিমোট GKE ক্লাস্টারে ডেপ্লয় ও ডিবাগ করেছেন।

ল্যাব শেষ করার পর পরিষ্কার করার জন্য:

  1. ল্যাবে ব্যবহৃত ফাইলগুলো মুছে ফেলুন।
cd ~ && rm -rf container-developer-workshop
  1. সম্পর্কিত সমস্ত অবকাঠামো ও রিসোর্স অপসারণ করতে প্রজেক্টটি ডিলিট করুন।