Python-এ HTTP Cloud Functions

১. ভূমিকা

b158ce75c3cccd6d.png

Python হল একটি জনপ্রিয় ওপেন সোর্স প্রোগ্রামিং ল্যাঙ্গুয়েজ যা ডেটা বিজ্ঞানী, ওয়েব অ্যাপ্লিকেশন ডেভেলপার, সিস্টেম অ্যাডমিনিস্ট্রেটর এবং আরও অনেকে ব্যবহার করেন।

Cloud Functions হল একটি ইভেন্ট-চালিত সার্ভারলেস কম্পিউট প্ল্যাটফর্ম। Cloud Functions-এর সাহায্যে আপনি রিসোর্স প্রোভিশন করা বা পরিবর্তিত প্রয়োজনীয়তা অনুযায়ী স্কেল করার ব্যাপারে চিন্তা না করেই কোড লিখতে পারবেন।

দুই ধরনের Cloud Functions আছে:

  • HTTP ফাংশন HTTP অনুরোধের উত্তর দেয়। এই কোডল্যাবে আপনি কয়েকটি তৈরি করবেন।
  • ব্যাকগ্রাউন্ড ফাংশন ইভেন্টের মাধ্যমে ট্রিগার করা হয়, যেমন Cloud Pub/Sub-এ কোনও মেসেজ প্রকাশ করা বা Cloud Storage-এ কোনও ফাইল আপলোড করা। আমরা এই ল্যাবে এই বিষয়ে আলোচনা করি না, তবে আপনি ডকুমেন্টেশন থেকে আরও পড়তে পারেন।

efb3268e3b74ed4f.png

এই কোডল্যাব আপনাকে Python-এ নিজের Cloud Functions তৈরি করার ব্যাপারে গাইড করবে।

আপনি কী তৈরি করবেন

এই কোডল্যাবে, আপনি একটি Cloud Function প্রকাশ করবেন যা HTTP-এর মাধ্যমে কল করা হলে, "Python Powered" লোগো দেখায়:

a7aaf656b78050fd.png

আপনি কী শিখবেন

  • HTTP Cloud Function কীভাবে লিখতে হয়।
  • আর্গুমেন্ট নেয় এমন HTTP Cloud Function কীভাবে লিখতে হয়।
  • HTTP Cloud Function কীভাবে পরীক্ষা করতে হয়।
  • ফাংশনটি পরীক্ষা করার জন্য কীভাবে একটি লোকাল Python HTTP সার্ভার চালাতে হয়।
  • একটি HTTP Cloud Function কীভাবে লিখতে হয় যা একটি ছবি রিটার্ন করে।

২. সেট-আপ ও প্রয়োজনীয়তা

নিজের সময় ও সুবিধামতো এনভায়রনমেন্ট সেট-আপ করা

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

fbef9caa1602edd0.pnga99b7ace416376c4.png5e3ff691252acf41.png

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

Cloud Shell চালু করুন

Google Cloud আপনার ল্যাপটপ থেকে রিমোটলি অপারেট করা গেলেও, এই কোডল্যাবে আপনি Cloud Shell ব্যবহার করবেন, এটি হল ক্লাউডে চলা একটি কমান্ড লাইন এনভায়রনমেন্ট।

Cloud Shell চালু করুন

  1. Cloud Console থেকে, Cloud Shell চালু করুন 853e55310c205094.png বিকল্পে ক্লিক করুন।

3c1dabeca90e44e5.png

আপনি প্রথমবার Cloud Shell চালু করলে, এটি কী তা বর্ণনা করে একটি মধ্যবর্তী স্ক্রিন দেখানো হবে। আপনাকে মধ্যবর্তী স্ক্রিন দেখানো হলে, চালিয়ে যান বিকল্পে ক্লিক করুন।

9c92662c6a846a5c.png

Cloud Shell-এ প্রভিশন ও কানেক্ট করতে মাত্র কয়েক মুহূর্ত সময় লাগতে পারে।

9f0e51b578fecce5.png

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

Cloud Shell-এ কানেক্ট করার পরে, আপনি যাচাইকরণ সম্পূর্ণ করেছেন এবং প্রোজেক্টটি আপনার প্রোজেক্ট আইডিতে সেট করা হয়েছে কিনা তা দেখতে পাবেন।

  1. আপনি যাচাইকৃত কিনা তা কনফার্ম করতে Cloud Shell-এ এই কমান্ড রান করুন:
gcloud auth list

কমান্ড আউটপুট

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. gcloud কমান্ড আপনার প্রোজেক্ট সম্পর্কে জানে কিনা তা কনফার্ম করতে Cloud Shell-এ এই কমান্ড রান করুন:
gcloud config list project

কমান্ড আউটপুট

[core]
project = <PROJECT_ID>

যদি না থাকে, তাহলে আপনি এই কমান্ডের সাহায্যে এটি সেট করতে পারেন:

gcloud config set project <PROJECT_ID>

কমান্ড আউটপুট

Updated property [core/project].

Cloud Functions এবং Cloud Build API চালু আছে কিনা তা নিশ্চিত করুন

Cloud Functions এবং Cloud Build API চালু আছে কিনা তা নিশ্চিত করতে Cloud Shell থেকে নিম্নলিখিত কমান্ডটি রান করুন:

gcloud services enable \
  cloudfunctions.googleapis.com \
  cloudbuild.googleapis.com

মনে রাখবেন: gcloud functions deploy কমান্ডের মাধ্যমে Cloud Build কল করা হবে এবং এটি অটোমেটিক আপনার কোডকে কন্টেনার ইমেজে বিল্ড করবে।

সোর্স কোড ডাউনলোড করুন

Cloud Shell টার্মিনাল থেকে, নিম্নলিখিত কমান্ডগুলি রান করুন:

REPO_NAME="codelabs"
REPO_URL="https://github.com/GoogleCloudPlatform/$REPO_NAME"
SOURCE_DIR="cloud-functions-python-http"

git clone --no-checkout --filter=blob:none --depth=1 $REPO_URL
cd $REPO_NAME
git sparse-checkout set $SOURCE_DIR
git checkout
cd $SOURCE_DIR

সোর্স ডিরেক্টরির কন্টেন্ট চেক করুন:

ls

আপনার কাছে নিম্নলিখিত ফাইলগুলি থাকতে হবে:

main.py  python-powered.png  test_main.py  web_app.py

৩. HTTP Cloud Functions-এর সাথে পরিচয়

Python-এ HTTP Cloud Functions সাধারণ Python ফাংশন হিসেবে লেখা হয়। ফাংশনটি অবশ্যই একটি একক flask.Request আর্গুমেন্ট গ্রহণ করবে, যার নাম সাধারণত request।

main.py

import flask


def hello_world(request: flask.Request) -> flask.Response:
    """HTTP Cloud Function.

    Returns:
    - "Hello World! 👋"
    """
    response = "Hello World! 👋"

    return flask.Response(response, mimetype="text/plain")

# ...

আপনার পছন্দের কমান্ড লাইন এডিটর (nano, vim, বা emacs) দিয়ে ফাইলটি খুলতে পারবেন। এছাড়াও, সোর্স ডিরেক্টরিকে ওয়ার্কস্পেস হিসেবে সেট করার পরে আপনি এটি Cloud Shell Editor-এ খুলতে পারবেন:

cloudshell open-workspace .

আসুন gcloud functions deploy কমান্ড ব্যবহার করে এই ফাংশনটি HTTP Cloud Function হিসেবে ডিপ্লয় করি:

FUNCTION_NAME="hello_world"

gcloud functions deploy $FUNCTION_NAME \
  --runtime python312 \
  --trigger-http \
  --allow-unauthenticated

কমান্ড আউটপুট:

...
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
...
entryPoint: FUNCTION_NAME
httpsTrigger:
  url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME
...

gcloud functions deploy বিকল্প সম্পর্কে নোট:

  • --runtime: এটি ল্যাঙ্গুয়েজ রানটাইম নির্দিষ্ট করে। Python-এর জন্য, এটি বর্তমানে python37, python38, python39, python310 বা python312 হতে পারে। রানটাইম দেখুন।
  • --trigger-http: ফাংশনটিতে একটি এন্ডপয়েন্ট অ্যাসাইন করা হবে। এন্ডপয়েন্টে HTTP অনুরোধ (POST, PUT, GET, DELETE, এবং OPTIONS) ফাংশন এক্সিকিউশন ট্রিগার করবে।
  • --allow-unauthenticated: ফাংশনটি সর্বজনীন হবে, যা যাচাইকরণ চেক না করেই সব কলারকে অনুমতি দেবে।
  • আরও জানতে, gcloud functions deploy দেখুন।

ফাংশনটি পরীক্ষা করতে, আপনি উপরে কমান্ড আউটপুটে দেখানো httpsTrigger.url URL-এ ক্লিক করতে পারেন। এছাড়াও, আপনি প্রোগ্রাম্যাটিক্যালি URL ফিরিয়ে আনতে এবং নিম্নলিখিত কমান্ডের সাহায্যে ফাংশন কল করতে পারবেন:

URL=$(gcloud functions describe $FUNCTION_NAME --format "value(httpsTrigger.url)")
curl -w "\n" $URL

আপনি নিম্নলিখিত ফলাফল দেখতে পাবেন:

Hello World! 👋

৪. আর্গুমেন্ট নেয় এমন HTTP Cloud Function লেখা

ফাংশন আর্গুমেন্ট গ্রহণ করলে তা আরও বহুমুখী হয়। আসুন, একটি নতুন ফাংশন hello_name সংজ্ঞায়িত করি যা একটি name প্যারামিটারকে সমর্থন করে:

main.py

# ...

def hello_name(request: flask.Request) -> flask.Response:
    """HTTP Cloud Function.

    Returns:
    - "Hello {NAME}! 🚀" if "name=NAME" is defined in the GET request
    - "Hello World! 🚀" otherwise
    """
    name = request.args.get("name", "World")
    response = f"Hello {name}! 🚀"

    return flask.Response(response, mimetype="text/plain")

# ...

এই নতুন ফাংশন ডিপ্লয় করা যাক:

FUNCTION_NAME="hello_name"

gcloud functions deploy $FUNCTION_NAME \
  --runtime python312 \
  --trigger-http \
  --allow-unauthenticated

কমান্ড আউটপুট:

...
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
...
entryPoint: FUNCTION_NAME
httpsTrigger:
  url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME
...

ফাংশনটি পরীক্ষা করতে, আপনি উপরে কমান্ড আউটপুটে দেখানো httpsTrigger.url URL-এ ক্লিক করতে পারেন। এছাড়াও, আপনি প্রোগ্রাম্যাটিক্যালি URL ফিরিয়ে আনতে এবং নিম্নলিখিত কমান্ডের সাহায্যে ফাংশন কল করতে পারবেন:

URL=$(gcloud functions describe $FUNCTION_NAME --format "value(httpsTrigger.url)")
curl -w "\n" $URL

আপনি ডিফল্ট ফলাফল পাবেন:

Hello World! 🚀

name আর্গুমেন্ট সেট করা নেই বলে আপনি ডিফল্ট ফলাফল পাচ্ছেন। URL-এ প্যারামিটার যোগ করুন:

curl -w "\n" $URL?name=YOUR%20NAME

এইবার, আপনি নিজের কাস্টম উত্তর পাবেন:

Hello YOUR NAME! 🚀

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

৫. পরীক্ষা লেখা

Python-এ HTTP Cloud Functions স্ট্যান্ডার্ড লাইব্রেরি থেকে unittest মডিউল ব্যবহার করে পরীক্ষা করা হয়। আপনার ফাংশন পরীক্ষা করার জন্য কোনও এমুলেটর বা অন্য সিমুলেশন চালানোর প্রয়োজন নেই—শুধু সাধারণ Python কোড।

hello_world এবং hello_name ফাংশনের জন্য টেস্ট কেমন দেখতে হয় তা এখানে দেওয়া হল:

test_main.py

import unittest
import unittest.mock

import main


class TestHello(unittest.TestCase):
    def test_hello_world(self):
        request = unittest.mock.Mock()

        response = main.hello_world(request)
        assert response.status_code == 200
        assert response.get_data(as_text=True) == "Hello World! 👋"

    def test_hello_name_no_name(self):
        request = unittest.mock.Mock(args={})

        response = main.hello_name(request)
        assert response.status_code == 200
        assert response.get_data(as_text=True) == "Hello World! 🚀"

    def test_hello_name_with_name(self):
        name = "FirstName LastName"
        request = unittest.mock.Mock(args={"name": name})

        response = main.hello_name(request)
        assert response.status_code == 200
        assert response.get_data(as_text=True) == f"Hello {name}! 🚀"
  1. অন্যান্য Python ফাইলের মতোই Python টেস্ট লেখা হয়। এগুলি এক সেট ইমপোর্ট দিয়ে শুরু হয়, তারপর ক্লাস ও ফাংশন সংজ্ঞায়িত করে।
  2. পরীক্ষার ঘোষণা class TestHello(TestCase) ফর্মের মতো। এটি অবশ্যই এমন একটি ক্লাস হতে হবে যা unittest.TestCase থেকে উত্তরাধিকারসূত্রে প্রাপ্ত।
  3. টেস্ট ক্লাসে পদ্ধতি আছে, যার প্রতিটি test_ দিয়ে শুরু হতে হবে, যা স্বতন্ত্র টেস্ট কেসকে উপস্থাপন করে।
  4. প্রতিটি টেস্ট কেস request প্যারামিটার মক করে আমাদের একটি ফাংশন টেস্ট করে (অর্থাৎ, টেস্টের জন্য প্রয়োজনীয় নির্দিষ্ট ডেটা সহ একটি নকল অবজেক্ট দিয়ে এটি রিপ্লেস করে)।
  5. প্রতিটি ফাংশন ইনভোক করার পরে, টেস্টটি HTTP রেসপন্স চেক করে নিশ্চিত করে যে এটি আমরা যা আশা করছিলাম তাই ছিল।

যেহেতু main.py, flask-এর উপর নির্ভর করে, তাই আপনার টেস্ট এনভায়রনমেন্টে Flask ফ্রেমওয়ার্ক ইনস্টল করা আছে কিনা তা নিশ্চিত করুন:

pip install flask

Flask ইনস্টল করলে নিম্নলিখিত ফলাফলের মতো একটি ফলাফল আউটপুট হিসেবে দেখায়:

Collecting flask
...
Successfully installed ... flask-3.0.2 ...

এইসব টেস্ট লোকালি রান করুন:

python -m unittest

তিনটি ইউনিট টেস্ট পাস করতে হবে:

...
----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

এরপর, আপনি একটি নতুন ফাংশন তৈরি করবেন যা "Python Powered" লোগো রিটার্ন করে।

৬. "Python দ্বারা পরিচালিত" HTTP Cloud Function লেখা

আসুন, প্রতিটি অনুরোধের জন্য "Python Powered" ছবি ফিরিয়ে দিয়ে নতুন ফাংশনকে আরও একটু বিনোদনমূলক করে তুলি:

a7aaf656b78050fd.png

এটি করার জন্য কোডটি নিম্নলিখিত তালিকায় দেখানো হয়েছে:

main.py

# ...

def python_powered(request: flask.Request) -> flask.Response:
    """HTTP Cloud Function.

    Returns:
    - The official "Python Powered" logo
    """
    return flask.send_file("python-powered.png")

নতুন python_powered ফাংশন ডিপ্লয় করুন:

FUNCTION_NAME="python_powered"

gcloud functions deploy $FUNCTION_NAME \
  --runtime python312 \
  --trigger-http \
  --allow-unauthenticated

কমান্ড আউটপুট:

...
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
...
entryPoint: FUNCTION_NAME
httpsTrigger:
  url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME
...

ফাংশনটি পরীক্ষা করতে, উপরে কমান্ড আউটপুটে দেখানো httpsTrigger.url URL-এ ক্লিক করুন। সবকিছু ঠিকঠাক কাজ করলে, আপনি নতুন ব্রাউজার ট্যাবে "Python Powered" লোগো দেখতে পাবেন!

এরপর, আপনি একটি অ্যাপ তৈরি করবেন যাতে ডিপ্লয় করার আগে লোকালি আপনার ফাংশন রান ও চেষ্টা করে দেখতে পারেন।

৭. ফাংশনটি লোকালি রান করা হচ্ছে

আপনি একটি ওয়েব অ্যাপ তৈরি করে এবং একটি রুটে আপনার ফাংশন কল করে স্থানীয়ভাবে একটি HTTP ফাংশন চালাতে পারেন। আপনার ফাংশনের মতো একই ডিরেক্টরিতে এটি যোগ করতে পারবেন। web_app.py নামের ফাইলে নিম্নলিখিত কন্টেন্ট আছে:

web_app.py

import flask

import main

app = flask.Flask(__name__)


@app.get("/")
def index():
    return main.python_powered(flask.request)


if __name__ == "__main__":
    # Local development only
    # Run "python web_app.py" and open http://localhost:8080
    app.run(host="localhost", port=8080, debug=True)
  1. এই ফাইলটি একটি Flask অ্যাপ্লিকেশন তৈরি করে।
  2. এটি বেস URL-এ একটি রুট রেজিস্টার করে যা index() নামের ফাংশনের মাধ্যমে ম্যানেজ করা হয়।
  3. index() ফাংশনটি তখন আমাদের python_powered ফাংশনকে কল করে, বর্তমান অনুরোধটি পাস করে।

আপনার ডেভেলপমেন্ট এনভায়রনমেন্টে Flask ফ্রেমওয়ার্ক ইনস্টল করা আছে কিনা তা নিশ্চিত করুন:

pip install flask

Flask ইনস্টল করলে নিম্নলিখিত ফলাফলের মতো একটি ফলাফল আউটপুট হিসেবে দেখায়:

Collecting flask
...
Successfully installed ... flask-3.0.2 ...

এই অ্যাপ্লিকেশনটি স্থানীয়ভাবে রান করতে, নিম্নলিখিত কমান্ড রান করুন:

python web_app.py

আপনার ব্রাউজারে ওয়েব অ্যাপ পরীক্ষা করতে এখন Cloud Shell ওয়েব প্রিভিউ ব্যবহার করুন। Cloud Shell-এ, "ওয়েব প্রিভিউ" বোতামে ক্লিক করে "পোর্ট ৮০৮০-তে প্রিভিউ" বিকল্প বেছে নিন:

6c9ff9e5c692c58e.gif

Cloud Shell নতুন ব্রাউজার উইন্ডোতে এর প্রক্সি সার্ভিসে প্রিভিউ URL খোলে। ওয়েব প্রিভিউ HTTPS-এর মাধ্যমে শুধু আপনার ব্যবহারকারীর অ্যাকাউন্টে অ্যাক্সেস সীমিত করে। সবকিছু ঠিকঠাক কাজ করলে, আপনি "Python Powered" লোগো দেখতে পাবেন!

8e5c3ead11cfd103.png

৮. অভিনন্দন!

b158ce75c3cccd6d.png

আপনি HTTP Cloud Functions ডিপ্লয় করেছেন, ইডিওমেটিক ফাংশন ব্যবহার করে যা Flask ফ্রেমওয়ার্কের সাথে ওয়েব অনুরোধ ম্যানেজ করে।

আপনার ফাংশন কত ঘন ঘন কল করা হয় তার উপর ভিত্তি করে Cloud Functions-এর দাম নির্ধারণ করা হয়, যার মধ্যে ঘন ঘন রান করে না এমন ফাংশনের জন্য একটি ফ্রি টিয়ার অন্তর্ভুক্ত থাকে। আপনার ক্লাউড ফাংশন পরীক্ষা করা হয়ে গেলে, আপনি gcloud ব্যবহার করে সেগুলি মুছে ফেলতে পারেন:

gcloud functions delete hello_world --quiet
gcloud functions delete hello_name --quiet
gcloud functions delete python_powered --quiet

এছাড়াও, আপনি Google Cloud কনসোল থেকে ফাংশন মুছে দিতে পারবেন।

আমরা আশা করি আপনি Python-এ Cloud Functions ব্যবহার করে আনন্দ পাবেন!