HTTP-Funktionen von Cloud Functions in Python

1. Einführung

b158ce75c3cccd6d.png

Python ist eine beliebte Open-Source-Programmiersprache, die von Data Scientists, Webanwendungsentwicklern, Systemadministratoren und anderen verwendet wird.

Cloud Functions ist eine ereignisgesteuerte serverlose Computing-Plattform. Mit Cloud Functions können Sie Code schreiben, ohne sich um die Bereitstellung von Ressourcen oder die Skalierung zur Bewältigung sich ändernder Anforderungen kümmern zu müssen.

Es gibt zwei Arten von Cloud Functions-Funktionen:

  • HTTP-Funktionen reagieren auf HTTP-Anfragen. In diesem Codelab erstellen Sie ein Paar.
  • Hintergrundfunktionen werden durch Ereignisse ausgelöst, z. B. wenn eine Nachricht in Cloud Pub/Sub veröffentlicht oder eine Datei in Cloud Storage hochgeladen wird. Wir gehen in diesem Lab nicht darauf ein, aber weitere Informationen finden Sie in der Dokumentation.

efb3268e3b74ed4f.png

In diesem Codelab lernen Sie Schritt für Schritt, wie Sie Ihre eigenen Cloud Functions in Python erstellen.

Aufgaben

In diesem Codelab stellen Sie eine Cloud Functions-Funktion bereit, die bei Aufruf über HTTP das Logo „Python Powered“ anzeigt:

a7aaf656b78050fd.png

Lerninhalte

  • HTTP-Cloud-Funktion schreiben
  • HTTP-Cloud Functions-Funktion schreiben, die Argumente akzeptiert
  • HTTP-Cloud-Funktion testen
  • Lokalen Python-HTTP-Server ausführen, um die Funktion zu testen
  • HTTP-Cloud Functions-Funktion schreiben, die ein Bild zurückgibt

2. Einrichtung und Anforderungen

Umgebung zum selbstbestimmten Lernen einrichten

  1. Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Es handelt sich um einen String, der nicht von Google APIs verwendet wird. Sie können sie jederzeit aktualisieren.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich (kann nach dem Festlegen nicht mehr geändert werden). In der Cloud Console wird automatisch ein eindeutiger String generiert. Normalerweise ist es nicht wichtig, wie dieser String aussieht. In den meisten Codelabs müssen Sie auf Ihre Projekt-ID verweisen (in der Regel als PROJECT_ID angegeben). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige ID generieren. Alternativ können Sie es mit einem eigenen Namen versuchen und sehen, ob er verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen.
  • Zur Information: Es gibt einen dritten Wert, die Projektnummer, die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten
  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Cloud-Ressourcen/-APIs zu verwenden. Die Durchführung dieses Codelabs kostet wenig oder gar nichts. Wenn Sie Ressourcen herunterfahren möchten, um Kosten zu vermeiden, die über diese Anleitung hinausgehen, können Sie die erstellten Ressourcen oder das Projekt löschen. Neue Google Cloud-Nutzer können am kostenlosen Testzeitraum mit einem Guthaben von 300$ teilnehmen.

Cloud Shell starten

Während Sie Google Cloud von Ihrem Laptop aus per Fernzugriff nutzen können, wird in diesem Codelab Cloud Shell verwendet, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren 853e55310c205094.png.

3c1dabeca90e44e5.png

Wenn Sie die Cloud Shell zum ersten Mal starten, wird ein Fenster mit einer Beschreibung eingeblendet. Klicken Sie in diesem Fall einfach auf Weiter.

9c92662c6a846a5c.png

Das Herstellen der Verbindung mit der Cloud Shell sollte nur wenige Augenblicke dauern.

9f0e51b578fecce5.png

Auf dieser virtuellen Maschine sind alle erforderlichen Entwicklungstools installiert. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Die meisten, wenn nicht sogar alle Aufgaben in diesem Codelab können mit einem Browser erledigt werden.

Sobald die Verbindung mit der Cloud Shell hergestellt ist, sehen Sie, dass Sie authentifiziert sind und für das Projekt Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in der Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list

Befehlsausgabe

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Führen Sie den folgenden Befehl in Cloud Shell aus, um zu bestätigen, dass der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

Achten Sie darauf, dass die Cloud Functions API und die Cloud Build API aktiviert sind.

Führen Sie den folgenden Befehl in Cloud Shell aus, um zu prüfen, ob die Cloud Functions API und die Cloud Build API aktiviert sind:

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

Hinweis: Cloud Build wird vom Befehl gcloud functions deploy aufgerufen und erstellt automatisch ein Container-Image aus Ihrem Code.

Quellcode herunterladen

Führen Sie im Cloud Shell-Terminal die folgenden Befehle aus:

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

Sehen Sie sich den Inhalt des Quellverzeichnisses an:

ls

Sie sollten die folgenden Dateien haben:

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

3. HTTP-Cloud-Funktionen

HTTP-Cloud Functions-Funktionen in Python werden als reguläre Python-Funktionen geschrieben. Die Funktion muss ein einzelnes flask.Request-Argument akzeptieren, das in der Regel request heißt.

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

# ...

Sie können die Datei mit dem Befehlszeileneditor Ihrer Wahl (z. B. nano, vim oder emacs) öffnen. Sie können es auch im Cloud Shell-Editor öffnen, nachdem Sie das Quellverzeichnis als Arbeitsbereich festgelegt haben:

cloudshell open-workspace .

Stellen wir diese Funktion als HTTP-Cloud Functions-Funktion mit dem Befehl gcloud functions deploy bereit:

FUNCTION_NAME="hello_world"

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

Befehlsausgabe:

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

Hinweise zu den gcloud functions deploy-Optionen:

  • --runtime: Gibt die Sprachlaufzeit an. Für Python kann dies derzeit python37, python38, python39, python310 oder python312 sein. Weitere Informationen finden Sie unter Laufzeiten.
  • --trigger-http: Der Funktion wird ein Endpunkt zugewiesen. HTTP-Anfragen (POST, PUT, GET, DELETE und OPTIONS) an den Endpunkt lösen die Ausführung der Funktion aus.
  • --allow-unauthenticated: Die Funktion ist öffentlich und kann von allen Aufrufern aufgerufen werden, ohne dass eine Authentifizierung erforderlich ist.
  • Weitere Informationen finden Sie unter gcloud functions deploy.

Wenn Sie die Funktion testen möchten, können Sie auf die httpsTrigger.url-URL klicken, die oben in der Befehlsausgabe angezeigt wird. Sie können die URL auch programmatisch abrufen und die Funktion mit den folgenden Befehlen aufrufen:

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

Sie sollten das folgende Ergebnis erhalten:

Hello World! 👋

4. HTTP-Cloud Functions-Funktion schreiben, die Argumente akzeptiert

Funktionen sind vielseitiger, wenn sie Argumente akzeptieren. Definieren wir eine neue Funktion hello_name, die den Parameter name unterstützt:

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

# ...

Stellen wir diese neue Funktion bereit:

FUNCTION_NAME="hello_name"

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

Befehlsausgabe:

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

Wenn Sie die Funktion testen möchten, können Sie auf die httpsTrigger.url-URL klicken, die oben in der Befehlsausgabe angezeigt wird. Sie können die URL auch programmatisch abrufen und die Funktion mit den folgenden Befehlen aufrufen:

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

Sie sollten das Standardergebnis erhalten:

Hello World! 🚀

Sie erhalten das Standardergebnis, weil das Argument name nicht festgelegt ist. Fügen Sie der URL einen Parameter hinzu:

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

Dieses Mal erhalten Sie Ihre benutzerdefinierte Antwort:

Hello YOUR NAME! 🚀

Als Nächstes fügen Sie Unit-Tests hinzu, um sicherzustellen, dass Ihre Funktionen weiterhin wie vorgesehen funktionieren, wenn der Quellcode aktualisiert wird.

5. Tests schreiben

HTTP-Cloud Functions-Funktionen in Python werden mit dem Modul unittest aus der Standardbibliothek getestet. Sie müssen keinen Emulator und keine andere Simulation ausführen, um Ihre Funktion zu testen – es reicht normaler Python-Code.

So sieht ein Test für die Funktionen hello_world und hello_name aus:

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-Tests werden auf dieselbe Weise wie andere Python-Dateien geschrieben. Sie beginnen mit einer Reihe von Importen und definieren dann Klassen und Funktionen.
  2. Die Testdeklaration hat die Form class TestHello(TestCase). Es muss eine Klasse sein, die von unittest.TestCase abgeleitet wird.
  3. Die Testklasse hat Methoden, die jeweils mit test_ beginnen müssen und einzelne Testläufe darstellen.
  4. In jedem Testlauf wird eine unserer Funktionen getestet, indem der Parameter request simuliert wird. Das bedeutet, dass er durch ein gefälschtes Objekt mit den für den Test erforderlichen spezifischen Daten ersetzt wird.
  5. Nach dem Aufrufen jeder Funktion prüft der Test die HTTP-Antwort, um sicherzugehen, dass sie unseren Erwartungen entspricht.

Da main.py von flask abhängt, muss das Flask-Framework in Ihrer Testumgebung installiert sein:

pip install flask

Bei der Installation von Flask wird ein Ergebnis ähnlich dem folgenden ausgegeben:

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

Führen Sie diese Tests lokal aus:

python -m unittest

Die drei Einheitentests sollten erfolgreich sein:

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

OK

Als Nächstes erstellen Sie eine neue Funktion, die das Logo „Python Powered“ zurückgibt.

6. HTTP-Cloud Functions-Funktion „Python Powered“ schreiben

Machen wir eine neue Funktion etwas unterhaltsamer, indem wir für jede Anfrage das Bild „Python Powered“ zurückgeben:

a7aaf656b78050fd.png

Die folgende Auflistung zeigt den Code, mit dem das möglich ist:

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

Stellen Sie eine neue python_powered-Funktion bereit:

FUNCTION_NAME="python_powered"

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

Befehlsausgabe:

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

Klicken Sie zum Testen der Funktion auf die httpsTrigger.url-URL, die in der Befehlsausgabe oben angezeigt wird. Wenn alles korrekt funktioniert, wird das Logo „Python Powered“ in einem neuen Browser-Tab angezeigt.

Als Nächstes erstellen Sie eine App, damit Sie Ihre Funktion vor der Bereitstellung lokal ausführen und testen können.

7. Funktion lokal ausführen

Sie können eine HTTP-Funktion lokal ausführen, indem Sie eine Web-App erstellen und Ihre Funktion in einem Pfad aufrufen. Sie können sie im selben Verzeichnis wie Ihre Funktion hinzufügen. Die Datei mit dem Namen web_app.py hat folgenden Inhalt:

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. In dieser Datei wird eine Flask-Anwendung erstellt.
  2. Sie registriert einen Pfad an der Basis-URL, der mit einer Funktion namens index() verarbeitet wird.
  3. Die Funktion index() ruft dann unsere Funktion python_powered auf und übergibt ihr die aktuelle Anfrage.

Prüfen Sie, ob das Flask-Framework in Ihrer Entwicklungsumgebung installiert ist:

pip install flask

Bei der Installation von Flask wird ein Ergebnis ähnlich dem folgenden ausgegeben:

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

Führen Sie den folgenden Befehl aus, um diese Anwendung lokal auszuführen:

python web_app.py

Testen Sie jetzt mit der Webvorschau von Cloud Shell die Web-App in Ihrem Browser. Klicken Sie in Cloud Shell auf die Schaltfläche „Webvorschau“ und wählen Sie „Vorschau auf Port 8080“ aus:

6c9ff9e5c692c58e.gif

Die Vorschau-URL für den Proxy-Dienst wird in Cloud Shell in einem neuen Browserfenster geöffnet. Die Webvorschau beschränkt den Zugriff über HTTPS auf Ihr Nutzerkonto. Wenn alles korrekt funktioniert, sollten Sie das Logo „Python Powered“ sehen.

8e5c3ead11cfd103.png

8. Glückwunsch!

b158ce75c3cccd6d.png

Sie haben HTTP Cloud Functions bereitgestellt und dabei idiomatische Funktionen verwendet, die Webanfragen mit dem Flask-Framework verarbeiten.

Die Preise für Cloud Functions richten sich danach, wie oft Ihre Funktion aufgerufen wird. Es gibt eine kostenlose Stufe für Funktionen, die nicht oft ausgeführt werden. Nachdem Sie Ihre Cloud Functions-Funktionen getestet haben, können Sie sie mit gcloud löschen:

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

Sie können die Funktionen auch über die Google Cloud Console löschen.

Wir hoffen, dass Ihnen die Verwendung von Cloud Functions in Python gefällt.