অ্যাপ ইঞ্জিন ব্লবস্টোর থেকে ক্লাউড স্টোরেজে স্থানান্তর করুন (মডিউল 16)

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

সার্ভারলেস মাইগ্রেশন স্টেশন সিরিজের কোডল্যাব (স্ব-গতিতে শেখার উপযোগী টিউটোরিয়াল) এবং সম্পর্কিত ভিডিওগুলোর লক্ষ্য হলো গুগল ক্লাউড সার্ভারলেস ডেভেলপারদের এক বা একাধিক মাইগ্রেশনের মাধ্যমে তাদের অ্যাপ্লিকেশনগুলোকে আধুনিক করে তুলতে সাহায্য করা, যার মূল উদ্দেশ্য হলো পুরোনো সার্ভিসগুলো থেকে সরে আসা। এটি আপনার অ্যাপগুলোকে আরও সহজে বহনযোগ্য করে তোলে এবং আপনাকে আরও বেশি বিকল্প ও নমনীয়তা দেয়, যার ফলে আপনি আরও বিস্তৃত পরিসরের ক্লাউড প্রোডাক্টের সাথে ইন্টিগ্রেট করতে ও সেগুলো ব্যবহার করতে পারেন এবং নতুন ল্যাঙ্গুয়েজ রিলিজে আরও সহজে আপগ্রেড করতে পারেন। যদিও প্রাথমিকভাবে এই সিরিজটি ক্লাউডের একেবারে প্রথম দিকের ব্যবহারকারী, অর্থাৎ অ্যাপ ইঞ্জিন (স্ট্যান্ডার্ড এনভায়রনমেন্ট) ডেভেলপারদের উপর দৃষ্টি নিবদ্ধ করে তৈরি, তবে এর পরিধি এতটাই বিস্তৃত যে এটি ক্লাউড ফাংশনস এবং ক্লাউড রান- এর মতো অন্যান্য সার্ভারলেস প্ল্যাটফর্ম বা প্রযোজ্য ক্ষেত্রে অন্য প্ল্যাটফর্মগুলোকেও অন্তর্ভুক্ত করতে পারে।

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

আরও ধাপে ধাপে তথ্যের জন্য যেকোনো সম্পর্কিত মাইগ্রেশন মডিউল দেখুন।

আপনি শিখবেন কিভাবে

  • অ্যাপ ইঞ্জিন ব্লবস্টোর এপিআই/লাইব্রেরির ব্যবহার যোগ করুন
  • ব্লবস্টোর পরিষেবাতে ব্যবহারকারীর আপলোডগুলি সংরক্ষণ করুন।
  • ক্লাউড স্টোরেজে স্থানান্তরের পরবর্তী পদক্ষেপের জন্য প্রস্তুতি নিন।

আপনার যা যা লাগবে

জরিপ

আপনি এই টিউটোরিয়ালটি কীভাবে ব্যবহার করবেন?

শুধু পুরোটা পড়ুন এটি পড়ুন এবং অনুশীলনগুলো সম্পূর্ণ করুন।

পাইথন নিয়ে আপনার অভিজ্ঞতাকে আপনি কীভাবে মূল্যায়ন করবেন?

শিক্ষানবিশ মধ্যবর্তী দক্ষ

গুগল ক্লাউড পরিষেবা ব্যবহারের অভিজ্ঞতাকে আপনি কীভাবে মূল্যায়ন করবেন?

শিক্ষানবিশ মধ্যবর্তী দক্ষ

২. পটভূমি

এই কোডল্যাবটি মডিউল ১৫-এর স্যাম্পল অ্যাপ দিয়ে শুরু হয়েছে এবং এতে দেখানো হয়েছে কীভাবে ব্লবস্টোর (এবং এনডিবি) থেকে ক্লাউড স্টোরেজ (এবং ক্লাউড এনডিবি)-তে মাইগ্রেট করতে হয়। এই মাইগ্রেশন প্রক্রিয়ায় অ্যাপ ইঞ্জিনের লিগ্যাসি বান্ডলড সার্ভিসগুলোর ওপর নির্ভরতা প্রতিস্থাপন করতে হয়, যা আপনাকে চাইলে আপনার অ্যাপগুলোকে অন্য কোনো ক্লাউড সার্ভারলেস প্ল্যাটফর্ম বা হোস্টিং প্ল্যাটফর্মে সরিয়ে নেওয়ার সুযোগ দেয়।

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

অ্যাপটি এখনও ব্যবহারকারীর 'ভিজিট' নথিভুক্ত করে এবং সাম্প্রতিকতম দশটি প্রদর্শন করে, কিন্তু পূর্ববর্তী (মডিউল ১৫) কোডল্যাবটি ব্লবস্টোর ব্যবহারের জন্য নতুন কার্যকারিতা যোগ করেছে: অ্যাপটি ব্যবহারকারীদের তাদের 'ভিজিট'-এর সাথে সম্পর্কিত একটি আর্টিফ্যাক্ট (একটি ফাইল) আপলোড করতে অনুরোধ করে। ব্যবহারকারীরা তা করতে পারেন অথবা এটি এড়িয়ে যেতে 'স্কিপ' নির্বাচন করতে পারেন। ব্যবহারকারীর সিদ্ধান্ত যাই হোক না কেন, পরবর্তী পৃষ্ঠাটি এই অ্যাপের পূর্ববর্তী সংস্করণগুলোর মতোই আউটপুট প্রদর্শন করে, যেখানে সাম্প্রতিকতম ভিজিটগুলো দেখানো হয়। একটি অতিরিক্ত বিশেষত্ব হলো, সংশ্লিষ্ট আর্টিফ্যাক্টসহ ভিজিটগুলোতে সেই ভিজিটের আর্টিফ্যাক্টটি দেখার জন্য একটি 'ভিউ' লিঙ্ক থাকে। এই কোডল্যাবটি পূর্বে উল্লিখিত মাইগ্রেশনগুলো বাস্তবায়ন করে এবং বর্ণিত কার্যকারিতা অক্ষুণ্ণ রাখে।

৩. প্রস্তুতি/পূর্বপ্রস্তুতি

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

১. প্রকল্প স্থাপন করুন

আপনি যদি ইতিমধ্যেই মডিউল ১৫ অ্যাপটি ডেপ্লয় করে থাকেন, তাহলে আমরা সেই একই প্রজেক্ট (এবং কোড) পুনরায় ব্যবহার করার পরামর্শ দিচ্ছি। বিকল্পভাবে, আপনি একটি সম্পূর্ণ নতুন প্রজেক্ট তৈরি করতে পারেন অথবা অন্য কোনো বিদ্যমান প্রজেক্ট পুনরায় ব্যবহার করতে পারেন। নিশ্চিত করুন যে প্রজেক্টটিতে একটি সক্রিয় বিলিং অ্যাকাউন্ট এবং অ্যাপ ইঞ্জিন চালু আছে।

২. বেসলাইন নমুনা অ্যাপটি নিন

এই কোডল্যাবটির একটি পূর্বশর্ত হলো একটি কার্যকর মডিউল ১৫ স্যাম্পল অ্যাপ থাকা। যদি আপনার কাছে এটি না থাকে, তবে আপনি মডিউল ১৫-এর "START" ফোল্ডার থেকে এটি সংগ্রহ করতে পারেন (লিঙ্ক নিচে দেওয়া আছে)। এই কোডল্যাবটি আপনাকে প্রতিটি ধাপের মধ্য দিয়ে নিয়ে যাবে এবং শেষে এমন কোড থাকবে যা মডিউল ১৬-এর "FINISH" ফোল্ডারের কোডের অনুরূপ।

মডিউল ১৫-এর প্রারম্ভিক ফাইলগুলোর ডিরেক্টরিটি দেখতে এইরকম হবে:

$ ls
README.md       app.yaml        main-gcs.py     main.py         templates

main-gcs.py ফাইলটি হলো মডিউল ১৫-এর main.py ফাইলের একটি বিকল্প সংস্করণ, যা প্রজেক্টের আইডি ( PROJECT_ID .appspot.com -এর উপর ভিত্তি করে অ্যাপের জন্য নির্ধারিত ডিফল্ট URL থেকে ভিন্ন একটি ক্লাউড স্টোরেজ বাকেট নির্বাচন করার সুযোগ দেয়। এই (মডিউল ১৬) কোডল্যাবে এই ফাইলটির কোনো ভূমিকা নেই, তবে ইচ্ছা করলে একই ধরনের মাইগ্রেশন কৌশল সেই ফাইলটিতেও প্রয়োগ করা যেতে পারে।

৩. বেসলাইন অ্যাপ (পুনরায়) স্থাপন করুন

এখন আপনার বাকি প্রস্তুতিমূলক ধাপগুলো সম্পন্ন করতে হবে:

  1. gcloud কমান্ড-লাইন টুলটির সাথে পুনরায় পরিচিত হয়ে নিন।
  2. gcloud app deploy ব্যবহার করে নমুনা অ্যাপটি পুনরায় ডিপ্লয় করুন।
  3. অ্যাপটি অ্যাপ ইঞ্জিনে কোনো সমস্যা ছাড়াই চলে কিনা তা নিশ্চিত করুন।

একবার আপনি সফলভাবে সেই ধাপগুলো সম্পন্ন করে আপনার মডিউল ১৫ অ্যাপটি কাজ করছে কিনা তা নিশ্চিত করলে, প্রাথমিক পৃষ্ঠাটি ব্যবহারকারীদের একটি ফর্ম দিয়ে স্বাগত জানাবে। এই ফর্মে একটি ভিজিট আর্টিফ্যাক্ট ফাইল আপলোড করার জন্য অনুরোধ করা হয় এবং এর সাথে অপ্ট-আউট করার জন্য একটি 'স্কিপ' বাটনও থাকে।

f5b5f9f19d8ae978.png

ব্যবহারকারীরা ফাইল আপলোড করলে বা এড়িয়ে গেলে, অ্যাপটি পরিচিত 'সর্বশেষ ভিজিট' পৃষ্ঠাটি প্রদর্শন করে:

f5ac6b98ee8a34cb.png

যেসব ভিজিটে কোনো আর্টিফ্যাক্ট দেখা যাবে, সেগুলোর ভিজিট টাইমস্ট্যাম্পের ডানদিকে আর্টিফ্যাক্টটি প্রদর্শন (বা ডাউনলোড) করার জন্য একটি "ভিউ" লিঙ্ক থাকবে। একবার আপনি অ্যাপটির কার্যকারিতা নিশ্চিত করলে, আপনি অ্যাপ ইঞ্জিনের পুরোনো পরিষেবাগুলো (webapp2, NDB, Blobstore) থেকে আধুনিক বিকল্পগুলোতে (Flask, Cloud NDB, Cloud Storage) স্থানান্তরিত হওয়ার জন্য প্রস্তুত।

৪. কনফিগারেশন ফাইল আপডেট করুন

আমাদের অ্যাপের আপডেট করা সংস্করণের জন্য তিনটি কনফিগারেশন ফাইল প্রয়োজন হয়। প্রয়োজনীয় কাজগুলো হলো:

  1. app.yaml এ প্রয়োজনীয় বিল্ট-ইন থার্ড-পার্টি লাইব্রেরিগুলো আপডেট করুন এবং সেইসাথে পাইথন ৩-এ মাইগ্রেশনের পথও খোলা রাখুন।
  2. একটি requirements.txt যোগ করুন, যেখানে বিল্ট-ইন নয় এমন সমস্ত প্রয়োজনীয় লাইব্রেরির উল্লেখ থাকবে।
  3. appengine_config.py ফাইলটি যোগ করুন, যাতে অ্যাপটি বিল্ট-ইন এবং নন-বিল্ট-ইন উভয় ধরনের থার্ড-পার্টি লাইব্রেরি সাপোর্ট করে।

app.yaml

libraries সেকশনটি আপডেট করে আপনার app.yaml ফাইলটি এডিট করুন। jinja2 সরিয়ে দিন এবং grpcio , setuptoolsssl যোগ করুন। তিনটি লাইব্রেরির জন্যই উপলব্ধ সর্বশেষ সংস্করণটি বেছে নিন। এছাড়াও Python 3 runtime ডিরেক্টিভটি যোগ করুন, কিন্তু কমেন্ট আউট করে রাখুন। কাজ শেষ হলে, এটি দেখতে এইরকম হবে (যদি আপনি Python 3.9 বেছে নিয়ে থাকেন):

পূর্বে:

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

libraries:
- name: jinja2
  version: latest

পরে:

#runtime: python39
runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

libraries:
- name: grpcio
  version: latest
- name: setuptools
  version: latest
- name: ssl
  version: latest

এই পরিবর্তনগুলো মূলত অ্যাপ ইঞ্জিন সার্ভারগুলোতে থাকা পাইথন ২-এর বিল্ট-ইন লাইব্রেরিগুলো সম্পর্কিত (যাতে আপনাকে এগুলো আলাদাভাবে বান্ডেল করতে না হয়)। আমরা জিনজা২ (Jinja2) সরিয়ে দিয়েছি কারণ এটি ফ্লাস্ক (Flask)-এর সাথেই আসে, যা আমরা reqs.txt ফাইলে যোগ করব। যখনই গুগল ক্লাউড ক্লায়েন্ট লাইব্রেরি, যেমন ক্লাউড এনডিবি (Cloud NDB) এবং ক্লাউড স্টোরেজ (Cloud Storage)-এর লাইব্রেরিগুলো ব্যবহার করা হয়, তখন grpcio এবং setuptools-এর প্রয়োজন হয়। সবশেষে, ক্লাউড স্টোরেজের জন্য ssl লাইব্রেরিটি প্রয়োজন। একদম উপরে কমেন্ট করে রাখা রানটাইম ডিরেক্টিভটি তখন ব্যবহার করতে হবে, যখন আপনি এই অ্যাপটিকে পাইথন ৩-এ পোর্ট করার জন্য প্রস্তুত হবেন। আমরা এই টিউটোরিয়ালের শেষে এই বিষয়টি নিয়ে আলোচনা করব।

requirements.txt

একটি requirements.txt ফাইল যোগ করুন, যেখানে Flask ফ্রেমওয়ার্ক এবং Cloud NDB ও Cloud Storage ক্লায়েন্ট লাইব্রেরিগুলো রিকোয়ার করা থাকবে, যেগুলোর কোনোটিই বিল্ট-ইন নয়। ফাইলটি নিম্নলিখিত কন্টেন্ট দিয়ে তৈরি করুন:

flask
google-cloud-ndb
google-cloud-storage

পাইথন ২ অ্যাপ ইঞ্জিন রানটাইমের জন্য বিল্ট-ইন নয় এমন থার্ড-পার্টি লাইব্রেরিগুলোর সেলফ-বান্ডলিং প্রয়োজন হয়, তাই এই লাইব্রেরিগুলো lib ফোল্ডারে ইনস্টল করতে নিম্নলিখিত কমান্ডটি চালান:

pip install -t lib -r requirements.txt

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

appengine_config.py

বিল্ট-ইন এবং নন-বিল্ট-ইন থার্ড-পার্টি লাইব্রেরি সমর্থন করে এমন একটি appengine_config.py ফাইল যোগ করুন। নিম্নলিখিত বিষয়বস্তু দিয়ে ফাইলটি তৈরি করুন:

import pkg_resources
from google.appengine.ext import vendor

# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
# Add libraries to pkg_resources working set to find the distribution.
pkg_resources.working_set.add_entry(PATH)

এইমাত্র সম্পন্ন করা ধাপগুলো অ্যাপ ইঞ্জিন ডক্স-এর 'Installing libraries for Python 2 apps' বিভাগে তালিকাভুক্ত ধাপগুলোর অনুরূপ বা অভিন্ন হওয়া উচিত, এবং আরও নির্দিষ্টভাবে বললে, appengine_config.py ফাইলের বিষয়বস্তু সেখানকার ধাপ ৫-এর সাথে মিলতে হবে।

কনফিগারেশন ফাইলগুলোর কাজ সম্পন্ন হয়েছে, এবার অ্যাপ্লিকেশনটির দিকে এগিয়ে যাওয়া যাক।

৫. অ্যাপ্লিকেশন ফাইলগুলি পরিবর্তন করুন

আমদানি

main.py এর প্রথম ধাপের পরিবর্তনগুলোর মধ্যে প্রতিস্থাপিত হতে যাওয়া সমস্ত কিছু অদলবদল করা অন্তর্ভুক্ত। নিচে যা যা পরিবর্তন হচ্ছে তা দেওয়া হলো:

  1. webapp2 Flask দ্বারা প্রতিস্থাপন করা হয়েছে
  2. webapp2_extras থেকে Jinja2 ব্যবহার করার পরিবর্তে, Flask-এর সাথে আসা Jinja2 ব্যবহার করুন।
  3. অ্যাপ ইঞ্জিন ব্লবস্টোর এবং এনডিবি-কে ক্লাউড এনডিবি এবং ক্লাউড স্টোরেজ দ্বারা প্রতিস্থাপন করা হয়েছে।
  4. webapp Blobstore হ্যান্ডলারগুলোকে io স্ট্যান্ডার্ড লাইব্রেরি মডিউল, Flask এবং werkzeug ইউটিলিটিগুলোর একটি সংমিশ্রণ দ্বারা প্রতিস্থাপন করা হয়েছে।
  5. ডিফল্টরূপে, Blobstore আপনার অ্যাপের URL ( PROJECT_ID.appspot.com ) নামে একটি ক্লাউড স্টোরেজ বাকেটে ডেটা লেখে। যেহেতু আমরা ক্লাউড স্টোরেজ ক্লায়েন্ট লাইব্রেরিতে পোর্ট করছি, তাই হুবহু একই বাকেট নামটি নির্দিষ্ট করার জন্য প্রজেক্ট আইডি পেতে google.auth ব্যবহার করা হয়। (আপনি বাকেট নামটি পরিবর্তন করতে পারেন, কারণ এটি এখন আর হার্ডকোড করা নেই।)

পূর্বে:

import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers

main.py ফাইলের বর্তমান ইম্পোর্ট সেকশনটি নিচের কোড স্নিপেট দিয়ে প্রতিস্থাপন করে উপরের তালিকায় থাকা পরিবর্তনগুলো প্রয়োগ করুন।

পরে:

import io

from flask import (Flask, abort, redirect, render_template,
        request, send_file, url_for)
from werkzeug.utils import secure_filename

import google.auth
from google.cloud import exceptions, ndb, storage

প্রারম্ভিকীকরণ এবং অপ্রয়োজনীয় জিনজা২ সমর্থন

এরপর যে কোড ব্লকটি প্রতিস্থাপন করতে হবে তা হলো webapp2_extras থেকে Jinja2-এর ব্যবহার নির্দিষ্টকারী BaseHandler । এটি অপ্রয়োজনীয়, কারণ Jinja2 Flask-এর সাথেই আসে এবং এটিই এর ডিফল্ট টেমপ্লেটিং ইঞ্জিন, তাই এটি সরিয়ে ফেলুন।

মডিউল ১৬-এর দিকে, আমরা এমন অবজেক্টগুলো ইনস্ট্যানশিয়েট করেছি যা আমাদের পুরোনো অ্যাপে ছিল না। এর মধ্যে রয়েছে ফ্লাস্ক অ্যাপ ইনিশিয়ালাইজ করা এবং ক্লাউড এনডিবি ও ক্লাউড স্টোরেজের জন্য এপিআই ক্লায়েন্ট তৈরি করা। সবশেষে, ইম্পোর্টস সেকশনে উপরে বর্ণিত পদ্ধতি অনুযায়ী আমরা ক্লাউড স্টোরেজ বাকেটের নামটি তৈরি করেছি। এই আপডেটগুলো প্রয়োগ করার আগের ও পরের অবস্থা নিচে দেওয়া হলো:

পূর্বে:

class BaseHandler(webapp2.RequestHandler):
    'Derived request handler mixing-in Jinja2 support'
    @webapp2.cached_property
    def jinja2(self):
        return jinja2.get_jinja2(app=self.app)

    def render_response(self, _template, **context):
        self.response.write(self.jinja2.render_template(_template, **context))

পরে:

app = Flask(__name__)
ds_client = ndb.Client()
gcs_client = storage.Client()
_, PROJECT_ID = google.auth.default()
BUCKET = '%s.appspot.com' % PROJECT_ID

ডেটাস্টোর অ্যাক্সেস আপডেট করুন

ক্লাউড এনডিবি মূলত অ্যাপ ইঞ্জিন এনডিবি-র সাথে সামঞ্জস্যপূর্ণ। ইতিমধ্যে আলোচিত একটি পার্থক্য হলো একটি এপিআই ক্লায়েন্টের প্রয়োজনীয়তা। আরেকটি হলো, এপিআই ক্লায়েন্টের পাইথন কনটেক্সট ম্যানেজারের মাধ্যমে ডেটাস্টোর অ্যাক্সেস নিয়ন্ত্রণ করতে হয়। মূলত, এর অর্থ হলো ক্লাউড এনডিবি ক্লায়েন্ট লাইব্রেরি ব্যবহার করে ডেটাস্টোর অ্যাক্সেসের সমস্ত কল শুধুমাত্র পাইথনের মধ্যেই ব্লকের with করা যাবে।

এটি একটি পরিবর্তন; অন্যটি হলো, Blobstore এবং এর অবজেক্টগুলো, যেমন BlobKey , Cloud Storage দ্বারা সমর্থিত নয়, তাই file_blob পরিবর্তন করে একটি ndb.StringProperty করুন। নিচে ডেটা মডেল ক্লাস এবং এই পরিবর্তনগুলো প্রতিফলিত করে আপডেট করা store_visit()fetch_visits() ফাংশনগুলো দেওয়া হলো:

পূর্বে:

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)
    file_blob = ndb.BlobKeyProperty()

def store_visit(remote_addr, user_agent, upload_key):
    'create new Visit entity in Datastore'
    Visit(visitor='{}: {}'.format(remote_addr, user_agent),
            file_blob=upload_key).put()

def fetch_visits(limit):
    'get most recent visits'
    return Visit.query().order(-Visit.timestamp).fetch(limit)

পরে:

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)
    file_blob = ndb.StringProperty()

def store_visit(remote_addr, user_agent, upload_key):
    'create new Visit entity in Datastore'
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent),
                file_blob=upload_key).put()

def fetch_visits(limit):
    'get most recent visits'
    with ds_client.context():
        return Visit.query().order(-Visit.timestamp).fetch(limit)

এ পর্যন্ত যে পরিবর্তনগুলো করা হয়েছে তার একটি চিত্ররূপ নিচে দেওয়া হলো:

a8f74ca392275822.png

হ্যান্ডলারদের আপডেট করা হচ্ছে

আপলোড হ্যান্ডলার

webapp2 এর হ্যান্ডলারগুলো ক্লাস হলেও Flask-এ সেগুলো ফাংশন। HTTP ভার্ব মেথডের পরিবর্তে, Flask ফাংশনটিকে ডেকোরেট করতে ভার্ব ব্যবহার করে। Blobstore এবং এর webapp হ্যান্ডলারগুলোকে Cloud Storage-এর কার্যকারিতা এবং Flask ও এর ইউটিলিটিগুলো দ্বারা প্রতিস্থাপন করা হয়েছে।

পূর্বে:

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    'Upload blob (POST) handler'
    def post(self):
        uploads = self.get_uploads()
        blob_id = uploads[0].key() if uploads else None
        store_visit(self.request.remote_addr, self.request.user_agent, blob_id)
        self.redirect('/', code=307)

পরে:

@app.route('/upload', methods=['POST'])
def upload():
    'Upload blob (POST) handler'
    fname = None
    upload = request.files.get('file', None)
    if upload:
        fname = secure_filename(upload.filename)
        blob = gcs_client.bucket(BUCKET).blob(fname)
        blob.upload_from_file(upload, content_type=upload.content_type)
    store_visit(request.remote_addr, request.user_agent, fname)
    return redirect(url_for('root'), code=307)

এই আপডেট সংক্রান্ত কিছু নোট:

  • blob_id এর পরিবর্তে, ফাইল আর্টিফ্যাক্টগুলি এখন ফাইলের নাম ( fname ) দ্বারা চিহ্নিত করা হয়, যদি তা উপস্থিত থাকে, এবং অন্যথায় None (ব্যবহারকারী ফাইল আপলোড না করার সিদ্ধান্ত নিয়েছেন)।
  • ব্লবস্টোর হ্যান্ডলারগুলো এর ব্যবহারকারীদের থেকে আপলোড প্রক্রিয়াটি আড়াল করে রেখেছিল, কিন্তু ক্লাউড স্টোরেজ তা করে না, তাই আপনি নতুন যোগ করা কোডটি দেখতে পাচ্ছেন যা ফাইলের ব্লব অবজেক্ট এবং অবস্থান (বাকেট) সেট করে, সেইসাথে প্রকৃত আপলোডটি সম্পাদনকারী কলটিও ( upload_from_file() )।
  • webapp2 অ্যাপ্লিকেশন ফাইলের একেবারে নিচে একটি রাউটিং টেবিল ব্যবহার করে, অন্যদিকে ফ্লাস্ক রাউটগুলো প্রতিটি ডেকোরেটেড হ্যান্ডলারে পাওয়া যায়।
  • উভয় হ্যান্ডলারই HTTP 307 রিটার্ন কোড সহ POST অনুরোধটি সংরক্ষণ করে হোম ( / ) এ রিডাইরেক্ট করার মাধ্যমে তাদের কার্যকারিতা শেষ করে।

ডাউনলোড হ্যান্ডলার

ডাউনলোড হ্যান্ডলার আপডেট করার পদ্ধতিটি আপলোড হ্যান্ডলারের মতোই, তবে এক্ষেত্রে কোড দেখার পরিমাণ অনেক কম। Blobstore এবং webapp কার্যকারিতা Cloud Storage এবং Flask-এর সমতুল্য অংশ দিয়ে প্রতিস্থাপন করুন:

পূর্বে:

class ViewBlobHandler(blobstore_handlers.BlobstoreDownloadHandler):
    'view uploaded blob (GET) handler'
    def get(self, blob_key):
        self.send_blob(blob_key) if blobstore.get(blob_key) else self.error(404)

পরে:

@app.route('/view/<path:fname>')
def view(fname):
    'view uploaded blob (GET) handler'
    blob = gcs_client.bucket(BUCKET).blob(fname)
    try:
        media = blob.download_as_bytes()
    except exceptions.NotFound:
        abort(404)
    return send_file(io.BytesIO(media), mimetype=blob.content_type)

এই আপডেট সম্পর্কিত নোট:

  • আবার, Flask হ্যান্ডলার ফাংশনগুলোকে তাদের রাউট দিয়ে সাজিয়ে রাখে, যেখানে webapp এটি একদম নিচে একটি রাউটিং টেবিলে করে থাকে, তাই webapp-এর প্যাটার্ন ম্যাচিং সিনট্যাক্স ('/view/([^/]+)?' ) এবং Flask-এর ( '/view/<path:fname>' ) সিনট্যাক্সের মধ্যে পার্থক্যটি খেয়াল রাখবেন।
  • আপলোড হ্যান্ডলারের মতোই, ব্লবস্টোর হ্যান্ডলার দ্বারা আড়াল করা কিছু কার্যকারিতার জন্য ক্লাউড স্টোরেজের দিকে আরও কিছুটা কাজ করার প্রয়োজন হয়। যেমন—প্রশ্নবিদ্ধ ফাইল (ব্লব) শনাক্ত করা এবং ব্লবস্টোর হ্যান্ডলারের একক send_blob() মেথড কলের পরিবর্তে স্পষ্টভাবে বাইনারিটি ডাউনলোড করা।
  • উভয় ক্ষেত্রেই, কোনো আর্টিফ্যাক্ট খুঁজে না পাওয়া গেলে ব্যবহারকারীকে একটি HTTP 404 ত্রুটি দেখানো হয়।

প্রধান পরিচালক

মূল অ্যাপ্লিকেশনের চূড়ান্ত পরিবর্তনগুলো মেইন হ্যান্ডলারে সম্পন্ন করা হয়। webapp2 HTTP ভার্ব মেথডগুলোকে তাদের কার্যকারিতা একত্রিত করে একটিমাত্র ফাংশন দ্বারা প্রতিস্থাপন করা হয়। নিচে দেখানো অনুযায়ী MainHandler ক্লাসটিকে root() ফাংশন দিয়ে প্রতিস্থাপন করুন এবং webapp2 রাউটিং টেবিলটি সরিয়ে ফেলুন:

পূর্বে:

class MainHandler(BaseHandler):
    'main application (GET/POST) handler'
    def get(self):
        self.render_response('index.html',
                upload_url=blobstore.create_upload_url('/upload'))

    def post(self):
        visits = fetch_visits(10)
        self.render_response('index.html', visits=visits)

app = webapp2.WSGIApplication([
    ('/', MainHandler),
    ('/upload', UploadHandler),
    ('/view/([^/]+)?', ViewBlobHandler),
], debug=True)

পরে:

@app.route('/', methods=['GET', 'POST'])
def root():
    'main application (GET/POST) handler'
    context = {}
    if request.method == 'GET':
        context['upload_url'] = url_for('upload')
    else:
        context['visits'] = fetch_visits(10)
    return render_template('index.html', **context)

আলাদা get() এবং post() মেথডের পরিবর্তে, এগুলো মূলত root() ফাংশনের মধ্যে একটি if-else স্টেটমেন্ট হিসেবে কাজ করে। এছাড়াও, root() একটি একক ফাংশন হওয়ায় GET এবং POST উভয়ের জন্য টেমপ্লেট রেন্ডার করতে মাত্র একবারই কল করা হয়, যেখানে webapp2 তে এটি করা সম্ভব নয়।

main.py তে করা এই দ্বিতীয় ও চূড়ান্ত পরিবর্তনগুলোর একটি সচিত্র উপস্থাপনা নিচে দেওয়া হলো:

5ec38818c32fec2.png

(ঐচ্ছিক) পূর্ববর্তী সংস্করণের সাথে সামঞ্জস্যের "উন্নয়ন"

সুতরাং উপরে তৈরি করা সমাধানটি পুরোপুরি কাজ করে... কিন্তু শুধুমাত্র যদি আপনি একদম শুরু থেকে কাজ করেন এবং আপনার কাছে Blobstore দ্বারা তৈরি কোনো ফাইল না থাকে। যেহেতু আমরা BlobKey এর পরিবর্তে ফাইলের নাম দিয়ে ফাইল শনাক্ত করার জন্য অ্যাপটি আপডেট করেছি, তাই মডিউল ১৬-এর সম্পূর্ণ অ্যাপটি যেমন আছে তেমন অবস্থায় Blobstore ফাইল দেখতে পারবে না। অন্য কথায়, এই মাইগ্রেশনটি করার সময় আমরা এমন একটি পরিবর্তন করেছি যা পূর্ববর্তী সংস্করণের সাথে সামঞ্জস্যপূর্ণ নয়। আমরা এখন main.py এর একটি বিকল্প সংস্করণ উপস্থাপন করছি যার নাম main-migrate.py (যা রিপো-তে পাওয়া যাবে) এবং এটি এই ঘাটতি পূরণের চেষ্টা করে।

Blobstore-এ তৈরি ফাইলগুলিকে সমর্থন করার জন্য প্রথম "এক্সটেনশন" হলো একটি ডেটা মডেল, যেটিতে একটি BlobKeyProperty রয়েছে (Cloud Storage-এ তৈরি ফাইলগুলির জন্য StringProperty পাশাপাশি):

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)
    file_blob = ndb.BlobKeyProperty()  # backwards-compatibility
    file_gcs  = ndb.StringProperty()

file_blob প্রপার্টিটি Blobstore-এ তৈরি ফাইল শনাক্ত করতে ব্যবহৃত হবে, আর file_gcs হলো ক্লাউড স্টোরেজ ফাইলের জন্য। এখন নতুন ভিজিট তৈরি করার সময়, file_blob এর পরিবর্তে file_gcs এ স্পষ্টভাবে একটি ভ্যালু স্টোর করা হবে, তাই `store_visit` দেখতে কিছুটা ভিন্ন হবে:

পূর্বে:

def store_visit(remote_addr, user_agent, upload_key):
    'create new Visit entity in Datastore'
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent),
                file_blob=upload_key).put()

পরে:

def store_visit(remote_addr, user_agent, upload_key):
    'create new Visit entity in Datastore'
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent),
                file_gcs=upload_key).put()

সর্বশেষ ভিজিটগুলো সংগ্রহ করার সময়, টেমপ্লেটে পাঠানোর আগে ডেটা 'নরম্যালাইজ' করুন:

পূর্বে:

@app.route('/', methods=['GET', 'POST'])
def root():
    'main application (GET/POST) handler'
    context = {}
    if request.method == 'GET':
        context['upload_url'] = url_for('upload')
    else:
        context['visits'] = fetch_visits(10)
    return render_template('index.html', **context)

পরে:

@app.route('/', methods=['GET', 'POST'])
def root():
    'main application (GET/POST) handler'
    context = {}
    if request.method == 'GET':
        context['upload_url'] = url_for('upload')
    else:
        context['visits'] = etl_visits(fetch_visits(10))
    return render_template('index.html', **context)

এরপর, file_blob অথবা file_gcs (কিংবা কোনোটিই নয়) আছে কিনা তা নিশ্চিত করুন। যদি কোনো ফাইল পাওয়া যায়, তবে বিদ্যমান ফাইলটি বেছে নিন এবং সেই আইডেন্টিফায়ারটি ব্যবহার করুন (Blobstore-এ তৈরি ফাইলের জন্য BlobKey অথবা Cloud Storage-এ তৈরি ফাইলের জন্য filename)। যখন আমরা "Cloud Storage-এ তৈরি ফাইল" বলি, তখন আমরা Cloud Storage ক্লায়েন্ট লাইব্রেরি ব্যবহার করে তৈরি করা ফাইলগুলোকে বোঝাই। Blobstore ক্লাউড স্টোরেজেও লেখে, কিন্তু সেক্ষেত্রে, সেগুলো Blobstore-এ তৈরি ফাইল হিসেবে গণ্য হবে।

এখন আরও গুরুত্বপূর্ণ বিষয় হলো, এই etl_visits() ফাংশনটি কী, যা শেষ ব্যবহারকারীর জন্য ডেটা নর্মালাইজ বা ETL (এক্সট্র্যাক্ট, ট্রান্সফর্ম এবং লোড) করতে ব্যবহৃত হয়? এটি দেখতে এইরকম:

def etl_visits(visits):
    return [{
            'visitor': v.visitor,
            'timestamp': v.timestamp,
            'file_blob': v.file_gcs if hasattr(v, 'file_gcs') \
                    and v.file_gcs else v.file_blob
            } for v in visits]

সম্ভবত এটি আপনার প্রত্যাশার মতোই দেখাচ্ছে: কোডটি সমস্ত ভিজিটের মধ্যে দিয়ে লুপ চালায়, এবং প্রতিটি ভিজিটের জন্য ভিজিটর ও টাইমস্ট্যাম্প ডেটা হুবহু গ্রহণ করে, তারপর file_gcs বা file_blob বিদ্যমান আছে কিনা তা পরীক্ষা করে, এবং যদি থাকে, তবে সেগুলোর মধ্যে একটি বেছে নেয় (অথবা কোনোটিই না থাকলে None বেছে নেয়)।

main.py এবং main-migrate.py এর মধ্যে পার্থক্যগুলো এখানে উদাহরণসহ দেখানো হলো:

718b05b2adadb2e1.png

আপনি যদি Blobstore-এর তৈরি ফাইল ছাড়া একেবারে নতুন করে শুরু করেন, তাহলে main.py ব্যবহার করুন। কিন্তু আপনি যদি রূপান্তর প্রক্রিয়ার মধ্যে থাকেন এবং Blobstore Cloud Storage উভয়ের তৈরি সহায়ক ফাইল চান, তাহলে main-migrate.py দেখে নিতে পারেন। এটি আপনাকে এই ধরনের পরিস্থিতি কীভাবে সামাল দিতে হয় তার একটি উদাহরণ দেবে এবং আপনার নিজের অ্যাপের মাইগ্রেশন পরিকল্পনা করতে সাহায্য করবে। জটিল মাইগ্রেশন করার সময় বিশেষ পরিস্থিতি তৈরি হওয়ার সম্ভাবনা থাকে, তাই এই উদাহরণটি বাস্তব ডেটা দিয়ে আসল অ্যাপ আধুনিকীকরণের প্রতি গভীর অনুরাগ দেখানোর জন্য দেওয়া হয়েছে।

৬. সারসংক্ষেপ/পরিষ্কারকরণ

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

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

আপনার অ্যাপটি পুনরায় ডিপ্লয় করার আগে, pip install -t lib -r requirements.txt চালিয়ে `lib` ফোল্ডারে সেলফ-বান্ডেল করা থার্ড-পার্টি লাইব্রেরিগুলো ইনস্টল করে নিন। আপনি যদি ব্যাকওয়ার্ড-কম্প্যাটিবল সলিউশনটি চালাতে চান, তাহলে প্রথমে `main-migrate.py` ফাইলটির নাম পরিবর্তন করে main.py main-migrate.py । এবার gcloud app deploy চালান এবং নিশ্চিত করুন যে অ্যাপটি মডিউল ১৫-এর অ্যাপটির মতোই হুবহু কাজ করছে। ফর্ম স্ক্রিনটি দেখতে এইরকম হবে:

f5b5f9f19d8ae978.png

সর্বশেষ ভিজিট পেজটি দেখতে এইরকম:

f5ac6b98ee8a34cb.png

অ্যাপ ইঞ্জিন ব্লবস্টোরকে ক্লাউড স্টোরেজ, অ্যাপ ইঞ্জিন এনডিবি-কে ক্লাউড এনডিবি এবং webapp2 কে ফ্লাস্ক দিয়ে প্রতিস্থাপন করে এই কোডল্যাবটি সম্পন্ন করার জন্য অভিনন্দন। আপনার কোড এখন FINISH (মডিউল ১৬) ফোল্ডারের কোডের সাথে মিলে যাওয়া উচিত। বিকল্প main-migrate.py ফাইলটিও ঐ ফোল্ডারে রয়েছে।

পাইথন ৩ 'মাইগ্রেশন'

এই অ্যাপটিকে পাইথন ৩-এ পোর্ট করার জন্য app.yaml শীর্ষে কমেন্ট করে রাখা পাইথন ৩ runtime ডিরেক্টিভটিই যথেষ্ট। সোর্স কোডটি ইতোমধ্যেই পাইথন ৩-এর সাথে সামঞ্জস্যপূর্ণ, তাই সেখানে কোনো পরিবর্তনের প্রয়োজন নেই। এটিকে একটি পাইথন ৩ অ্যাপ হিসেবে ডেপ্লয় করতে, নিম্নলিখিত ধাপগুলো অনুসরণ করুন:

  1. app.yaml ফাইলের শীর্ষে থাকা Python 3 runtime ডিরেক্টিভটির কমেন্ট তুলে দিন।
  2. app.yaml এর বাকি সব লাইন মুছে দিন।
  3. appengine_config.py ফাইলটি মুছে ফেলুন। (পাইথন ৩ রানটাইমে এটি ব্যবহৃত হয় না)
  4. lib ফোল্ডারটি থাকলে তা মুছে ফেলুন। (পাইথন ৩ রানটাইমের জন্য এটি অপ্রয়োজনীয়)

পরিষ্কার করা

সাধারণ

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

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

  • console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
  • console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
  • উপরের স্টোরেজ লিঙ্কগুলি আপনার PROJECT_ID এবং * LOC *-এর উপর নির্ভর করে, উদাহরণস্বরূপ, " us " যদি আপনার অ্যাপটি মার্কিন যুক্তরাষ্ট্রে হোস্ট করা হয়।

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

এই কোডল্যাবের জন্য নির্দিষ্ট

নীচে তালিকাভুক্ত পরিষেবাগুলি এই কোডল্যাবের জন্য অনন্য। আরও তথ্যের জন্য প্রতিটি পণ্যের ডকুমেন্টেশন দেখুন:

উল্লেখ্য যে, আপনি যদি মডিউল ১৫ থেকে ১৬-তে স্থানান্তরিত হয়ে থাকেন, তাহলেও আপনার ডেটা ব্লবস্টোরে থেকে যাবে, আর একারণেই আমরা উপরে এর মূল্য সংক্রান্ত তথ্য অন্তর্ভুক্ত করেছি।

পরবর্তী পদক্ষেপ

এই টিউটোরিয়াল ছাড়াও, পুরোনো বান্ডেল পরিষেবাগুলো থেকে সরে আসার উপর আলোকপাত করে এমন অন্যান্য মাইগ্রেশন মডিউলগুলোর মধ্যে রয়েছে:

  • মডিউল ২ : অ্যাপ ইঞ্জিন ndb থেকে ক্লাউড এনডিবি-তে মাইগ্রেট করুন
  • মডিউল ৭-৯ : অ্যাপ ইঞ্জিন টাস্ক কিউ থেকে ক্লাউড টাস্কে টাস্ক স্থানান্তর ও পুশ করা
  • মডিউল ১২-১৩ : অ্যাপ ইঞ্জিন মেমক্যাশ থেকে ক্লাউড মেমোরিস্টোরে স্থানান্তর
  • মডিউল ১৮-১৯ : অ্যাপ ইঞ্জিন টাস্ক কিউ (পুল টাস্ক) থেকে ক্লাউড পাব/সাব-এ মাইগ্রেট করা

গুগল ক্লাউডে অ্যাপ ইঞ্জিন এখন আর একমাত্র সার্ভারলেস প্ল্যাটফর্ম নয়। যদি আপনার একটি ছোট বা সীমিত কার্যকারিতাসম্পন্ন অ্যাপ ইঞ্জিন অ্যাপ থাকে এবং আপনি সেটিকে একটি স্বতন্ত্র মাইক্রোসার্ভিসে পরিণত করতে চান, অথবা একটি মনোলিথিক অ্যাপকে একাধিক পুনঃব্যবহারযোগ্য কম্পোনেন্টে বিভক্ত করতে চান, তবে ক্লাউড ফাংশনস -এ স্থানান্তরিত হওয়ার কথা বিবেচনা করার জন্য এগুলোই যথেষ্ট কারণ। যদি কন্টেইনারাইজেশন আপনার অ্যাপ্লিকেশন ডেভেলপমেন্ট ওয়ার্কফ্লোর একটি অংশ হয়ে থাকে, বিশেষ করে যদি এতে একটি CI/CD (কন্টিনিউয়াস ইন্টিগ্রেশন/কন্টিনিউয়াস ডেলিভারি বা ডিপ্লয়মেন্ট) পাইপলাইন থাকে, তবে ক্লাউড রান -এ মাইগ্রেট করার কথা বিবেচনা করুন। এই পরিস্থিতিগুলো নিম্নলিখিত মডিউলগুলোর আওতায় পড়ে:

  • অ্যাপ ইঞ্জিন থেকে ক্লাউড ফাংশনে স্থানান্তর করুন: মডিউল ১১ দেখুন।
  • অ্যাপ ইঞ্জিন থেকে ক্লাউড রান-এ মাইগ্রেট করুন: ডকার ব্যবহার করে আপনার অ্যাপকে কন্টেইনারাইজ করতে মডিউল ৪ দেখুন, অথবা কন্টেইনার, ডকার জ্ঞান বা Dockerfile ছাড়াই এটি করতে মডিউল ৫ দেখুন।

অন্য কোনো সার্ভারলেস প্ল্যাটফর্মে পরিবর্তন করা ঐচ্ছিক, এবং আমরা সুপারিশ করি যে কোনো পরিবর্তন করার আগে আপনার অ্যাপ ও ব্যবহারের ক্ষেত্রগুলোর জন্য সেরা বিকল্পগুলো বিবেচনা করে নিন।

এরপরে আপনি যে মাইগ্রেশন মডিউলটিই বিবেচনা করুন না কেন, সার্ভারলেস মাইগ্রেশন স্টেশনের সমস্ত কন্টেন্ট (কোডল্যাব, ভিডিও, সোর্স কোড [যখন উপলব্ধ]) এর ওপেন সোর্স রিপো থেকে অ্যাক্সেস করা যাবে। রিপোটির README কোন মাইগ্রেশনগুলো বিবেচনা করা উচিত এবং মাইগ্রেশন মডিউলগুলোর প্রাসঙ্গিক "ক্রম" সম্পর্কেও নির্দেশনা দেওয়া আছে।

৭. অতিরিক্ত সম্পদ

কোডল্যাবের সমস্যা/মতামত

এই কোডল্যাবে কোনো সমস্যা পেলে, অভিযোগ জানানোর আগে অনুগ্রহ করে সমস্যাটি অনুসন্ধান করুন। নতুন সমস্যা অনুসন্ধান ও তৈরি করার লিঙ্ক:

অভিবাসন সম্পদ

মডিউল ১৫ (শুরু) এবং মডিউল ১৬ (শেষ)-এর রিপো ফোল্ডারগুলোর লিঙ্ক নিচের টেবিলে দেওয়া আছে। এছাড়াও, সমস্ত অ্যাপ ইঞ্জিন কোডল্যাব মাইগ্রেশনের রিপো থেকেও এগুলো অ্যাক্সেস করা যাবে, যা আপনি ক্লোন করতে পারেন অথবা একটি জিপ ফাইল হিসেবে ডাউনলোড করতে পারেন।

কোডল্যাব

পাইথন ২

পাইথন ৩

মডিউল ১৫

কোড

প্রযোজ্য নয়

মডিউল ১৬ (এই কোডল্যাব)

কোড

(পাইথন ২ এর অনুরূপ)

অনলাইন রিসোর্স

এই টিউটোরিয়ালটির জন্য প্রাসঙ্গিক হতে পারে এমন কিছু অনলাইন রিসোর্স নিচে দেওয়া হলো:

অ্যাপ ইঞ্জিন ব্লবস্টোর এবং ক্লাউড স্টোরেজ

অ্যাপ ইঞ্জিন প্ল্যাটফর্ম

অন্যান্য ক্লাউড তথ্য

পাইথন

ভিডিও

লাইসেন্স

এই কাজটি ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন ২.০ জেনেরিক লাইসেন্সের অধীনে রয়েছে।