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 Ihren Code schreiben, ohne sich Gedanken über die Bereitstellung von Ressourcen oder die Skalierung für sich ändernde Anforderungen machen zu müssen.

Es gibt zwei Arten von Cloud Functions-Funktionen:

  • HTTP-Funktionen reagieren auf HTTP-Anfragen. In diesem Codelab erstellen Sie einige davon.
  • Hintergrundfunktionen werden durch Ereignisse ausgelöst, z. B. durch das Veröffentlichen einer Nachricht in Cloud Pub/Sub oder das Hochladen einer Datei in Cloud Storage. In diesem Lab wird darauf nicht näher eingegangen. Weitere Informationen finden Sie jedoch 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 bei Aufruf über HTTP das Logo „Python Powered“ anzeigt:

a7aaf656b78050fd.png

Lerninhalte

  • HTTP-Cloud Functions-Funktion schreiben
  • HTTP-Cloud Functions-Funktion schreiben, die Argumente akzeptiert
  • HTTP-Cloud Functions-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.pnga99b7ace416376c4.png5e3ff691252acf41.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). Die Cloud Console generiert automatisch einen eindeutigen String. In der Regel ist es egal, wie dieser lautet. In den meisten Codelabs müssen Sie auf Ihre Projekt-ID verweisen (normalerweise als PROJECT_ID gekennzeichnet). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige ID generieren. Alternativ können Sie auch einen eigenen Namen ausprobieren und prüfen, 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, eine Projektnummer, die von einigen 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 und ‑APIs verwenden zu können. Die Kosten für dieses Codelab sind gering, wenn überhaupt welche anfallen. Wenn Sie Ressourcen herunterfahren möchten, um zu vermeiden, dass Ihnen über diese Anleitung hinaus Kosten in Rechnung gestellt werden, können Sie die erstellten Ressourcen oder das Projekt löschen. Neue Google Cloud-Nutzer kommen für das Programm für die kostenlose Testversion mit einem Guthaben von 300 $ infrage.

Cloud Shell starten

Google Cloud kann zwar remote von Ihrem Laptop aus bedient werden, in diesem Codelab verwenden Sie jedoch die 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.

3c1dabeca90e44e5.png

Wenn Sie Cloud Shell zum ersten Mal starten, wird ein Fenster mit einer Beschreibung eingeblendet. Klicken Sie in diesem Fall 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 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 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 API und die Cloud Build API aktiviert sind.

Führen Sie in Cloud Shell den folgenden Befehl 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. Einführung in HTTP-Cloud Functions

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 einem Befehlszeileneditor Ihrer Wahl (nano, vim oder emacs) öffnen. Sie können sie auch im Cloud Shell-Editor öffnen, nachdem Sie das Quellverzeichnis als Arbeitsbereich festgelegt haben:

cloudshell open-workspace .

Stellen Sie diese Funktion mit dem Befehl gcloud functions deploy als HTTP-Cloud Functions-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. 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 Funktionsausführung aus.
  • --allow-unauthenticated: Die Funktion ist öffentlich und lässt alle Aufrufer ohne Authentifizierungsprüfung zu.
  • Weitere Informationen finden Sie unter gcloud functions deploy.

Wenn Sie die Funktion testen möchten, klicken Sie auf die URL httpsTrigger.url, die in der obigen 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 mit Argumenten schreiben

Funktionen sind vielseitiger, wenn sie Argumente akzeptieren. Wir definieren 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 Sie 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, klicken Sie auf die URL httpsTrigger.url, die in der obigen 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

Diesmal erhalten Sie Ihre benutzerdefinierte Antwort:

Hello YOUR NAME! 🚀

Als Nächstes fügen Sie Unittests hinzu, um sicherzustellen, dass Ihre Funktionen auch nach einer Aktualisierung des Quellcodes wie vorgesehen funktionieren.

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 erbt.
  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 heißt, er wird durch ein fiktives Objekt mit den für den Test erforderlichen Daten ersetzt.
  5. Nach dem Aufrufen der einzelnen Funktionen prüft der Test die HTTP-Antwort, um sicherzugehen, dass sie den 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 ein Ergebnis, das in etwa so aussieht:

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

Führen Sie diese Tests lokal aus:

python -m unittest

Die drei Unit-Tests sollten erfolgreich sein:

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

OK

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

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

Wir erstellen jetzt eine neue Funktion, die für jede Anfrage das Bild „Python Powered“ zurückgibt:

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 URL httpsTrigger.url, die in der obigen Befehlsausgabe angezeigt wird. Wenn alles korrekt funktioniert, sehen Sie das „Python Powered“-Logo in einem neuen Browsertab.

Als Nächstes erstellen Sie eine Anwendung, 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 Webanwendung erstellen und Ihre 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. Mit dieser Datei wird eine Flask-Anwendung erstellt.
  2. Es wird eine Route unter der Basis-URL registriert, 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 ein Ergebnis, das in etwa so aussieht:

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 Webanwendung im Browser. Klicken Sie in Cloud Shell auf den Button „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, sehen Sie jetzt das „Python Powered“-Logo.

8e5c3ead11cfd103.png

8. Glückwunsch!

b158ce75c3cccd6d.png

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

Die Preise für Cloud Functions richten sich danach, wie oft Ihre Funktion aufgerufen wird. Für Funktionen, die nicht oft ausgeführt werden, gibt es eine kostenlose Stufe. 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 wünschen Ihnen viel Spaß mit Cloud Functions in Python!