HTTP-Funktionen von Cloud Functions in Python

1. Einführung

b158ce75c3cccd6d.png

Python ist eine beliebte Open-Source-Programmiersprache, die unter anderem von Data Scientists, Entwicklern von Webanwendungen und Systemadministratoren 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 eine Skalierung für sich ändernde 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. eine Nachricht, die in Cloud Pub/Sub veröffentlicht wird, oder eine Datei, die in Cloud Storage hochgeladen wird. Damit wird in diesem Lab nicht behandelt. Weitere Informationen finden Sie in der Dokumentation.

efb3268e3b74ed4f.png

In diesem Codelab erfahren Sie, wie Sie eigene Cloud Functions-Funktionen in Python erstellen.

Aufgaben

In diesem Codelab veröffentlichen Sie eine Cloud Functions-Funktion, die beim Aufrufen über HTTP die Meldung „Python Powered“ Logo:

a7aaf656b78050fd.png

Lerninhalte

  • Cloud Functions-HTTP-Funktion schreiben
  • Hier erfahren Sie, wie Sie eine Cloud Functions-HTTP-Funktion schreiben, die Argumente annimmt.
  • Cloud Functions-HTTP-Funktion testen
  • Hier erfahren Sie, wie Sie einen lokalen Python-HTTP-Server ausführen, um die Funktion auszuprobieren.
  • Hier erfahren Sie, wie Sie eine Cloud Functions-HTTP-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 Projektteilnehmer. Es handelt sich um eine Zeichenfolge, die von Google APIs nicht verwendet wird. Sie können sie jederzeit aktualisieren.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich. Sie kann nach dem Festlegen nicht mehr geändert werden. Die Cloud Console generiert automatisch einen eindeutigen String. ist Ihnen meist egal, was es ist. In den meisten Codelabs musst du auf deine Projekt-ID verweisen, die üblicherweise als PROJECT_ID bezeichnet wird. Wenn Ihnen die generierte ID nicht gefällt, können Sie eine weitere zufällige ID generieren. Alternativ können Sie einen eigenen verwenden und nachsehen, ob er verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts erhalten.
  • Zur Information gibt es noch einen dritten Wert, die Projektnummer, die von manchen APIs verwendet wird. Weitere Informationen zu allen drei Werten finden Sie in der Dokumentation.
  1. Als Nächstes müssen Sie in der Cloud Console die Abrechnung aktivieren, um Cloud-Ressourcen/APIs verwenden zu können. Dieses Codelab ist kostengünstig. Sie können die von Ihnen erstellten Ressourcen oder das Projekt löschen, um Ressourcen herunterzufahren, um zu vermeiden, dass über diese Anleitung hinaus Kosten anfallen. Neue Google Cloud-Nutzer haben Anspruch auf das kostenlose Testprogramm mit 300$Guthaben.

Cloud Shell starten

Sie können Google Cloud zwar von Ihrem Laptop aus der Ferne bedienen, in diesem Codelab verwenden Sie jedoch Cloud Shell, 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.

5c1dabeca90e44e5.png

Wenn Sie Cloud Shell zum ersten Mal starten, wird ein Zwischenbildschirm mit einer Beschreibung der Funktion angezeigt. Wenn ein Zwischenbildschirm angezeigt wird, klicken Sie auf Weiter.

9c92662c6a846a5c.png

Die Bereitstellung und Verbindung mit Cloud Shell dauert nur einen Moment.

9f0e51b578fecce5.png

Diese virtuelle Maschine verfügt über alle erforderlichen Entwicklertools. Es bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und wird in Google Cloud ausgeführt. Dadurch werden die Netzwerkleistung und die Authentifizierung erheblich verbessert. Viele, wenn nicht sogar alle Arbeiten in diesem Codelab können mit einem Browser erledigt werden.

Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie authentifiziert sind und das Projekt auf Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in 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 in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob 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 und Cloud Build APIs aktiviert sind

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

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

Hinweis: Cloud Build wird mit dem Befehl gcloud functions deploy aufgerufen und erstellt den Code automatisch in einem Container-Image.

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 folgende Dateien haben:

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

3. Einführung in HTTP-Cloud Functions-Funktionen

HTTP-Cloud Functions-Funktionen in Python werden als reguläre Python-Funktionen geschrieben. Die Funktion muss ein einzelnes flask.Request-Argument akzeptieren, das normalerweise den Namen request hat.

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 Ihrem bevorzugten Befehlszeileneditor öffnen (Nano, Vim oder Emacs). Sie können die Datei auch im Cloud Shell-Editor öffnen, nachdem Sie das Quellverzeichnis als Arbeitsbereich festgelegt haben:

cloudshell open-workspace .

Stellen wir diese Funktion mit dem Befehl gcloud functions deploy als Cloud Functions-HTTP-Funktion 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. Bei Python kann dies derzeit python37, python38, python39, python310 oder python312 sein. Siehe 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 lässt alle Aufrufer zu, ohne dass die Authentifizierung geprüft wird.
  • Weitere Informationen finden Sie unter gcloud Functions deploy.

Zum Testen der Funktion können Sie auf die URL httpsTrigger.url klicken, die in der Befehlsausgabe oben 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. Cloud Functions-HTTP-Funktion schreiben, die Argumente annimmt

Funktionen sind vielseitiger einsetzbar, wenn sie Argumente akzeptieren. Lassen Sie uns eine neue Funktion hello_name definieren, die einen name-Parameter 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
...

Zum Testen der Funktion können Sie auf die URL httpsTrigger.url klicken, die in der Befehlsausgabe oben 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 sehen:

Hello World! 🚀

Sie erhalten das Standardergebnis, weil das Argument name nicht festgelegt ist. Parameter zur URL hinzufügen:

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

Dieses Mal erhalten Sie Ihre benutzerdefinierte Antwort:

Hello YOUR NAME! 🚀

Fügen Sie als Nächstes Einheitentests hinzu, um sicherzustellen, dass Ihre Funktionen nach der Aktualisierung des Quellcodes weiterhin wie vorgesehen funktionieren.

5. Tests schreiben

HTTP-Funktionen von Cloud Functions in Python werden mit dem Modul unittest aus der Standardbibliothek getestet. Sie müssen zum Testen Ihrer Funktion keinen Emulator oder eine andere Simulation ausführen, sondern einfach normalen Python-Code verwenden.

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 die gleiche Weise wie andere Python-Dateien geschrieben. Sie beginnen mit einer Reihe von Importen und definieren dann Klassen und Funktionen.
  2. Die Testdeklaration hat das Format class TestHello(TestCase). Es muss sich um eine Klasse handeln, die Werte von unittest.TestCase übernimmt.
  3. Die Testklasse enthält Methoden, von denen jede mit test_ beginnen muss. Sie stehen für individuelle Testfälle.
  4. In jedem Testlauf wird eine unserer Funktionen getestet, indem der request-Parameter simuliert wird. Das heißt, er wird durch ein fiktives Objekt mit den für den Test erforderlichen spezifischen Daten ersetzt.
  5. Nach dem Aufrufen jeder Funktion prüft der Test die HTTP-Antwort, um sicherzustellen, dass sie unseren Erwartungen entspricht.

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

pip install flask

Die Installation von Flask liefert in etwa folgendes Ergebnis:

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

Führen Sie diese Tests lokal aus:

python -m unittest

Die drei Einheitentests sollten bestanden werden:

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

OK

Als Nächstes erstellen Sie eine neue Funktion, die den Fehler "Python Powered" Logo.

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

Um eine neue Funktion etwas unterhaltsamer zu gestalten, geben wir die Bild für jede Anfrage:

a7aaf656b78050fd.png

Hier sehen Sie den entsprechenden Code:

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 URL httpsTrigger.url, die in der Befehlsausgabe oben angezeigt wird. Wenn alles ordnungsgemäß funktioniert, wird die Meldung "Python Powered" -Logo in einem neuen Browsertab.

Als Nächstes erstellen Sie eine Anwendung, damit Sie die 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 Webanwendung erstellen und die Funktion in einer Route 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. Diese Datei erstellt eine Flask-Anwendung.
  2. Sie registriert eine Route unter der Basis-URL, die mit einer Funktion namens index() verarbeitet wird.
  3. Die Funktion index() ruft dann die 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

Die Installation von Flask liefert in etwa folgendes Ergebnis:

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

Verwenden Sie jetzt die Cloud Shell-Webvorschau, um die Webanwendung in Ihrem Browser zu testen. Klicken Sie in Cloud Shell auf „Webvorschau“. und wählen Sie "Vorschau auf Port 8080" aus:

6c9ff9e5c692c58e.gif

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

8e5c3ead11cfd103.png

8. Glückwunsch!

b158ce75c3cccd6d.png

Sie haben Cloud Functions-HTTP-Funktionen mit idiomatischen Funktionen bereitgestellt, die Webanfragen mit dem Flask-Framework verarbeiten.

Die Cloud Functions-Preise richten sich danach, wie oft Ihre Funktion aufgerufen wird. Es gibt auch eine kostenlose Stufe für Funktionen, die selten ausgeführt werden. Wenn Sie mit dem Testen der Cloud Functions-Funktionen fertig sind, 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 wünschen Ihnen viel Spaß mit Cloud Functions in Python!