Exemple App Engine et Google Cloud Storage

ID de la région

Le REGION_ID est un code abrégé que Google attribue en fonction de la région que vous sélectionnez lors de la création de votre application. Le code ne correspond pas à un pays ou une province, même si certains ID de région peuvent ressembler aux codes de pays et de province couramment utilisés. Pour les applications créées après février 2020, REGION_ID.r est inclus dans les URL App Engine. Pour les applications existantes créées avant cette date, l'ID de région est facultatif dans l'URL. En savoir plus sur les ID de région

Découvrez comment activer l'accès de Cloud Storage à votre application App Engine en langage Python, et comment créer, écrire, lire et répertorier des fichiers dans le bucket Cloud Storage.

Ce tutoriel part du principe que vous maîtrisez Python et que vous avez configuré votre environnement de développement.

Lorsque cet exemple est exécuté, il exécute un script et écrit le résultat dans le navigateur. Le script présente les fonctionnalités suivantes de la bibliothèque client Cloud Storage :

  • Créer un fichier et écrire le fichier dans un bucket
  • Lire le fichier et récupérer ses métadonnées
  • Créer plusieurs fichiers, puis les répertorier à partir du bucket
  • Répertorier les fichiers que vous venez d'ajouter au bucket
  • Lire l'ensemble de fichiers
  • Supprimer cet ensemble de fichiers

Objectifs

  • Parcourir le projet Python pour découvrir l'organisation et les fichiers requis
  • Comprendre le code pour se connecter à Cloud Storage
  • Comprendre le code pour créer, écrire, lire, répertorier et supprimer des fichiers
  • Comprendre le code des nouvelles tentatives
  • Générer et tester l'application sur votre serveur de développement local
  • Déployer l'application en production sur Google App Engine

Coûts

App Engine offre un niveau d'utilisation gratuit. Si votre utilisation totale d'App Engine est inférieure aux limites spécifiées dans le quota gratuit d'App Engine, ce tutoriel est gratuit.

Avant de commencer

Avant d'exécuter cet exemple, vous devez disposer d'un ID de projet, de l'outil de ligne de commande gcloud et d'un bucket Cloud Storage :

  1. Créez un projet de console ou récupérez l'ID d'un projet existant à partir de la console Google Cloud :

    Accéder à la page Projets

    Conseil : Vous pouvez récupérer la liste de vos ID de projet existants à l'aide de l'outil de ligne de commande gcloud.

  2. Installez et initialisez Google Cloud CLI :

    Télécharger le SDK

  3. Activez le bucket Cloud Storage par défaut.

Cloner le projet de tutoriel

Pour cloner le projet :

  1. Clonez la bibliothèque cliente et l'exemple d'application (démo) sur votre ordinateur local.

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples
    

    Vous pouvez également télécharger l'exemple dans un fichier zip et l'extraire.

  2. Accédez au répertoire approprié dans le projet cloné ou téléchargé :

    cd python-docs-samples/appengine/standard/storage/appengine-client
    

Installer les dépendances

L'outil virtualenv vous permet de créer un environnement Python propre sur votre système. Pour le développement d'App Engine, cela permet de garantir que le code que vous testez en local est similaire à l'environnement dans lequel votre code sera déployé. Pour en savoir plus, consultez la page Utiliser des bibliothèques tierces.

Pour installer virtualenv et les dépendances de l'exemple :

macOS/Linux

  1. Si virtualenv n'est pas installé, utilisez pip afin de l'installer pour l'ensemble du système :
    sudo pip install virtualenv
  2. Créez un environnement Python isolé :
    virtualenv env
    source env/bin/activate
  3. Si vous n'êtes pas dans le répertoire qui contient l'exemple de code, accédez au répertoire qui contient l'exemple de code hello_world. Ensuite, installez les dépendances :
    cd YOUR_SAMPLE_CODE_DIR
    pip install -t lib -r requirements.txt

Windows

Si vous avez installé la CLI Google Cloud, Python 2.7 devrait déjà être installé, généralement dans C:\python27_x64\ (pour les systèmes 64 bits). Exécutez les packages Python à l'aide de PowerShell.

  1. Localisez votre installation de PowerShell.
  2. Cliquez avec le bouton droit sur le raccourci PowerShell et démarrez une session en tant qu'administrateur.
  3. Essayez d'exécuter la commande python. Si le dossier Python est introuvable, ajoutez-le à la variable d'environnement PATH.
    $env:Path += ";C:\python27_x64\"
  4. Si virtualenv n'est pas installé, utilisez pip afin de l'installer pour l'ensemble du système :
    python -m pip install virtualenv
  5. Créez un environnement Python isolé.
    python -m virtualenv env
    . env\Scripts\activate
  6. Accédez au répertoire de votre projet et installez les dépendances : Si vous n'êtes pas dans le répertoire qui contient l'exemple de code, accédez au répertoire qui contient l'exemple de code hello_world. Ensuite, installez les dépendances :
    cd YOUR_SAMPLE_CODE_DIR
    python -m pip install -t lib -r requirements.txt

L'exemple de code que vous avez cloné ou téléchargé contient déjà un fichier appengine_config.py. Ce fichier impose à App Engine l'utilisation du dossier lib pour charger les dépendances localement et lors du déploiement.

Exécution locale

Pour exécuter l'exemple en local :

  1. Dans le sous-répertoire du projet python-docs-samples/appengine/standard/storage/appengine-client, exécutez l'application sur le [serveur de développement local] :

    dev_appserver.py .
    
  2. Attendez le message de réussite, qui ressemble à ceci :

    INFO     2016-04-12 21:33:35,446 api_server.py:205] Starting API server at: http://localhost:36884
    INFO     2016-04-12 21:33:35,449 dispatcher.py:197] Starting module "default" running at: http://localhost:8080
    INFO     2016-04-12 21:33:35,449 admin_server.py:116] Starting admin server at: http://localhost:8000
    
  3. Accédez à cette URL dans votre navigateur :

    http://localhost:8080/

    L'application s'exécutera au chargement de la page, affichant le résultat dans le navigateur afin d'indiquer ce qu'elle a exécuté. Le résultat ressemble à ceci :

    Hello_Storage

  4. Arrêtez le serveur de développement en appuyant sur Ctrl+C.

Tutoriel pour le fichier app.yaml

Le fichier app.yaml spécifie les détails de la configuration de l'application :

runtime: python27
api_version: 1
threadsafe: yes

env_variables:

handlers:
- url: /blobstore.*
  script: blobstore.app

- url: /.*
  script: main.app

Pour en savoir plus sur les options de configuration disponibles dans ce fichier, consultez la documentation de référence sur app.yaml.

Tutoriel pour les importations

Le fichier main.py contient les importations types utilisées pour accéder à Cloud Storage via la bibliothèque cliente :

import os

import cloudstorage
from google.appengine.api import app_identity

import webapp2

Vous avez besoin du module os et de l'API app_identity pour obtenir le nom du bucket par défaut au moment de l'exécution. Vous aurez besoin du nom de ce bucket pour toutes les opérations d'accès à Cloud Storage.

L'exemple utilise également le framework Web webapp2.

Spécifier le bucket Cloud Storage

Avant toute opération dans Cloud Storage, vous devez fournir le nom du bucket. Pour ce faire, le moyen le plus simple consiste à utiliser le bucket par défaut de votre projet, qui peut être obtenu comme suit :

def get(self):
    bucket_name = os.environ.get(
        'BUCKET_NAME', app_identity.get_default_gcs_bucket_name())

    self.response.headers['Content-Type'] = 'text/plain'
    self.response.write(
        'Demo GCS Application running from Version: {}\n'.format(
            os.environ['CURRENT_VERSION_ID']))
    self.response.write('Using bucket name: {}\n\n'.format(bucket_name))

Écrire un fichier dans Cloud Storage

L'exemple suivant montre comment écrire dans le bucket :

def create_file(self, filename):
    """Create a file."""

    self.response.write('Creating file {}\n'.format(filename))

    # The retry_params specified in the open call will override the default
    # retry params for this particular file handle.
    write_retry_params = cloudstorage.RetryParams(backoff_factor=1.1)
    with cloudstorage.open(
        filename, 'w', content_type='text/plain', options={
            'x-goog-meta-foo': 'foo', 'x-goog-meta-bar': 'bar'},
            retry_params=write_retry_params) as cloudstorage_file:
                cloudstorage_file.write('abcde\n')
                cloudstorage_file.write('f'*1024*4 + '\n')
    self.tmp_filenames_to_clean_up.append(filename)

Notez que lors de l'appel de open pour l'ouverture du fichier en écriture, l'exemple spécifie certains en-têtes Cloud Storage qui écrivent des métadonnées personnalisées pour le fichier. Ces métadonnées peuvent être récupérées à l'aide de cloudstorage.stat. Vous trouverez la liste des en-têtes compatibles dans la documentation de référence de cloudstorage.open.

Notez également que l'en-tête x-goog-acl n'est pas défini. Cela signifie que la liste de contrôle d'accès Cloud Storage par défaut pour la lecture publique va être appliquée à l'objet lors de son écriture dans le bucket.

Enfin, vous pouvez constater que l'appel close ferme le fichier une fois l'écriture terminée. Si cet appel n'est pas émis, le fichier n'est pas écrit dans Cloud Storage. Sachez qu'après avoir appelé close, vous ne pouvez plus rien ajouter au fichier. Si vous devez modifier un fichier, vous devrez le rouvrir en mode écriture. Les données seront alors écrasées et non ajoutées.

Lire un fichier à partir de Cloud Storage

L'exemple suivant montre comment lire un fichier à partir du bucket :

def read_file(self, filename):
    self.response.write(
        'Abbreviated file content (first line and last 1K):\n')

    with cloudstorage.open(filename) as cloudstorage_file:
        self.response.write(cloudstorage_file.readline())
        cloudstorage_file.seek(-1024, os.SEEK_END)
        self.response.write(cloudstorage_file.read())

L'exemple montre comment afficher les lignes sélectionnées du fichier en cours de lecture (dans le cas présent, la ligne d'ouverture et les mille dernières lignes) à l'aide de seek.

Notez qu'aucun mode n'est spécifié dans le code ci-dessus lorsque le fichier est ouvert en lecture. La valeur par défaut pour open est le mode de lecture seule.

Répertorier le contenu du bucket

L'exemple de code montre comment parcourir un bucket comportant un grand nombre de fichiers, en utilisant les paramètres marker et max_keys pour parcourir une liste du contenu du bucket :

def list_bucket(self, bucket):
    """Create several files and paginate through them."""

    self.response.write('Listbucket result:\n')

    # Production apps should set page_size to a practical value.
    page_size = 1
    stats = cloudstorage.listbucket(bucket + '/foo', max_keys=page_size)
    while True:
        count = 0
        for stat in stats:
            count += 1
            self.response.write(repr(stat))
            self.response.write('\n')

        if count != page_size or count == 0:
            break
        stats = cloudstorage.listbucket(
            bucket + '/foo', max_keys=page_size, marker=stat.filename)

Notez que le nom de fichier complet est affiché comme une chaîne sans délimiteurs de répertoire. Si vous souhaitez afficher le fichier avec une hiérarchie de répertoires plus reconnaissable, définissez le paramètre delimiter sur le délimiteur de répertoires que vous souhaitez utiliser.

Supprimer des fichiers

L'exemple de code montre comment supprimer des fichiers, dans ce cas tous les fichiers ajoutés lors de l'exécution de l'application. Vous n'avez pas besoin d'effectuer cette opération dans votre code, car il ne s'agit que d'une fonctionnalité de nettoyage de cet exemple :

def delete_files(self):
    self.response.write('Deleting files...\n')
    for filename in self.tmp_filenames_to_clean_up:
        self.response.write('Deleting file {}\n'.format(filename))
        try:
            cloudstorage.delete(filename)
        except cloudstorage.NotFoundError:
            pass

Déployer l'exemple

Pour déployer et exécuter l'exemple d'application dans App Engine :

  1. Importez l'exemple d'application en exécutant la commande suivante à partir du répertoire python-docs-samples/appengine/standard/storage/appengine-client où se trouve le fichier app.yaml :

    gcloud app deploy
    

    Indicateurs facultatifs :

    • Incluez l'option --project pour spécifier un ID de projet de console différent de celui que vous avez initialisé par défaut dans gcloud CLI. Exemple : --project [YOUR_PROJECT_ID]
    • Incluez l'option -v pour spécifier un ID de version. Si vous omettez cet ID, un ID est généré automatiquement. Exemple : -v [YOUR_VERSION_ID]

    Conseil : Si vous spécifiez l'ID de version d'une application précédemment téléchargée, votre déploiement écrasera la version existante dans App Engine. Cela n'est pas toujours souhaitable, surtout si la version dans App Engine diffuse du trafic. Pour éviter de perturber le trafic vers votre application, vous pouvez déployer cette dernière avec un ID de version différent, puis déplacer le trafic vers cette version. Pour en savoir plus sur le déplacement du trafic, consultez la page Répartition du trafic.

  2. Une fois le déploiement terminé, vous pouvez afficher l'application sur https://PROJECT_ID.REGION_ID.r.appspot.com en exécutant la commande suivante :

    gcloud app browse
    

    L'application demo s'exécute au chargement de la page, exactement comme lors de son exécution en local. Cependant, l'application va maintenant écrire et lire dans votre bucket Cloud Storage.

Pour en savoir plus sur le déploiement de l'application à partir de la ligne de commande, consultez la page Déployer une application Python 2.

Étapes suivantes