Python-Laufzeit

Die Python-Laufzeit ist das Softwarepaket, das für die Installation Ihres Anwendungscodes und der Abhängigkeiten sowie für die Ausführung dieser Anwendung in der flexiblen Umgebung verantwortlich ist.

  • Die Versionen 3.8 und höher werden mit Buildpacks erstellt. Dazu müssen Sie ein Betriebssystem in der app.yaml-Datei auswählen. Wenn Sie beispielsweise Python 3.12 verwenden möchten, müssen Sie Ubuntu 22 als Betriebssystem angeben.

  • Version 3.7 und früher werden mit Docker erstellt.

Eine vollständige Liste der unterstützten Phyton-Versionen und der entsprechenden Ubuntu-Versionen finden Sie im Laufzeitsupportzeitplan.

Neue Laufzeitversionen

Für die Python-Laufzeit Version 3.8 und höher müssen Sie die Einstellungen runtime_config und operating_system in die Datei app.yaml aufnehmen, um ein Betriebssystem anzugeben.

Zur Verwendung der neuen Laufzeiten müssen Sie die gcloud-CLI-Version 420.0.0 oder höher installieren. Sie können die Befehlszeilentools mit dem Befehl gcloud components update aktualisieren. Führen Sie den Befehl gcloud version aus, um die installierte Version aufzurufen.

Optional: Sie können eine Laufzeitversion angeben. Nehmen Sie dazu die Einstellung runtime_version in die Datei app.yaml auf. Standardmäßig wird die neueste Python-Version verwendet, wenn die Einstellung runtime_version nicht angegeben ist.

Beispiele

  • So geben Sie Python 3.12 auf Ubuntu 22 an:

    runtime: python
    env: flex
    entrypoint: gunicorn -b :$PORT main:app
    
    runtime_config:
        operating_system: "ubuntu22"
        runtime_version: "3.12"
    
  • So geben Sie die neueste unterstützte Python-Version unter Ubuntu 22 an:

      runtime: python
      env: flex
      entrypoint: gunicorn -b :$PORT main:app
    
      runtime_config:
          operating_system: "ubuntu22"
    

Weitere Informationen finden Sie auf der Referenzseite app.yaml.

Vorherige Laufzeitversionen

Für Python Version 3.7 und früher geben Sie eine Version mit den Einstellungen runtime_config und python_version in der Datei app.yaml Ihrer Anwendung an.

Beispiel

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
    python_version: 3.7

Bei den Python-Versionen 3.7 und früher ist der Standard-Interpreter Python 2.7.12, wenn runtime_config oder python_version weggelassen wird. Sie können beispielsweise die Standardlaufzeit verwenden. Geben Sie dazu runtime: python in der Datei app.yaml an:

runtime: python
env: flex

Weitere Informationen finden Sie auf der Referenzseite app.yaml.

Die Interpreter, die für jede -Einstellung bereitgestellt werden, sind in der folgenden Tabelle aufgeführt:

python_version-Einstellung Bereitgestellter Interpreter Laufzeit-ID Beispiel für app.yaml
2 (Standardeinstellung) 2.7.12 python2 runtime_config:
python_version: 2
3.4 3.4.8 python34 runtime_config:
python_version: 3.4
3.5 3.5.9 python35 runtime_config:
python_version: 3.5
3 oder 3.6 3.6.10 python36 runtime_config:
python_version: 3
3.7 3.7.9 python37 runtime_config:
python_version: 3.7

Weitere Unterstützung für Python-Laufzeiten

Wenn die gewünschte Python-Version nicht aufgeführt ist, gibt es mehrere Optionen:

  1. Flexible App Engine-Umgebung: Erstellen Sie eine benutzerdefinierte Laufzeit und wählen Sie ein gültiges Basis-Image mit der benötigten Python-Version aus.
  2. App Engine-Standardumgebung: Python 3.7, 3.8, 3.9, 3.10 und 3.11 werden unterstützt.
  3. Cloud Functions: Python 3.7, 3.8, 3.9 und 3.10 werden unterstützt.
  4. Cloud Run: Containerisieren Sie Ihre Anwendung basierend auf einem Container-Image für die benötigte Python-Version (siehe Python-Kurzanleitung). Da bereits Python 3.10-Images verfügbar sind, können Sie diese Version noch heute bereitstellen.

Informationen zur flexiblen App Engine-Umgebung oder zu Cloud Run finden Sie unter Benutzerdefinierte Laufzeiten erstellen für von Google bereitgestellte Basis-Images oder unter Docker-Basis-Images für Python für derzeit verfügbare Python-Images, einschließlich Python 2-Image-Informationen.

Weitere Informationen zur Containerisierung von App Engine-Anwendungen für Cloud Run finden Sie im Codelab und in den Videoinhalten zur Containerisierung mit Docker oder ohne Docker. Beachten Sie, dass diese Inhalte derzeit nur auf Migrationen von der App Engine-Standardumgebung zu Cloud Run eingehen.

Abhängigkeiten

Die Laufzeit sucht im Quellverzeichnis der Anwendung nach der Datei requirements.txt und verwendet pip, um Abhängigkeiten zu installieren, bevor die Anwendung gestartet wird. Weitere Informationen zur Deklaration und Verwaltung von Paketen finden Sie unter Python-Bibliotheken verwenden.

Wenn Ihre Anwendung private Abhängigkeiten erfordert, müssen Sie zur Installation der entsprechenden Pakete eine benutzerdefinierte Laufzeit verwenden, die auf der Python-Laufzeit basiert.

C-Bibliotheken mit Ruby verwenden

Die Header für die aktuelle Python-Version und die folgenden Ubuntu-Pakete sind auf dem System vorinstalliert, um die Verwendung von Python-Paketen zu ermöglichen, die C-Erweiterungen erfordern:

  • build-essential
  • ca-certificates
  • curl
  • gfortran
  • git
  • libatlas-dev
  • libblas-dev
  • libcurl4-openssl-dev
  • libffi-dev
  • libfreetype6-dev
  • libjpeg-dev
  • liblapack-dev
  • libmemcached-dev
  • libmysqlclient-dev
  • libpng12-dev
  • libpq-dev
  • libquadmath0
  • libsasl2-2
  • libsasl2-dev
  • libsasl2-modules
  • libsqlite3-dev
  • libssl-dev
  • libxml2-dev
  • libxslt1-dev
  • libz-dev
  • mercurial
  • netbase
  • pkg-config
  • sasl2-bin
  • swig
  • wget
  • zlib1g-dev

Diese Pakete ermöglichen die Installation der gängigsten Python-Bibliotheken. Wenn Ihre Anwendung zusätzliche Abhängigkeiten auf Betriebssystemebene erfordert, müssen Sie eine auf dieser Laufzeit basierende benutzerdefinierte Laufzeit verwenden, um die entsprechenden Pakete zu installieren.

Anwendungsstart

Die Laufzeit startet Ihre Anwendung mit dem in der Datei app.yaml definierten entrypoint. Der Einstiegspunkt sollte einen Prozess starten, der auf HTTP-Anfragen an dem von der Umgebungsvariablen PORT definierten Port antwortet.

Die meisten Webanwendungen verwenden einen WSGI-Server wie Gunicorn, uWSGI oder Waitress.

Bevor Sie einen dieser Server verwenden können, müssen Sie ihn als Abhängigkeit in die requirements.txt-Datei Ihrer Anwendung aufnehmen. Wenn Sie gunicorn für Ihre Flask-Anwendung verwenden, achten Sie darauf, dass die Python-Version Ihrer Anwendung mit gunicorn kompatibel ist.

Die Laufzeit stellt sicher, dass alle Abhängigkeiten installiert sind, bevor der Einstiegspunkt aufgerufen wird.

Flask==2.0.2
gunicorn==20.1.0

Beispiel für einen Einstiegspunkt unter Verwendung von Gunicorn für eine Flask-Anwendung:

entrypoint: gunicorn -b :$PORT main:app

Beispiel für einen Einstiegspunkt unter Verwendung von Gunicorn für eine Django-Anwendung:

entrypoint: gunicorn -b :$PORT mydjangoapp:wsgi

Gunicorn ist der empfohlene WSGI-Server, aber es ist durchaus möglich, einen anderen WSGI-Server zu verwenden. Das folgende Beispiel zeigt einen Einstiegspunkt, der uWSGI mit Flask verwendet:

entrypoint: uwsgi --http :$PORT --wsgi-file main.py --callable app

Für Anwendungen, die Requests ohne einen WSGI-Server verarbeiten können, müssen Sie lediglich ein Python-Script ausführen:

entrypoint: python main.py

Die einfachen oben aufgeführten entrypoint-Beispiele dienen als Ausgangspunkte und funktionieren möglicherweise mit Ihren Webanwendungen. Die meisten Anwendungen erfordern jedoch eine zusätzliche Konfiguration des WSGI-Servers. Statt alle Einstellungen für den Einstiegspunkt anzugeben, sollten Sie die Datei gunicorn.conf.py im Stammverzeichnis Ihres Projekts erstellen, in dem sich die Datei app.yaml befindet, und sie als Einstiegspunkt festlegen:

entrypoint: gunicorn -c gunicorn.conf.py -b :$PORT main:app

Weitere Informationen zu sämtlichen Konfigurationswerten von Gunicorn finden Sie in der zugehörigen Dokumentation.

Worker

Gunicorn verwendet Worker, um Requests zu bearbeiten. Gunicorn verwendet standardmäßig sync workers. Diese Worker-Klasse ist mit allen Webanwendungen kompatibel, aber jeder Worker kann jeweils nur einen Request bearbeiten. Gunicorn verwendet standardmäßig nur diese Worker. Dies kann häufig dazu führen, dass Ihre Instanzen nicht ausreichend ausgelastet sind und die Latenz in Anwendungen mit hoher Auslastung steigt.

Wir empfehlen, die Anzahl der Worker auf das 2- bis 4-Fache der Anzahl der CPU-Kerne für Ihre Instanz plus eins zu setzen. Sie können dies in gunicorn.conf.py folgendermaßen angeben:

import multiprocessing

workers = multiprocessing.cpu_count() * 2 + 1

Außerdem können einige Webanwendungen, die hauptsächlich I/O-gebunden sind, eine Leistungsverbesserung durch Verwendung einer anderen Worker-Klasse feststellen. Wenn Ihre Worker-Klasse zusätzliche Abhängigkeiten wie gevent oder tornado benötigt, müssen diese in der Datei requirements.txt Ihrer Anwendung deklariert werden.

HTTPS- und Weiterleitungs-Proxys

App Engine beendet die HTTPS-Verbindung am Load-Balancer und leitet die Anfrage zu Ihrer Anwendung weiter. Für die meisten Anwendungen müssen Sie nicht wissen, ob die Anfrage über HTTPS gesendet wurde. Für Anwendungen, die diese Informationen benötigen, sollte Gunicorn jedoch so konfiguriert werden, dass dem App Engine-Proxy in ihrer gunicorn.conf.py-Datei vertraut wird:

forwarded_allow_ips = '*'
secure_scheme_headers = {'X-FORWARDED-PROTO': 'https'}

Gunicorn stellt nun sicher, dass das auf wsgi.url_scheme festgelegte 'https', das die meisten Web-Frameworks als Hinweis auf die Anfrage verwenden, sicher ist. Wenn Ihr WSGI-Server oder -Framework dies nicht unterstützt, prüfen Sie den Wert des Headers X-Forwarded-Proto einfach manuell.

Einige Anwendungen müssen auch die IP-Adresse des Nutzers ermitteln. Diese Funktion ist im Header X-Forwarded-For verfügbar.

Beachten Sie, dass die Einstellung secure_scheme_headers in gunicorn.conf.py großgeschrieben werden muss, z. B. X-FORWARDED-PROTO. Die von Ihrem Code gelesenen Header werden hingegen in Klein- und Großbuchstaben geschrieben, z. B. X-Forwarded-Proto.

Laufzeit erweitern

Die flexible Python-Laufzeitumgebung kann zur Erstellung einer benutzerdefinierten Laufzeit verwendet werden. Weitere Informationen finden Sie unter Python anpassen.

Umgebungsvariablen

Die folgenden Umgebungsvariablen werden durch die Laufzeitumgebung festgelegt:

Umgebungsvariable Beschreibung
GAE_INSTANCE Der Name der aktuellen Instanz
GAE_MEMORY_MB Die Größe des für den Anwendungsprozess verfügbaren Speichers
GAE_SERVICE Der in der Datei app.yaml Ihrer Anwendung angegebene Dienstname. Wenn kein Dienstname angegeben ist, wird als Wert default festgelegt.
GAE_VERSION Das Versionslabel der aktuellen Anwendung
GOOGLE_CLOUD_PROJECT Die mit Ihrer Anwendung verknüpfte Projekt-ID, die in der Google Cloud Console angezeigt wird
PORT Der Port, der HTTP-Anfragen empfängt

Sie können in der Datei app.yaml noch weitere Umgebungsvariablen festlegen.

Metadatenserver

Jede Instanz Ihrer Anwendung kann den Compute Engine-Metadatenserver verwenden, um Informationen über die Instanz abzufragen, einschließlich ihres Hostnamens, ihrer externen IP-Adresse, Instanz-ID, benutzerdefinierten Metadaten und Dienstkontoinformationen. Sie können in App Engine nicht für jede einzelne Instanz benutzerdefinierte Metadaten festlegen. Sie haben aber die Möglichkeit, projektweite benutzerdefinierte Metadaten festzulegen und diese aus den App Engine- und Compute Engine-Instanzen zu lesen.

Diese Beispielfunktion ruft die externe IP-Adresse der Instanz über den Metadatenserver ab:

METADATA_NETWORK_INTERFACE_URL = (
    "http://metadata/computeMetadata/v1/instance/network-interfaces/0/"
    "access-configs/0/external-ip"
)

def get_external_ip():
    """Gets the instance's external IP address from the Compute Engine metadata
    server.

    If the metadata server is unavailable, it assumes that the application is running locally.

    Returns:
        The instance's external IP address, or the string 'localhost' if the IP address
        is not available.
    """
    try:
        r = requests.get(
            METADATA_NETWORK_INTERFACE_URL,
            headers={"Metadata-Flavor": "Google"},
            timeout=2,
        )
        return r.text
    except requests.RequestException:
        logging.info("Metadata server could not be reached, assuming local.")
        return "localhost"