Environnement d'exécution Python

L'environnement d'exécution Python est la pile logicielle chargée d'installer le code et les dépendances de votre application, puis d'exécuter cette application dans l'environnement flexible.

  • Les versions 3.8 et ultérieures sont créées à l'aide de packs de création, ce qui nécessite de choisir un système d'exploitation dans votre fichier app.yaml. Par exemple, pour utiliser Python 3.12, vous devez spécifier Ubuntu 22 comme système d'exploitation.

  • Les versions 3.7 et antérieures sont créées à l'aide de Docker.

Pour obtenir la liste complète des versions de Python compatibles, ainsi que la version d'Ubuntu correspondante, consultez la page Programmation de la compatibilité avec l'environnement d'exécution.

Nouvelles versions de l'environnement d'exécution

Pour l'environnement d'exécution Python version 3.8 et pour les versions ultérieures, vous devez inclure les paramètres runtime_config et operating_system dans votre fichier app.yaml afin de spécifier un système d'exploitation.

Pour utiliser les nouveaux environnements d'exécution, vous devez installer les versions 420.0.0 ou ultérieures de gcloud CLI. Vous pouvez mettre à jour les outils de la CLI en exécutant la commande gcloud components update. Pour afficher la version installée, exécutez la commande gcloud version.

Facultatif : Vous pouvez spécifier une version d'exécution en incluant le paramètre runtime_version dans votre fichier app.yaml. Par défaut, la dernière version de Python est utilisée si le paramètre runtime_version n'est pas spécifié.

Exemples

  • Pour spécifier Python 3.12 sur Ubuntu 22 :

    runtime: python
    env: flex
    entrypoint: gunicorn -b :$PORT main:app
    
    runtime_config:
        operating_system: "ubuntu22"
        runtime_version: "3.12"
    
  • Pour spécifier la dernière version compatible de Python sur Ubuntu 22, procédez comme suit :

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

Pour en savoir plus, consultez la page de référence app.yaml.

Versions précédentes de l'environnement d'exécution

Pour les versions 3.7 et antérieures de Python, vous spécifiez une version à l'aide des paramètres runtime_config et python_version dans le fichier app.yaml de votre application.

Exemple

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

runtime_config:
    python_version: 3.7

Pour les versions d'exécution 3.7 et antérieures de Python, l'interpréteur par défaut est Python 2.7.12 si runtime_config ou python_version sont omis. Par exemple, vous pouvez utiliser l'environnement d'exécution par défaut en spécifiant runtime: python dans votre fichier app.yaml :

runtime: python
env: flex

Pour en savoir plus, consultez la page de référence app.yaml.

Les interpréteurs déployés pour chaque paramètre de version sont présentés dans le tableau suivant :

Paramètre python_version Interpréteur déployé ID d'exécution Exemple app.yaml
2 (par défaut) 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 ou 3.6 3.6.10 python36 runtime_config:
python_version: 3
3.7 3.7.9 python37 runtime_config:
python_version: 3.7

Autres fonctionnalités d'exécution Python

Si la version Python souhaitée n'est pas répertoriée, plusieurs options s'offrent à vous :

  1. Environnement flexible App Engine : créez un environnement d'exécution personnalisé et sélectionnez une image de base valide avec la version Python dont vous avez besoin.
  2. Environnement standard App Engine : Python 3.7, 3.8, 3.9 3.10 et 3.11 sont compatibles.
  3. Cloud Functions : Python 3.7, 3.8, 3.9 et 3.10 sont compatibles.
  4. Cloud Run : conteneurisez votre application à partir d'une image de conteneur pour la version Python dont vous avez besoin (consultez le guide de démarrage rapide pour Python correspondant). Les images Python 3.10 étant déjà disponibles, vous pouvez déployer cette version dès aujourd'hui.

Pour l'environnement flexible App Engine ou Cloud Run, consultez la section Créer des environnements d'exécution personnalisés pour les images de base fournies par Google ou les images de base Python Docker pour les images Python actuellement disponibles, y compris des informations concernant les images Python 2.

Pour examiner plus en détail la conteneurisation d'applications App Engine pour Cloud Run, consultez l'atelier de programmation et le contenu vidéo couvrant la conteneurisation avec Docker ou sans Docker. Notez que ce contenu ne couvre actuellement que les migrations de l'environnement standard App Engine vers Cloud Run.

Dépendances

L'environnement d'exécution recherche un fichier requirements.txt dans le répertoire source de votre application et, avant de démarrer cette dernière, utilise pip pour installer les dépendances. Pour plus d'informations sur la déclaration et la gestion des packages, consultez Utiliser les bibliothèques Python.

Si votre application nécessite des dépendances privées, vous devez utiliser un environnement d'exécution personnalisé basé sur l'environnement d'exécution Python pour installer les packages appropriés.

Utiliser les bibliothèques C avec Python

Pour permettre l'utilisation de packages Python nécessitant des extensions C, les en-têtes correspondant à la version actuelle de Python ainsi que les packages Ubuntu suivants sont préinstallés sur le système :

  • 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

Ces packages permettent d'installer les bibliothèques Python les plus populaires. Si votre application possède des dépendances supplémentaires au niveau du système d'exploitation, vous devrez utiliser un environnement d'exécution personnalisé basé sur l'environnement d'exécution standard pour installer les packages appropriés.

Démarrage de l'application

L'environnement d'exécution démarre l'application à l'aide de l'élément entrypoint défini dans votre fichier app.yaml. Le point d'entrée doit démarrer un processus qui répond aux requêtes HTTP sur le port défini par la variable d'environnement PORT.

La plupart des applications Web utilisent un serveur WSGI, tel que Gunicorn, uWSGI ou Waitress.

Avant de pouvoir utiliser l'un de ces serveurs, vous devez l'ajouter en tant que dépendance dans le fichier requirements.txt de votre application. Si vous utilisez gunicorn pour votre application Flask, assurez-vous que la version de Python de votre application est compatible avec gunicorn.

L'environnement d'exécution s'assure que toutes les dépendances sont installées avant d'appeler votre point d'entrée.

Flask==2.0.2
gunicorn==20.1.0

Voici un exemple de point d'entrée utilisant Gunicorn pour une application Flask :

entrypoint: gunicorn -b :$PORT main:app

Voici un exemple de point d'entrée utilisant Gunicorn pour une application Django :

entrypoint: gunicorn -b :$PORT mydjangoapp:wsgi

Gunicorn est le serveur WSGI recommandé, mais il est tout à fait possible d'utiliser un autre serveur WSGI. Par exemple, voici un point d'entrée qui utilise uWSGI avec Flask :

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

Pour les applications capables de gérer des requêtes sans serveur WSGI, vous pouvez simplement exécuter un script Python :

entrypoint: python main.py

Les exemples élémentaires de points d'entrée présentés ci-dessus sont destinés à servir de points de départ et peuvent convenir à vos applications Web. Cependant, la plupart des applications nécessitent une configuration plus avancée du serveur WSGI. Au lieu de spécifier tous les paramètres du point d'entrée, créez un fichier gunicorn.conf.py dans le répertoire racine de votre projet, dans lequel se trouve le fichier app.yaml, et spécifiez-le dans votre point d'entrée :

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

La documentation Gunicorn vous renseignera davantage sur toutes les valeurs de configuration que vous pouvez définir.

Travailleurs

Gunicorn utilise des travailleurs pour traiter les requêtes. Par défaut, Gunicorn utilise des travailleurs synchrones. Cette classe est compatible avec toutes les applications Web, mais chaque travailleur ne peut gérer qu'une requête à la fois. Par défaut, Gunicorn n'en utilise qu'un. Cette manière de procéder peut souvent entraîner une sous-utilisation des instances et une latence accrue lorsque les applications sont soumises à une charge élevée.

Nous vous recommandons de définir un nombre de travailleurs compris entre 2 et 4 fois le nombre de cœurs de processeur de l'instance, plus un. Vous pouvez le spécifier dans le fichier gunicorn.conf.py comme suit :

import multiprocessing

workers = multiprocessing.cpu_count() * 2 + 1

De plus, avec certaines applications Web principalement liées aux E/S, vous pouvez constater une amélioration des performances en utilisant une classe de travailleur différente. Si votre classe de nœud de calcul nécessite des dépendances supplémentaires, telles que gevent ou tornado, ces dépendances doivent être déclarées dans le fichier requirements.txt de votre application.

HTTPS et proxy de transfert

App Engine met fin à la connexion HTTPS au niveau de l'équilibreur de charge et transfère la requête à l'application. La plupart des applications n'ont pas besoin de savoir si la requête a été envoyée via HTTPS ou non, mais celles qui ont besoin de ces informations doivent configurer Gunicorn pour approuver le proxy App Engine dans leur fichier gunicorn.conf.py :

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

Gunicorn va maintenant s'assurer que l'élément wsgi.url_scheme est défini sur 'https', ce que la plupart des frameworks Web interpréteront comme indiquant que la requête est sécurisée. Si votre serveur ou framework WSGI ne le permet pas, vérifiez manuellement la valeur de l'en-tête X-Forwarded-Proto.

Certaines applications doivent également vérifier l'adresse IP de l'utilisateur. Cette option est disponible dans l'en-tête X-Forwarded-For.

Le paramètre secure_scheme_headers dans le fichier gunicorn.conf.py doit être en majuscules (par exemple, X-FORWARDED-PROTO), mais les en-têtes que votre code peut lire contiendront à la fois des lettres majuscules et minuscules (par exemple, X-Forwarded-Proto).

Étendre l'environnement d'exécution

L'environnement d'exécution flexible Python peut être utilisé pour créer un environnement d'exécution personnalisé. Pour en savoir plus, consultez la section Personnaliser l'environnement d'exécution Python.

Variables d'environnement

Les variables d'environnement suivantes sont définies par l'environnement d'exécution :

Variable d'environnement Description
GAE_INSTANCE Le nom de l'instance actuelle.
GAE_MEMORY_MB La quantité de mémoire disponible pour le processus d'application.
GAE_SERVICE Nom du service spécifié dans le fichier app.yaml de votre application. Si aucun nom de service n'est spécifié, il est défini sur default.
GAE_VERSION Libellé de version de l'application en cours.
GOOGLE_CLOUD_PROJECT ID du projet associé à votre application, visible dans Google Cloud Console.
PORT Port qui reçoit les requêtes HTTP.

Vous pouvez définir des variables d'environnement supplémentaires dans le fichier app.yaml.

Serveur de métadonnées

Chaque instance de votre application peut utiliser le serveur de métadonnées Compute Engine pour rechercher des informations sur l'instance, y compris son nom d'hôte, son adresse IP externe, son ID d'instance, ses métadonnées personnalisées et ses informations de compte de service. App Engine ne vous permet pas de définir des métadonnées personnalisées pour chaque instance, mais vous pouvez définir des métadonnées personnalisées à l'échelle du projet et les lire à partir de vos instances App Engine et Compute Engine.

Cet exemple de fonction utilise le serveur de métadonnées pour obtenir l'adresse IP externe de l'instance :

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"