Déployer une application Web Python Flask dans l'environnement flexible App Engine

Résumé

Dans cet atelier de programmation, vous allez apprendre à déployer une application Web Python Flask dans l'environnement flexible App Engine. L'exemple d'application permet à un utilisateur d'importer la photo du visage d'une personne et de mesurer la probabilité que cette personne soit contente. L'application utilise les API Google Cloud pour Vision, Storage et Datastore.

À propos d'App Engine

Les applications Google App Engine sont faciles à créer et à maintenir. Grâce à leur caractère évolutif, elles s'adaptent en fonction de vos besoins en termes de trafic et de stockage des données. Avec App Engine, vous n'avez aucun serveur à maintenir. Il vous suffit d'importer votre application pour vous lancer.

Les applications App Engine s'adaptent automatiquement au trafic entrant. L'équilibrage de charge, les microservices, l'autorisation, les bases de données SQL et NoSQL, la répartition du trafic, la journalisation, la recherche, la gestion des versions, l'exécution de déploiements et de rollbacks et les analyses de sécurité sont des fonctionnalités natives et hautement personnalisables.

L'environnement flexible d'App Engine est compatible avec tous les langages de programmation suivants: C#, Go, Java, Node.js, PHP, Python et Ruby. L'environnement flexible App Engine exécute votre application dans des conteneurs Docker s'exécutant sur des machines virtuelles Google Compute Engine. L'option Environnement standard d'App Engine est une alternative à certains langages, y compris Python. L'environnement standard App Engine exécute votre application dans un environnement de bac à sable plus restrictif. Pour plus d'informations, consultez la page Choisir un environnement App Engine.

Points abordés

  • Déployer une application Web simple dans l'environnement flexible App Engine
  • Accéder aux bibliothèques clientes Google Cloud pour Vision, Storage et Datastore
  • Gérer les différentes ressources cloud à l'aide de Google Cloud Console et du SDK Google Cloud
  • Utiliser Cloud Shell

Prérequis

  • Connaissances de base sur Python
  • Bonne connaissance des éditeurs de texte Linux standards tels que Vim, Emacs ou Nano

Création de projet

Si vous n'avez pas encore de compte Google (Gmail ou Google Apps), vous devez en créer un. Connectez-vous à la console Google Cloud Platform (console.cloud.google.com) et créez un projet:

Mémorisez l'ID du projet. Il s'agit d'un nom unique permettant de différencier chaque projet Google Cloud (le nom ci-dessus est déjà pris ; vous devez en trouver un autre). Nous l'appellerons plus tard PROJECT_ID dans cet atelier de programmation.

Facturation

Vous devez ensuite activer la facturation dans Cloud Console afin d'utiliser les ressources Google Cloud.

Le coût de cet atelier de programmation ne devrait pas vous coûter plus que quelques dollars, mais il pourrait être plus élevé si vous décidez d'utiliser davantage de ressources ou de les laisser s'exécuter.

Les nouveaux utilisateurs de Google Cloud Platform peuvent bénéficier d'un essai offert de 300$.

Vous pouvez utiliser Google Cloud à distance depuis votre ordinateur portable. Dans cet atelier de programmation, nous utiliserons Google Cloud Shell, un environnement de ligne de commande fonctionnant dans le cloud. Cette machine virtuelle basée sur Debian contient tous les outils de développement dont vous aurez besoin (gcloud, python, virtualenv, pip, etc.). Elle offre un répertoire de base persistant de 5 Go et s'exécute sur Google Cloud, améliorant considérablement les performances et l'authentification du réseau. Cela signifie que tout ce dont vous avez besoin pour cet atelier de programmation est un navigateur (oui, tout fonctionne sur un Chromebook).

Pour activer Google Cloud Shell, cliquez sur le bouton en haut à droite de la Console pour les développeurs, qui ne devrait pas prendre quelques instants pour provisionner l'environnement et s'y connecter :

En principe, une fois que vous êtes connecté à Cloud Shell, vous êtes authentifié, et le projet est déjà défini sur PROJECT_ID :

gcloud auth list
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
gcloud config list project
[core]
Project = <PROJECT_ID>

Si, pour une raison quelconque, le projet n'est pas défini, exécutez simplement la commande suivante:

gcloud config set project <PROJECT_ID>

Vous ne connaissez pas votre ID de projet (ID_PROJET) ? Vérifiez l'ID de projet utilisé lors de la configuration ou recherchez-le dans le tableau de bord de la console:

Dans Cloud Shell, exécutez la commande suivante pour cloner le dépôt GitHub :

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

Accédez au répertoire python-docs-samples/codelabs/flex_and_vision :

cd python-docs-samples/codelabs/flex_and_vision

Avant de pouvoir utiliser les API Vision, Storage et Datastore, vous devez activer les API à l'aide des commandes suivantes:

gcloud services enable vision.googleapis.com
gcloud services enable storage-component.googleapis.com
gcloud services enable datastore.googleapis.com

Pour envoyer des requêtes aux API Vision, Storage et Datastore, vous avez besoin des identifiants du compte de service. Les identifiants du compte de service de votre projet peuvent être générés à l'aide de l'outil gcloud.

Définissez une variable d'environnement pour votre PROJECT_ID, en remplaçant [YOUR_PROJECT_ID] par votre propre ID de projet:

export PROJECT_ID=[YOUR_PROJECT_ID]

Créez un compte de service pour accéder aux API Google Cloud lors de vos tests en local :

gcloud iam service-accounts create codelab \
  --display-name "My Codelab Service Account"

Attribuez-lui les autorisations nécessaires :

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:codelab@${PROJECT_ID}.iam.gserviceaccount.com \
--role roles/owner

Ensuite, créez une clé de compte de service :

gcloud iam service-accounts keys create ~/key.json \
--iam-account codelab@${PROJECT_ID}.iam.gserviceaccount.com

Cette commande génère une clé de compte de service dans le fichier JSON key.json de votre répertoire d'accueil.

À l'aide du chemin absolu de la clé générée, définissez une variable d'environnement pour la clé de votre compte de service dans Cloud Shell :

export GOOGLE_APPLICATION_CREDENTIALS="/home/${USER}/key.json"

En savoir plus sur l'authentification de l'API Vision

Démarrer votre environnement virtuel et installer des dépendances

Créez un environnement Python 3 isolé nommé env à l'aide de virtualenv :

virtualenv -p python3 env

Saisissez vos virtualenv nouvellement créés env:

source env/bin/activate

À l'aide de pip, installez des dépendances pour votre projet à partir du fichier requirements.txt :

pip install -r requirements.txt

Le fichier requirements.txt est une liste des dépendances de package dont vous avez besoin pour votre projet. La commande ci-dessus a téléchargé toutes les dépendances de package répertoriées dans virtualenv.

Créer une application App Engine

Créez ensuite une instance App Engine à l'aide de la commande suivante :

gcloud app create

Créer un bucket Storage

Commencez par définir la variable d'environnement CLOUD_STORAGE_BUCKET sur le nom de votre projet PROJECT_ID. (Il est généralement recommandé que le nom de votre bucket soit identique à celui de votre PROJECT_ID pour plus de commodité).

export CLOUD_STORAGE_BUCKET=${PROJECT_ID}

Notre application utilise un bucket Cloud Storage, que vous devez créer à partir de Cloud Shell à l'aide d'un outil appelé gsutil. Exécutez la commande suivante pour créer un bucket portant le même nom que votre PROJECT_ID.

gsutil mb gs://${PROJECT_ID}

Exécuter l'application

python main.py

Une fois l'application démarrée, cliquez sur l'icône Web Preview dans la barre d'outils Cloud Shell, puis choisissez"Preview on port 8080" (Prévisualiser sur le port 8080).

Un onglet s'ouvre dans votre navigateur et se connecte au serveur que vous venez de démarrer. Ce type de message devrait s'afficher :

Capture d&#39;écran 23/02/2017 à 19:22.50 PM.png

Essayez d'importer une photo dont le visage est humain. Cliquez sur le bouton Choose File (Sélectionner un fichier), sélectionnez une image sur votre ordinateur, puis cliquez sur Submit (Envoyer).

Une fois la photo importée, un résultat semblable à ce qui suit va s'afficher :

Capture d&#39;écran 23/02/2017 à 19:32.08 PM.png

Exemple de mise en page de code

L'exemple se présente de la façon suivante :

templates/
  homepage.html   /* HTML template that uses Jinja2 */
app.yaml          /* App Engine application configuration file */
main.py           /* Python Flask web application */
requirements.txt  /* List of dependencies for the project */

main.py

Ce fichier Python est une application Web Flask. L'application permet aux utilisateurs d'envoyer des photos (de préférence des visages), qui sont stockées dans Cloud Storage et analysées à l'aide de la fonctionnalité de reconnaissance faciale de l'API Cloud Vision. Les informations clés sur chaque photo sont stockées dans Datastore, la base de données NoSQL de Google Cloud Platform. Un utilisateur peut y accéder chaque fois qu'il visite le site Web.

Cette application utilise les bibliothèques clientes de Google Cloud Platform pour Storage, Datastore et Vision. Ces bibliothèques clientes facilitent l'accès aux API Cloud dans votre langage de programmation favori.

Jetons un coup d'œil à quelques extraits clés du code.

La section des importations en haut est l'endroit où nous importons les différents packages dont nous avons besoin pour notre code. C'est de cette façon que les bibliothèques clientes Google Cloud sont importées pour Datastore, Storage et Vision :

from google.cloud import datastore
from google.cloud import storage
from google.cloud import vision

Il s'agit du code qui décrit ce qui se passe lorsqu'un utilisateur visite l'URL racine du site Web. Nous créons un objet client Datastore qui permet d'accéder à la bibliothèque cliente Datastore. Nous exécutons ensuite une requête sur Datastore pour les entités de genre Faces (Visages). Enfin, nous affichons notre modèle HTML en transmettant l'élément image_entities à partir de Datastore en tant que variable.

@app.route('/')
def homepage():
    # Create a Cloud Datastore client.
    datastore_client = datastore.Client()

    # Use the Cloud Datastore client to fetch information from Datastore about
    # each photo.
    query = datastore_client.query(kind='Faces')
    image_entities = list(query.fetch())

    # Return a Jinja2 HTML template and pass in image_entities as a parameter.
    return render_template('homepage.html', image_entities=image_entities)

Examinons comment les entités sont enregistrées dans Datastore. Datastore est la solution de base de données NoSQL de Google Cloud. Les informations sont stockées dans des objets appelés entités. Chaque entité se voit attribuer une clé d'identification unique, qui peut être créée à l'aide d'un genre et d'une chaîne de nom de clé. Un genre est un bucket qui permet d'organiser les entités selon leur nature. Par exemple, vous pouvez définir des genres pour Photos, Contacts et Animaux.

Chaque entité peut avoir plusieurs propriétés définies par un développeur. Ces propriétés peuvent avoir des valeurs d'un certain nombre de types comme les nombres entiers, les nombres à virgule flottante, les chaînes, les dates ou les données binaires.

    # Create a Cloud Datastore client.
    datastore_client = datastore.Client()

    # Fetch the current date / time.
    current_datetime = datetime.now()

    # The kind for the new entity.
    kind = 'Faces'

    # The name/ID for the new entity.
    name = blob.name

    # Create the Cloud Datastore key for the new entity.
    key = datastore_client.key(kind, name)

    # Construct the new entity using the key. Set dictionary values for entity
    # keys blob_name, storage_public_url, timestamp, and joy.
    entity = datastore.Entity(key)
    entity['blob_name'] = blob.name
    entity['image_public_url'] = blob.public_url
    entity['timestamp'] = current_datetime
    entity['joy'] = face_joy

    # Save the new entity to Datastore.
    datastore_client.put(entity)

Les bibliothèques clientes Storage et Vision sont accessibles de manière automatisée d'une manière semblable à Datastore. Vous pouvez ouvrir le fichier main.py à l'aide de vim, emacs, ou nano pour découvrir tous les exemples de codes.

Pour en savoir plus sur Flask, consultez http://flask.pocoo.org/.

Pour en savoir plus sur les bibliothèques clientes, consultez la page https://googlecloudplatform.github.io/google-cloud-python/.

pageaccueil.html

Le framework Web Flask utilise Jinja2 comme moteur de création de modèles. Cela permet de passer des variables et des expressions de main.py dans homepage.html, qui sont remplacées par des valeurs une fois la page affichée.

Apprenez-en plus sur Jinja2 à l'adresse http://jinja.pocoo.org/docs/2.9/templates/.

Ce modèle HTML Jinja2 affiche un formulaire permettant aux utilisateurs d'envoyer des photos à la base de données. Il affiche également chaque image envoyée avec le nom du fichier, la date ou l'heure de téléchargement et la probabilité que le visage détecté par l'API Vision soit content.

homepage.html

<h1>Google Cloud Platform - Face Detection Sample</h1>

<p>This Python Flask application demonstrates App Engine Flexible, Google Cloud
Storage, Datastore, and the Cloud Vision API.</p>

<br>

<html>
  <body>
    <form action="upload_photo" method="POST" enctype="multipart/form-data">
      Upload File: <input type="file" name="file"><br>
      <input type="submit" name="submit" value="Submit">
    </form>
    
  </body>
</html>

L'environnement flexible App Engine décrit la configuration de déploiement d'une application à l'aide du fichier app.yaml. Si ce fichier est absent, App Engine tente de déterminer la configuration de déploiement. Toutefois, nous vous recommandons de fournir ce fichier.

Vous allez ensuite modifier le fichier app.yaml à l'aide des éditeurs de votre choix (vim, nano ou emacs). Nous allons utiliser l'éditeur nano :

nano app.yaml

app.yaml

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

runtime_config:
    python_version: 3

env_variables:
    CLOUD_STORAGE_BUCKET: <your-cloud-storage-bucket>

Ce contenu indique la configuration de base nécessaire au déploiement d'une application Python 3 dans l'environnement flexible App Engine. Pour en savoir plus sur la configuration d'App Engine, cliquez ici.

Une fois le fichier app.yaml ouvert, remplacez <your-cloud-storage-bucket > par le nom de votre bucket Cloud Storage. (Si vous avez oublié le nom de votre bucket Cloud Storage, copiez l'ID du projet GCP depuis Qwiklabs.) La section env_variables définit des variables d'environnement qui seront utilisées dans le fichier main.py une fois l'application déployée.

Vous pouvez désormais enregistrer et fermer le fichier dans nano, en appuyant sur Ctrl + X. L'invite suivante s'affichera :

Capture d&#39;écran 2017-02-17 à 16.47.12 PM.png

Saisissez une lettre y, puis appuyez une nouvelle fois sur la touche ENTRÉE pour confirmer le nom de fichier de l'invite suivante:

Capture d&#39;écran 24/02/2017 à 16:18.23.png

Déployez votre application sur App Engine à l'aide de gcloud :

gcloud app deploy

Une fois l'application déployée, vous pouvez y accéder dans votre navigateur Web en ouvrant l'URL https://< PROJECT_ID >.appspot.com.

Résumé

Au cours de cette étape, vous allez configurer une application Web Python et la déployer dans l'environnement flexible App Engine.

Vous avez appris à écrire et à déployer votre première application Web flexible App Engine.

Effectuer un nettoyage

Afin d'éviter que des frais ne soient facturés sur votre compte Google Cloud Platform pour les ressources utilisées dans ce démarrage rapide, procédez comme suit :

  • Accédez à la console Cloud Platform.
  • Sélectionnez le projet que vous souhaitez arrêter, puis cliquez sur "Supprimer' en haut" pour planifier la suppression du projet.

En savoir plus

Licence

Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.