Python में एचटीटीपी Cloud Functions

1. परिचय

b158ce75c3cccd6d.png

Python एक लोकप्रिय ओपन सोर्स प्रोग्रामिंग लैंग्वेज है. इसका इस्तेमाल डेटा साइंटिस्ट, वेब ऐप्लिकेशन डेवलपर, सिस्टम एडमिन वगैरह करते हैं.

Cloud Functions, इवेंट-ड्रिवन सर्वरलेस कंप्यूट प्लैटफ़ॉर्म है. Cloud Functions की मदद से, संसाधनों को उपलब्ध कराने या बदलती ज़रूरतों को पूरा करने के लिए स्केल करने की चिंता किए बिना कोड लिखा जा सकता है.

Cloud Functions दो तरह के होते हैं:

  • एचटीटीपी फ़ंक्शन, एचटीटीपी अनुरोधों का जवाब देते हैं. इस कोडलैब में, आपको कुछ फ़िल्टर बनाने का तरीका बताया जाएगा.
  • बैकग्राउंड फ़ंक्शन, इवेंट से ट्रिगर होते हैं. जैसे, Cloud Pub/Sub पर कोई मैसेज पब्लिश करना या Cloud Storage पर कोई फ़ाइल अपलोड करना. हमने इस लैब में इस बारे में नहीं बताया है. हालांकि, दस्तावेज़ में इसके बारे में ज़्यादा जानकारी दी गई है.

efb3268e3b74ed4f.png

इस कोडलैब में, आपको Python में Cloud Functions बनाने के बारे में जानकारी मिलेगी.

आपको क्या बनाना है

इस कोडलैब में, आपको एक Cloud फ़ंक्शन पब्लिश करना होगा. इसे एचटीटीपी के ज़रिए चालू करने पर, "Python Powered" लोगो दिखेगा:

a7aaf656b78050fd.png

आपको क्या सीखने को मिलेगा

  • एचटीटीपी Cloud फ़ंक्शन लिखने का तरीका.
  • आर्ग्युमेंट लेने वाला एचटीटीपी Cloud फ़ंक्शन कैसे लिखें.
  • एचटीटीपी Cloud Function की जांच कैसे करें.
  • फ़ंक्शन को आज़माने के लिए, लोकल Python HTTP सर्वर को कैसे चलाया जाए.
  • इमेज दिखाने वाला एचटीटीपी क्लाउड फ़ंक्शन कैसे लिखें.

2. सेटअप और ज़रूरी शर्तें

अपनी स्पीड से एनवायरमेंट सेट अप करना

  1. Google Cloud Console में साइन इन करें और नया प्रोजेक्ट बनाएं या किसी मौजूदा प्रोजेक्ट का फिर से इस्तेमाल करें. अगर आपके पास पहले से कोई Gmail या Google Workspace खाता नहीं है, तो आपको एक खाता बनाना होगा.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • प्रोजेक्ट का नाम, इस प्रोजेक्ट में हिस्सा लेने वाले लोगों के लिए डिसप्ले नेम होता है. यह एक वर्ण स्ट्रिंग है, जिसका इस्तेमाल Google API नहीं करते. इसे कभी भी अपडेट किया जा सकता है.
  • प्रोजेक्ट आईडी, सभी Google Cloud प्रोजेक्ट के लिए यूनीक होता है. साथ ही, इसे बदला नहीं जा सकता. Cloud Console, एक यूनीक स्ट्रिंग अपने-आप जनरेट करता है. आम तौर पर, आपको इससे कोई फ़र्क़ नहीं पड़ता कि यह क्या है. ज़्यादातर कोडलैब में, आपको अपने प्रोजेक्ट आईडी (आम तौर पर PROJECT_ID के तौर पर पहचाना जाता है) का रेफ़रंस देना होगा. अगर आपको जनरेट किया गया आईडी पसंद नहीं है, तो कोई दूसरा रैंडम आईडी जनरेट किया जा सकता है. इसके अलावा, आपके पास अपना नाम आज़माने का विकल्प भी है. इससे आपको पता चलेगा कि वह नाम उपलब्ध है या नहीं. इस चरण के बाद, इसे बदला नहीं जा सकता. यह प्रोजेक्ट की अवधि तक बना रहता है.
  • आपकी जानकारी के लिए बता दें कि एक तीसरी वैल्यू भी होती है, जिसे प्रोजेक्ट नंबर कहते हैं. इसका इस्तेमाल कुछ एपीआई करते हैं. इन तीनों वैल्यू के बारे में ज़्यादा जानने के लिए, दस्तावेज़ देखें.
  1. इसके बाद, आपको Cloud Console में बिलिंग चालू करनी होगी, ताकि Cloud संसाधनों/एपीआई का इस्तेमाल किया जा सके. इस कोडलैब को पूरा करने में ज़्यादा समय नहीं लगेगा. इस ट्यूटोरियल के बाद बिलिंग से बचने के लिए, संसाधनों को बंद किया जा सकता है. इसके लिए, बनाए गए संसाधनों को मिटाएं या प्रोजेक्ट को मिटाएं. Google Cloud के नए उपयोगकर्ताओं को, मुफ़्त में आज़माने के लिए 300 डॉलर का क्रेडिट मिलता है.

Cloud Shell शुरू करना

Google Cloud को अपने लैपटॉप से रिमोटली ऑपरेट किया जा सकता है. हालांकि, इस कोडलैब में Cloud Shell का इस्तेमाल किया जाएगा. यह क्लाउड में चलने वाला कमांड लाइन एनवायरमेंट है.

Cloud Shell चालू करें

  1. Cloud Console में, Cloud Shell चालू करें 853e55310c205094.png पर क्लिक करें.

3c1dabeca90e44e5.png

अगर आपने Cloud Shell को पहली बार शुरू किया है, तो आपको एक इंटरमीडिएट स्क्रीन दिखेगी. इसमें Cloud Shell के बारे में जानकारी दी गई होगी. अगर आपको इंटरमीडिएट स्क्रीन दिखती है, तो जारी रखें पर क्लिक करें.

9c92662c6a846a5c.png

Cloud Shell से कनेक्ट होने में कुछ ही सेकंड लगेंगे.

9f0e51b578fecce5.png

इस वर्चुअल मशीन में, डेवलपमेंट के लिए ज़रूरी सभी टूल पहले से मौजूद हैं. यह 5 जीबी की होम डायरेक्ट्री उपलब्ध कराता है, जो हमेशा बनी रहती है. साथ ही, यह 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 Shell में यह कमांड चलाकर पक्का करें कि Cloud Functions और Cloud Build API चालू हों:

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

ध्यान दें: Cloud Build को gcloud functions deploy कमांड से कॉल किया जाएगा. साथ ही, यह आपके कोड को कंटेनर इमेज में अपने-आप बना देगा.

सोर्स कोड डाउनलोड करना

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

3. पेश है एचटीटीपी Cloud Functions

Python में एचटीटीपी 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 कमांड का इस्तेमाल करके, एचटीटीपी क्लाउड फ़ंक्शन के तौर पर डिप्लॉय करें:

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: फ़ंक्शन को एक एंडपॉइंट असाइन किया जाएगा. एंडपॉइंट पर एचटीटीपी अनुरोध (POST, PUT, GET, DELETE, और OPTIONS) करने पर, फ़ंक्शन चालू हो जाएगा.
  • --allow-unauthenticated: यह फ़ंक्शन सार्वजनिक होगा. इससे सभी कॉल करने वाले लोग, पुष्टि किए बिना कॉल कर पाएंगे.
  • ज़्यादा जानने के लिए, gcloud functions deploy देखें.

फ़ंक्शन की जांच करने के लिए, ऊपर कमांड के आउटपुट में दिखाए गए httpsTrigger.url यूआरएल पर क्लिक करें. यूआरएल को प्रोग्राम के हिसाब से भी वापस पाया जा सकता है. साथ ही, यहां दिए गए निर्देशों का इस्तेमाल करके फ़ंक्शन को कॉल किया जा सकता है:

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

आपको यह नतीजा दिखना चाहिए:

Hello World! 👋

4. तर्क लेने वाला एचटीटीपी 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=$(gcloud functions describe $FUNCTION_NAME --format "value(httpsTrigger.url)")
curl -w "\n" $URL

आपको डिफ़ॉल्ट नतीजा दिखेगा:

Hello World! 🚀

name आर्ग्युमेंट सेट न होने की वजह से, आपको डिफ़ॉल्ट नतीजा दिख रहा है. यूआरएल में कोई पैरामीटर जोड़ें:

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

इस बार, आपको अपनी पसंद के मुताबिक जवाब मिलेगा:

Hello YOUR NAME! 🚀

अगला चरण, यूनिट टेस्ट जोड़ना है. इससे यह पक्का किया जा सकेगा कि सोर्स कोड अपडेट होने पर भी आपके फ़ंक्शन, उम्मीद के मुताबिक काम करते रहें.

5. लिखने की जांच

Python में एचटीटीपी 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. हर फ़ंक्शन को शुरू करने के बाद, टेस्ट में एचटीटीपी रिस्पॉन्स की जांच की जाती है. इससे यह पक्का किया जाता है कि रिस्पॉन्स हमारी उम्मीद के मुताबिक है.

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" लोगो दिखाता है.

6. "Python Powered" एचटीटीपी क्लाउड फ़ंक्शन लिखना

आइए, हर अनुरोध के लिए "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 यूआरएल पर क्लिक करें. अगर सब कुछ सही तरीके से काम कर रहा है, तो आपको नए ब्राउज़र टैब में "Python Powered" लोगो दिखेगा!

इसके बाद, आपको एक ऐप्लिकेशन बनाना होगा, ताकि डिप्लॉयमेंट से पहले अपने फ़ंक्शन को स्थानीय तौर पर चलाया और आज़माया जा सके.

7. फ़ंक्शन को स्थानीय तौर पर चलाना

वेब ऐप्लिकेशन बनाकर और किसी रूट में अपने फ़ंक्शन को कॉल करके, एचटीटीपी फ़ंक्शन को स्थानीय तौर पर चलाया जा सकता है. इसे फ़ंक्शन वाली डायरेक्ट्री में जोड़ा जा सकता है. 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. यह फ़ंक्शन, बेस यूआरएल पर एक रूट रजिस्टर करता है. इसे 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 में, "वेब प्रीव्यू" बटन पर क्लिक करें और "पोर्ट 8080 पर प्रीव्यू करें" चुनें:

6c9ff9e5c692c58e.gif

Cloud Shell, प्रॉक्सी सेवा पर झलक दिखाने वाले यूआरएल को ब्राउज़र की नई विंडो में खोलता है. वेब प्रीव्यू की सुविधा, एचटीटीपीएस पर सिर्फ़ आपके उपयोगकर्ता खाते को ऐक्सेस करने की अनुमति देती है. अगर सब कुछ ठीक से काम कर रहा है, तो आपको "Python Powered" लोगो दिखेगा!

8e5c3ead11cfd103.png

8. बधाई हो!

b158ce75c3cccd6d.png

आपने एचटीटीपी क्लाउड फ़ंक्शन डिप्लॉय किए हैं. इसके लिए, आपने ऐसे फ़ंक्शन का इस्तेमाल किया है जो Flask फ़्रेमवर्क की मदद से वेब अनुरोधों को हैंडल करते हैं.

Cloud Functions की कीमत इस बात पर निर्भर करती है कि आपका फ़ंक्शन कितनी बार शुरू होता है. इसमें ऐसे फ़ंक्शन के लिए मुफ़्त टियर भी शामिल है जो अक्सर नहीं चलते. Cloud Functions की टेस्टिंग पूरी होने के बाद, उन्हें gcloud का इस्तेमाल करके मिटाया जा सकता है:

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

Google Cloud Console से भी फ़ंक्शन मिटाए जा सकते हैं.

हमें उम्मीद है कि आपको Python में Cloud Functions का इस्तेमाल करने में मज़ा आएगा!