Cette suite d'ateliers de programmation (tutoriels pratiques à suivre à votre rythme) est destinée à aider les développeurs Google App Engine (standard) à moderniser leurs applications en les guidant tout au long d'une série de migrations. L'étape la plus importante est de délaisser les services groupés de l'environnement d'exécution d'origine, car les environnements d'exécution nouvelle génération sont plus souples et offrent aux utilisateurs davantage d'options de service. Le passage à l'environnement d'exécution nouvelle génération vous permet d'intégrer plus facilement les produits Google Cloud, d'utiliser une plus large gamme de services compatibles et de prendre en charge les versions de langage actuelles.
Ce tutoriel explique comment migrer de la bibliothèque cliente intégrée ndb
(Next Database) d'App Engine vers la bibliothèque cliente Cloud NDB.
Vous apprendrez à effectuer les tâches suivantes :
- Utiliser la bibliothèque
ndb
d'App Engine (si vous ne la connaissez pas déjà) - Migrer de
ndb
vers Cloud NDB - Migrer votre application vers Python 3
Prérequis
- Un projet Google Cloud Platform avec :
- Des connaissances de base en Python
- Une connaissance correcte des commandes Linux courantes
- Des connaissances de base du développement et du déploiement d'applications App Engine
- Une application de module 1 App Engine fonctionnelle
Enquête
Comment allez-vous utiliser cet atelier de programmation ?
Dans le module 1, nous avons migré les frameworks Web du framework webapp2
intégré d'App Engine vers Flask. Dans le présent atelier de programmation, nous continuons à abandonner les services intégrés d'App Engine en passant de la bibliothèque ndb
d'App Engine à Google Cloud NDB.
Une fois la migration terminée, vous pourrez :
- Migrer vers Python 3 et vers l'environnement d'exécution App Engine nouvelle génération.
- Migrer vers Cloud Datastore (bibliothèque cliente pour les applications non-App Engine).
- Conteneuriser votre application Python 2 (ou 3) et migrer vers Cloud Run.
- Ajouter l'utilisation des files d'attente de tâches d'App Engine (push) puis migrer vers Cloud Tasks.
Mais nous n'en sommes pas encore là. Terminez le présent atelier de programmation avant de réfléchir aux étapes suivantes. Les étapes de migration principales du présent tutoriel sont les suivantes :
- Configuration/Préparation
- Ajouter la bibliothèque Cloud NDB
- Mettre à jour les fichiers de l'application
Avant de passer à la partie principale du tutoriel, nous allons configurer notre projet, obtenir le code et déployer l'application de base pour nous assurer de bien utiliser du code fonctionnel.
1. Configurer le projet
Si vous avez terminé l'atelier de programmation du module 1, nous vous recommandons de réutiliser le même projet (et le même code). Vous pouvez également créer un projet ou réutiliser un autre projet existant. Assurez-vous que le projet dispose d'un compte de facturation actif et qu'App Engine est bien activé.
2. Obtenir un exemple d'application de référence
L'une des conditions préalables est de disposer de l'exemple d'application du module 1. Vous pouvez utiliser votre propre application si vous avez suivi ce tutoriel. Sinon, vous pouvez suivre le tutoriel maintenant (lien ci-dessus) ou simplement puis copier le dépôt du module 1 (lien ci-dessous).
Que vous utilisiez votre application ou la nôtre, le code de départ ("START") est celui du module 1. Le présent atelier de programmation du module 2 vous guide pour chaque étape jusqu'à obtenir le code final ("FINISH"), avec le bonus de la migration de Python 2 vers Python 3 :
- Code de départ "START" : Code du module 1
- Code final "FINISH" : Code Python 2 du module 2 (BONUS : Code Python 3)
- Dépôt complet (pour cloner ou télécharger un fichier ZIP)
Le dossier contenant le code de départ "START" du module 1 doit contenir les éléments suivants :
$ ls
README.md appengine_config.py requirements.txt
app.yaml main.py templates
Si vous avez suivi le tutoriel du module 1, vous avez également un dossier lib
avec Flask et ses dépendances. Si vous n'avez pas de dossier lib
, créez-le à l'aide de la commande pip install -t lib -r requirements.txt
afin que nous puissions déployer cette application de référence à l'étape suivante. Si Python 2 et Python 3 sont tous les deux installés, nous vous recommandons d'utiliser pip2
plutôt que pip
afin d'éviter toute confusion avec Python 3.
3. (Re)Déployer l'application du Mmodule 1
Étapes préliminaires restantes :
- Familiarisez-vous avec l'outil de ligne de commande
gcloud
(si nécessaire). - (Re)déployez le code du module 1 sur App Engine (si nécessaire).
Une fois que vous avez exécuté ces étapes et vérifié le bon fonctionnement du code, nous pouvons passer à la suite de ce tutoriel en commençant par les fichiers de configuration.
De nombreux services intégrés d'App Engine ont évolué pour devenir des produits autonomes, et Datastore est l'un d'entre eux. Aujourd'hui, les applications autres qu'App Engine peuvent utiliser Cloud Datastore. Pour les utilisateurs de longue date de ndb
, l'équipe Google Cloud a créé la bibliothèque cliente Cloud NDB pour communiquer avec Cloud Datastore. Elle est disponible pour Python 2 et Python 3.
Nous allons modifier les fichiers de confirmation pour remplacer App Engine ndb
par Cloud NDB, puis modifier notre application.
1. Mettre à jour requirements.txt
Dans le module 1, la seule dépendance externe de notre application était Flask. Ajoutons maintenant Cloud NDB. Voici à quoi ressemblait votre fichier requirements.txt
à la fin du module 1 :
- AVANT :
Flask==1.1.2
Pour effectuer une migration depuis App Engine ndb
, vous devez utiliser la bibliothèque Cloud NDB (google-cloud-ndb
) en ajoutant son package à requirements.txt
.
- APRÈS :
Flask==1.1.2
google-cloud-ndb==1.7.1
Lorsque cet atelier de programmation a été rédigé, la dernière version recommandée était la 1.7.1. Cependant, il est possible que le requirements.txt
dans le dépôt utilise une version plus récente. Nous vous recommandons d'utiliser les dernières versions de chaque bibliothèque. Toutefois, si celles-ci ne fonctionnent pas, vous pouvez rétablir une version antérieure.
Supprimez le dossier lib
si vous en avez un et que vous ne l'avez pas vous-même créé plus haut. Maintenant, (ré)installez les bibliothèques mises à jour avec la commande pip install -t lib -r requirements.txt
, en utilisant pip2
au lieu de pip
si nécessaire.
2. Mettre à jour app.yaml
Certains prérequis s'appliquent à l'ajout de bibliothèques clientes Google Cloud telles que google-cloud-ndb
car elles s'appuient sur l'inclusion de bibliothèques intégrées, c'est-à-dire des packages tiers déjà disponibles sur les serveurs Google. Vous ne pouvez pas les répertorier pas dans requirements.txt
ni les copier avec pip install
. Les seules conditions requises sont les suivantes :
- Spécifier les bibliothèques intégrées dans
app.yaml
. - Les faire pointer vers les bibliothèques tierces copiées avec lesquelles elles pourraient travailler (dans
lib
).
Voici le fichier app.yaml
de départ ("START") du module 1 :
- AVANT :
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Ajoutez maintenant les lignes suivantes à app.yaml
pour référencer les deux packages tiers grpcio
et setuptools
dans une nouvelle section libraries
:
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
Pourquoi utiliser ces bibliothèques intégrées ? gRPC est un framework RPC ouvert utilisé par toutes les bibliothèques clientes de Google Cloud, y compris google-cloud-ndb
. La bibliothèque grpcio
correspond à l'adaptateur gRPC Python et est donc obligatoire. Le raisonnement derrière l'inclusion de setuptools
vous sera prochainement expliqué.
- APRÈS :
Une fois les modifications ci-dessus effectuées, votre fichier app.yaml
mis à jour devrait maintenant ressembler à ceci :
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
3. Mettre à jour appengine_config.py
L'outil pkg_resources
, qui fait partie de la bibliothèque setuptools
, permet aux bibliothèques tierces intégrées d'accéder aux bibliothèques fournies sous forme de package. Mettez à jour appengine_config.py
pour utiliser pkg_resources
afin de les faire pointer vers les bibliothèques regroupées dans lib
. Une fois les modifications terminées, le fichier complet doit ressembler à ceci :
import pkg_resources
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
# Add libraries to pkg_resources working set to find the distribution.
pkg_resources.working_set.add_entry(PATH)
Maintenant que les formalités de fichier de configuration sont terminées, vous pouvez migrer de ndb
vers Cloud NDB. Pour effectuer la migration, mettez à jour les bibliothèques importées et ajoutez la gestion du contexte dans main.py
.
1. Importations
Faites l'échange d'importation suivant dans main.py
:
- AVANT
from google.appengine.ext import ndb
- APRÈS :
from google.cloud import ndb
Le passage d'une bibliothèque App Engine à une bibliothèque Google Cloud est parfois aussi subtil dans le cas présent. Pour les services intégrés qui sont devenus des produits Google Cloud complets, vous importerez les attributs de google.cloud
au lieu de google.appengine
.
2. Accès à Datastore
Pour pouvoir utiliser la bibliothèque Cloud NDB, votre application doit utiliser des gestionnaires de contexte Python. Leur rôle est de contrôler l'accès aux ressources de telle sorte qu'elles doivent être acquises avant de pouvoir être utilisées. Les gestionnaires de contexte reposent sur la technique de contrôle informatique appelée RAII ("Resource Allocation Is Initialization" ou littéralement, "toute allocation de ressource est une initialisation"). Les gestionnaires de contexte sont utilisés avec des fichiers Python (qui doivent être ouverts avant de pouvoir y accéder) et en appliquant la simultanéité. Vous devez donc obtenir des verrous "spin lock" avant de pouvoir exécuter le code dans une section critique.
De même, Cloud NDB nécessite d'obtenir le contexte client pour communiquer avec Datastore avant de pouvoir exécuter des commandes Datastore. Commencez par créer un client (ndb.Client()
) en ajoutant ds_client = ndb.Client()
dans main.py
juste après l'initialisation de Flask :
app = Flask(__name__)
ds_client = ndb.Client()
La commande Python with
permet uniquement d'obtenir le contexte d'un objet. Encapsulez tous les blocs de code accédant à Datastore dans des instructions with
.
Vous trouverez ci-dessous les mêmes fonctions que dans le module 1 pour l'écriture d'une nouvelle entité dans Datastore et la lecture afin d'afficher les entités les plus récemment ajoutées :
- AVANT :
Voici le code d'origine sans gestion contextuelle :
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
return (v.to_dict() for v in Visit.query().order(
-Visit.timestamp).fetch(limit))
- APRÈS :
Ajoutez maintenant with ds_client.context():
et déplacez votre code d'accès Datastore dans le bloc with
:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return (v.to_dict() for v in Visit.query().order(
-Visit.timestamp).fetch(limit))
L'application de pilote principal reste identique à celle du module 1 car aucun code ndb
(ou Cloud NDB) n'apparaît ici :
@app.route('/')
def root():
'main application (GET) handler'
store_visit(request.remote_addr, request.user_agent)
visits = fetch_visits(10)
return render_template('index.html', visits=visits)
Une bonne pratique consiste à faire une distinction claire entre le code d'application et l'accès aux données. Ainsi, il n'est pas nécessaire de modifier le code principal de votre application lorsque le mécanisme de stockage de données sous-jacent est modifié comme nous l'avons fait avec cette migration.
Déployer l'application
Redéployez votre application avec gcloud app deploy
et confirmez qu'elle fonctionne correctement. Votre code doit maintenant correspondre à celui du dépôt du module 2.
Si vous avez consulté cette série sans suivre les ateliers de programmation précédents, l'application elle-même ne change pas. Elle enregistre toutes les visites sur la page Web principale (/
) et ressemble à ceci une fois que vous avez consulté le site suffisamment de fois :
Bravo ! Vous avez terminé l'atelier de programmation du module 2. Vous venez de franchir la ligne d'arrivée : il s'agit de la dernière des migrations vivement recommandées jusqu'à présent pour ce qui est de Datastore.
Facultatif : Effectuer un nettoyage
Que diriez-vous d'un bon nettoyage pour éviter que des frais vous soient facturés tant que vous n'êtes pas prêt à passer à l'atelier de programmation suivant sur la migration ? En tant que développeur existant, vous connaissez probablement déjà les informations de tarification d'App Engine.
Facultatif : Désactiver l'application
Si vous n'êtes pas encore prêt à passer au tutoriel suivant, désactivez votre application pour éviter les frais. Lorsque vous êtes prêt à passer au prochain atelier de programmation, vous pouvez la réactiver. Tant que votre application est désactivée, elle ne génère aucun trafic, donc aucuns frais. Toutefois, si vous dépassez le quota gratuit, votre utilisation de Datastore vous sera facturée, alors supprimez suffisamment d'éléments pour rester dans la limite.
En revanche, si vous ne souhaitez pas poursuivre vos migrations et souhaitez supprimer tous les éléments, vous pouvez arrêter le projet.
Étapes suivantes
Plusieurs choix s'offrent maintenant à vous pour la suite. Choisissez l'une des options suivantes :
- Module 2 : Bonus : passez à la partie bonus de ce tutoriel et découvrez comment porter votre application vers Python 3 et utiliser l'environnement d'exécution App Engine nouvelle génération.
- Module 7 : files d'attente d'envoi de tâches App Engine (obligatoire si vous utilisez des files d'attente de tâches d'envoi de tâches [push])
- Ajoutez des tâches push
taskqueue
App Engine à l'application du module 1. - Préparez les utilisateurs à migrer vers Cloud Tasks dans le module 8.
- Ajoutez des tâches push
- Module 4 : Migrer vers Cloud Run avec Docker
- Conteneurisez votre application pour l'exécuter sur Cloud Run avec Docker.
- Cela vous permet de continuer d'utiliser Python 2.
- Module 5 : Migrer vers Cloud Run avec les packs de création Cloud
- Conteneurisez votre application pour qu'elle s'exécute sur Cloud Run avec les packs de création Cloud.
- Il n'est pas nécessaire de déjà connaître Docker, les conteneurs ou les
Dockerfile
. - Vous devez avoir déjà effectué la migration de votre application vers Python 3.
- Module 3 :
- Modernisez l'accès au Datastore en passant de Cloud NDB à Cloud Datastore.
- Il s'agit de la bibliothèque utilisée pour les applications Python 3 App Engine ou autres.
Pour bénéficier des nouvelles fonctionnalités et des derniers environnements d'exécution App Engine, nous vous recommandons de migrer vers Python 3. Dans notre exemple d'application, Datastore était le seul service intégré utilisé. La migration de ndb
vers Cloud NDB ayant été effectuée, nous pouvons maintenant transitionner vers l'environnement d'exécution Python 3 d'App Engine.
Présentation
Bien que le portage vers Python 3 dépasse le cadre d'un simple tutoriel Google Cloud, la présente partie de notre atelier de programmation donne aux développeurs une idée des spécificités de l'environnement d'exécution App Engine pour Python 3. L'accès à des packages tiers est l'un des principaux avantages de l'environnement d'exécution nouvelle génération. Il n'est plus nécessaire de spécifier des packages intégrés dans app.yaml
, ni de copier ou d'importer des bibliothèques non intégrées (elles sont installées de manière implicite car elles figurent dans requirements.txt
).
Comme notre exemple est très basique et que Cloud NDB est compatible avec les deux versions de Python, le portage ne nécessite aucune modification et le code fonctionne aussi bien sous Python 2 que sous Python 3. Dans le cas présent, seules les modifications de configuration suivantes sont requises :
- Simplifier
app.yaml
pour référencer Python 3 et supprimer les bibliothèques tierces. - Supprimer
appengine_config.py
et le dossierlib
car ils ne sont plus nécessaires.
En plus de main.py
, les fichiers requirements.txt
et templates/index.html
restent inchangés.
Simplier app.yaml
AVANT :
La seule réelle modification pour cet exemple d'application est le fait de raccourcir app.yaml
. Pour rappel, voici ce que nous avions dans app.yaml
à la fin du module 2 :
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
APRÈS :
Dans Python 3, les instructions threadsafe
, api_version
et libraries
sont toutes obsolètes. Toutes les applications sont supposées être threadsafe et api_version
n'est plus utilisé dans Python 3. Comme aucun package tiers intégré n'est préinstallé sur les services App Engine, le service libraries
est également obsolète. Pour plus d'informations sur ces modifications, consultez la documentation sur les modifications apportées à app.yaml
. Par conséquent, vous devez supprimer ces trois éléments de app.yaml
et passer à une version compatible de Python 3 (voir ci-dessous).
Utilisation de la directive handlers
En outre, la directive handlers
, qui dirige le trafic vers des applications App Engine spécifiques, a également été abandonnée. Étant donné que l'environnement d'exécution nouvelle génération suppose que les frameworks Web gèrent le routage des applications, tous les "scripts de gestionnaire" doivent être définis sur "auto
". En combinant les modifications ci-dessus, vous obtenez ce fichier app.yaml
:
runtime: python38
handlers:
- url: /.*
script: auto
Pour en savoir plus sur script: auto
, consultez sa page de documentation.
Supprimer l'instruction handlers
Étant donné que handlers
est obsolète, vous pouvez également supprimer toute la section et ne laisser qu'une seule ligne dans votre fichier app.yaml
:
runtime: python38
Par défaut, le serveur Web WSGI Gunicorn est disponible pour toutes les applications. Si vous maîtrisez gunicorn
, voici la commande qui s'exécute lors d'un démarrage par défaut avec un fichier app.yaml
réduit au strict minimum :
gunicorn main:app --workers 2 -c /config/gunicorn.py
Facultatif : utilisation de la directive entrypoint
Toutefois, vous pouvez utiliser une instruction entrypoint
si votre application nécessite une commande de démarrage spécifique, auquel cas votre fichier app.yaml
ressemble à ceci :
runtime: python38
entrypoint: python main.py
Cet exemple demande spécifiquement un serveur de développement Flask plutôt que d'utiliser gunicorn
. Le code qui démarre le serveur de développement doit également être ajouté à votre application pour démarrer sur l'interface 0.0.0.0
sur le port 8080 en ajoutant cette petite section à la fin de main.py
:
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
Pour en savoir plus sur entrypoint
, consultez la documentation correspondante. Pour obtenir d'autres exemples et bonnes pratiques, consultez la documentation sur le démarrage standard App Engine ainsi que la documentation sur le démarrage flexible App Engine.
Supprimer appengine_config.py
et lib
Supprimez le fichier appengine_config.py
et le dossier lib
. Lors de la migration vers Python 3, App Engine acquiert et installe les packages répertoriés dans requirements.txt
.
Le fichier de configuration appengine_config.py
permet de reconnaître les bibliothèques et packages tiers, que vous les ayez copiés vous-même ou que vous utilisiez ceux qui sont déjà disponibles sur des serveurs App Engine (intégrés) Voici un résumé des principaux changements lorsque vous passez à Python 3 :
- Pas de regroupement de bibliothèques tierces copiées (répertoriées dans
requirements.txt
). - Pas de
pip install
dans un dossierlib
et pas de dossierlib
. - Pas de liste de bibliothèques tierces dans
app.yaml
. - Pas besoin de référencer une application auprès des bibliothèques tierces, et donc pas de fichier
appengine_config.py
.
Il vous suffit de répertorier toutes les bibliothèques tierces requises dans requirements.txt
.
Déployer l'application
Redéployez votre application pour vous assurer qu'elle fonctionne. Vous pouvez également vérifier que votre solution est identique à l'exemple de code Python 3 du module 2. Pour visualiser les différences avec Python 2, comparez le code à sa version Python 2.
Nous vous félicitons d'avoir terminé l'étape bonus du module 2 ! Consultez la documentation sur la préparation des fichiers de configuration pour l'environnement d'exécution Python 3. Enfin, revenez à l'étape "Récapitulatif/Nettoyage" pour connaître les étapes suivantes et effectuer un nettoyage.
Préparer votre application
Au moment de procéder à la migration de votre application, vous devez transférer le fichier main.py
et les autres fichiers de l'application vers la version 3.x. Il est donc recommandé d'optimiser autant que possible la compatibilité ascendante de votre application 2.x.
Pour ce faire il existe de nombreuses ressources en ligne mais voici quelques conseils essentiels :
- Assurez-vous que toutes les dépendances de votre application sont entièrement compatibles avec la version 3.x.
- Assurez-vous que votre application s'exécute au moins avec la version 2.6 (de préférence 2.7).
- Assurez-vous que l'application réussit en intégralité la suite de tests (avec une couverture minimale de 80 %).
- Utilisez des bibliothèques de compatibilité telles que
six
, Future et/ou Modernize. - Informez-vous sur les principaux problèmes de compatibilité entre les versions 2.x et 3.x.
- Toute E/S peut entraîner des incompatibilités entre les chaînes Unicode et les chaînes d'octets.
L'exemple d'application a été conçu pour tenir compte de tous ces aspects, ce qui explique pourquoi l'application s'exécute aussi bien sous 2.x que sous 3.x. Nous pouvons donc nous concentrer sur les modifications à apporter pour utiliser la plate-forme nouvelle génération.
Problèmes/commentaires concernant le module de migration App Engine en atelier de programmation
Si vous rencontrez des problèmes avec cet atelier de programmation, commencez par faire une recherche avant de les signaler. Liens vers la recherche et la création d'un signalement :
Ressources de migration
Vous trouverez des liens vers les dossiers des dépôts du module 1 (code de départ "START") et du module 2 (code final "FINISH") dans le tableau ci-dessous. Vous pouvez également y accéder depuis le dépôt pour toutes les migrations d'ateliers de programmation App Engine que vous pouvez cloner ou télécharger sous forme de fichier ZIP.
Atelier de programmation | Python 2 | Python 3 |
(n/a) | ||
Module 2 |
Ressources App Engine
Vous trouverez ci-dessous d'autres ressources concernant cette migration en particulier :
- Références Python NDB
- (ANCIEN) Migration de Python 2.5 et
webapp
vers 2.7 etwebapp2
- Migrer vers Python 3 et l'environnement d'exécution nouvelle génération GAE
- Migration de GAE
ndb
vers Cloud NDB - Dépôt d'exemple de la documentation de migration GAE
ndb
vers Cloud NDB - Gestionnaires de scripts facultatifs
- La référence
entrypoint
- Exemples de fichiers
app.yaml
et bonnes pratiques - Autres exemples et bonnes pratiques
- Migrer des fichiers de configuration App Engine
- Page d'accueil Migration
- Migration de GAE
- Général