Cloud Functions HTTP di Python

1. Pengantar

b158ce75c3cccd6d.png

Python adalah bahasa pemrograman open source populer yang digunakan oleh ilmuwan data, pengembang aplikasi web, administrator sistem, dan lainnya.

Cloud Functions adalah platform komputasi serverless berbasis peristiwa. Dengan Cloud Functions, Anda dapat menulis kode tanpa perlu khawatir tentang penyediaan resource atau penskalaan untuk menangani perubahan persyaratan.

Ada dua jenis Cloud Functions:

  • Fungsi HTTP merespons permintaan HTTP. Anda akan membuat beberapa di codelab ini.
  • Fungsi latar belakang dipicu oleh peristiwa, seperti pesan yang dipublikasikan ke Cloud Pub/Sub atau file yang diupload ke Cloud Storage. Kita tidak membahasnya di lab ini, tetapi Anda dapat membaca selengkapnya di dokumentasi.

efb3268e3b74ed4f.png

Codelab ini akan memandu Anda membuat Cloud Functions Anda sendiri di Python.

Yang akan Anda build

Dalam codelab ini, Anda akan memublikasikan Cloud Function yang, saat dipanggil melalui HTTP, menampilkan logo"Python Powered":

a7aaf656b78050fd.png

Yang akan Anda pelajari

  • Cara menulis HTTP Cloud Function.
  • Cara menulis HTTP Cloud Function yang menerima argumen.
  • Cara menguji Cloud Function HTTP.
  • Cara menjalankan server HTTP Python lokal untuk mencoba fungsi.
  • Cara menulis HTTP Cloud Function yang menampilkan gambar.

2. Penyiapan dan persyaratan

Penyiapan lingkungan mandiri

  1. Login ke Google Cloud Console dan buat project baru atau gunakan kembali project yang sudah ada. Jika belum memiliki akun Gmail atau Google Workspace, Anda harus membuatnya.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Project name adalah nama tampilan untuk peserta project ini. String ini adalah string karakter yang tidak digunakan oleh Google API. Anda dapat memperbaruinya kapan saja.
  • Project ID bersifat unik di semua project Google Cloud dan tidak dapat diubah (tidak dapat diubah setelah ditetapkan). Cloud Console otomatis membuat string unik; biasanya Anda tidak mementingkan kata-katanya. Di sebagian besar codelab, Anda harus merujuk Project ID-nya (umumnya diidentifikasi sebagai PROJECT_ID). Jika tidak suka dengan ID yang dibuat, Anda dapat membuat ID acak lainnya. Atau, Anda dapat mencobanya sendiri, dan lihat apakah ID tersebut tersedia. ID tidak dapat diubah setelah langkah ini dan tersedia selama durasi project.
  • Sebagai informasi, ada nilai ketiga, Project Number, yang digunakan oleh beberapa API. Pelajari lebih lanjut ketiga nilai ini di dokumentasi.
  1. Selanjutnya, Anda harus mengaktifkan penagihan di Konsol Cloud untuk menggunakan resource/API Cloud. Menjalankan operasi dalam codelab ini tidak akan memakan banyak biaya, bahkan mungkin tidak sama sekali. Guna mematikan resource agar tidak menimbulkan penagihan di luar tutorial ini, Anda dapat menghapus resource yang dibuat atau menghapus project-nya. Pengguna baru Google Cloud memenuhi syarat untuk mengikuti program Uji Coba Gratis senilai $300 USD.

Mulai Cloud Shell

Meskipun Google Cloud dapat dioperasikan dari jarak jauh menggunakan laptop Anda, dalam codelab ini, Anda akan menggunakan Cloud Shell, lingkungan command line yang berjalan di Cloud.

Mengaktifkan Cloud Shell

  1. Dari Cloud Console, klik Aktifkan Cloud Shell 853e55310c205094.png.

3c1dabeca90e44e5.png

Jika ini adalah pertama kalinya Anda memulai Cloud Shell, Anda akan melihat layar perantara yang menjelaskan apa itu Cloud Shell. Jika Anda melihat layar perantara, klik Continue.

9c92662c6a846a5c.png

Perlu waktu beberapa saat untuk menyediakan dan terhubung ke Cloud Shell.

9f0e51b578fecce5.png

Virtual machine ini dilengkapi dengan semua alat pengembangan yang diperlukan. VM ini menawarkan direktori beranda tetap sebesar 5 GB dan beroperasi di Google Cloud, sehingga sangat meningkatkan performa dan autentikasi jaringan. Sebagian besar pekerjaan Anda dalam codelab ini dapat dilakukan dengan browser.

Setelah terhubung ke Cloud Shell, Anda akan melihat bahwa Anda telah diautentikasi dan project telah ditetapkan ke project ID Anda.

  1. Jalankan perintah berikut di Cloud Shell untuk mengonfirmasi bahwa Anda telah diautentikasi:
gcloud auth list

Output perintah

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Jalankan perintah berikut di Cloud Shell untuk mengonfirmasi bahwa perintah gcloud mengetahui project Anda:
gcloud config list project

Output perintah

[core]
project = <PROJECT_ID>

Jika tidak, Anda dapat menyetelnya dengan perintah ini:

gcloud config set project <PROJECT_ID>

Output perintah

Updated property [core/project].

Pastikan Cloud Functions dan Cloud Build API diaktifkan

Jalankan perintah berikut dari Cloud Shell untuk memastikan Cloud Functions API dan Cloud Build API diaktifkan:

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

Catatan: Cloud Build akan dipanggil oleh perintah gcloud functions deploy dan akan otomatis membangun kode Anda ke dalam image container.

Mendownload kode sumber

Dari terminal Cloud Shell, jalankan perintah berikut:

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

Periksa konten direktori sumber:

ls

Anda akan memiliki file berikut:

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

3. Memperkenalkan Cloud Functions HTTP

HTTP Cloud Functions di Python ditulis sebagai fungsi Python biasa. Fungsi harus menerima satu argumen flask.Request, yang biasanya diberi nama 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")

# ...

Anda dapat membuka file dengan editor command line pilihan Anda (nano, vim, atau emacs). Anda juga dapat membukanya di Cloud Shell Editor setelah menetapkan direktori sumber sebagai ruang kerja:

cloudshell open-workspace .

Mari kita deploy fungsi ini sebagai Cloud Function HTTP menggunakan perintah gcloud functions deploy:

FUNCTION_NAME="hello_world"

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

Output perintah:

...
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
...

Catatan tentang opsi gcloud functions deploy:

  • --runtime: Ini menentukan runtime bahasa. Untuk Python, saat ini dapat berupa python37, python38, python39, python310, atau python312. Lihat Runtime.
  • --trigger-http: Fungsi akan diberi endpoint. Permintaan HTTP (POST, PUT, GET, DELETE, dan OPTIONS) ke endpoint akan memicu eksekusi fungsi.
  • --allow-unauthenticated: Fungsi akan bersifat publik, sehingga semua pemanggil dapat mengaksesnya tanpa perlu memeriksa autentikasi.
  • Untuk mempelajari lebih lanjut, lihat gcloud functions deploy.

Untuk menguji fungsi, Anda dapat mengklik URL httpsTrigger.url yang ditampilkan di output perintah di atas. Anda juga dapat mengambil URL secara terprogram dan memanggil fungsi dengan perintah berikut:

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

Anda akan mendapatkan hasil berikut:

Hello World! 👋

4. Menulis HTTP Cloud Function yang mengambil argumen

Fungsi menjadi lebih serbaguna saat menerima argumen. Mari kita tentukan fungsi baru hello_name yang mendukung parameter 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")

# ...

Mari kita deploy fungsi baru ini:

FUNCTION_NAME="hello_name"

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

Output perintah:

...
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
...

Untuk menguji fungsi, Anda dapat mengklik URL httpsTrigger.url yang ditampilkan di output perintah di atas. Anda juga dapat mengambil URL secara terprogram dan memanggil fungsi dengan perintah berikut:

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

Anda akan mendapatkan hasil default:

Hello World! 🚀

Anda mendapatkan hasil default karena argumen name tidak ditetapkan. Tambahkan parameter ke URL:

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

Kali ini, Anda akan mendapatkan respons kustom:

Hello YOUR NAME! 🚀

Langkah berikutnya adalah menambahkan pengujian unit untuk memastikan fungsi Anda terus berfungsi seperti yang diharapkan saat kode sumber diperbarui.

5. Menulis pengujian

HTTP Cloud Functions di Python diuji menggunakan modul unittest dari library standar. Anda tidak perlu menjalankan emulator atau simulasi lain untuk menguji fungsi—cukup kode Python normal.

Berikut tampilan pengujian untuk fungsi hello_world dan 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. Pengujian Python ditulis dengan cara yang sama seperti file Python lainnya. Mereka dimulai dengan serangkaian impor, lalu menentukan class dan fungsi.
  2. Deklarasi pengujian berbentuk class TestHello(TestCase). Harus berupa class yang mewarisi unittest.TestCase.
  3. Class pengujian memiliki metode, yang masing-masing harus dimulai dengan test_, yang merepresentasikan kasus pengujian individual.
  4. Setiap kasus pengujian menguji salah satu fungsi kami dengan mengejek parameter request (yaitu menggantinya dengan objek palsu dengan data spesifik yang diperlukan untuk pengujian).
  5. Setelah memanggil setiap fungsi, pengujian akan memeriksa respons HTTP untuk memastikan bahwa respons tersebut sesuai dengan yang kami harapkan.

Karena main.py bergantung pada flask, pastikan framework Flask diinstal di lingkungan pengujian Anda:

pip install flask

Menginstal Flask akan menghasilkan output yang mirip dengan berikut ini:

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

Jalankan pengujian ini secara lokal:

python -m unittest

Ketiga pengujian unit harus berhasil:

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

OK

Selanjutnya, Anda akan membuat fungsi baru yang menampilkan logo "Python Powered".

6. Menulis HTTP Cloud Function "Python Powered"

Mari kita buat fungsi baru menjadi lebih menarik dengan menampilkan gambar "Python Powered" untuk setiap permintaan:

a7aaf656b78050fd.png

Listingan berikut menunjukkan kode untuk mewujudkannya:

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")

Deploy fungsi python_powered baru:

FUNCTION_NAME="python_powered"

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

Output perintah:

...
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
...

Untuk menguji fungsi, klik URL httpsTrigger.url yang ditampilkan di output perintah di atas. Jika semuanya berfungsi dengan benar, Anda akan melihat logo "Python Powered" di tab browser baru.

Selanjutnya, Anda akan membuat aplikasi agar dapat menjalankan dan mencoba fungsi secara lokal sebelum deployment.

7. Menjalankan fungsi secara lokal

Anda dapat menjalankan fungsi HTTP secara lokal dengan membuat aplikasi web dan memanggil fungsi Anda dalam rute. Anda dapat menambahkannya di direktori yang sama dengan fungsi Anda. File bernama web_app.py memiliki konten berikut:

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. File ini membuat aplikasi Flask.
  2. Fungsi ini mendaftarkan rute di URL dasar yang ditangani dengan fungsi bernama index().
  3. Fungsi index() kemudian memanggil fungsi python_powered, dengan meneruskan permintaan saat ini.

Pastikan framework Flask diinstal di lingkungan pengembangan Anda:

pip install flask

Menginstal Flask akan menghasilkan output yang mirip dengan berikut ini:

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

Untuk menjalankan aplikasi ini secara lokal, jalankan perintah berikut:

python web_app.py

Sekarang gunakan Web Preview di Cloud Shell untuk menguji aplikasi web di browser Anda. Di Cloud Shell, klik tombol "Web Preview" dan pilih "Preview on port 8080":

6c9ff9e5c692c58e.gif

Cloud Shell membuka URL pratinjau pada layanan proxy-nya di jendela browser baru. Pratinjau web membatasi akses melalui HTTPS hanya ke akun pengguna Anda. Jika semuanya berfungsi dengan baik, Anda akan melihat logo "Python Powered".

8e5c3ead11cfd103.png

8. Selamat!

b158ce75c3cccd6d.png

Anda telah men-deploy HTTP Cloud Functions, menggunakan fungsi idiomatik yang menangani permintaan web dengan framework Flask.

Harga Cloud Functions didasarkan pada seberapa sering fungsi Anda dipanggil, termasuk paket gratis untuk fungsi yang tidak sering dijalankan. Setelah selesai menguji Cloud Functions, Anda dapat menghapusnya menggunakan gcloud:

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

Anda juga dapat menghapus fungsi dari Konsol Google Cloud.

Semoga Anda menikmati penggunaan Cloud Functions di Python.