1. Présentation
La série d'ateliers de programmation Serverless Migration Station (tutoriels pratiques à suivre à votre rythme) et les vidéos associées ont pour but d'aider les développeurs sans serveur Google Cloud à moderniser leurs applications en les guidant à travers une ou plusieurs migrations, principalement en abandonnant les anciens services. Cela rend vos applications plus portables et vous offre plus d'options et de flexibilité, ce qui vous permet de les intégrer à un plus grand nombre de produits Cloud et d'y accéder, et de passer plus facilement à des versions de langage plus récentes. Bien qu'elle se concentre initialement sur les premiers utilisateurs de Cloud, principalement les développeurs App Engine (environnement standard), cette série est suffisamment vaste pour inclure d'autres plates-formes sans serveur telles que Cloud Functions et Cloud Run, ou d'autres, le cas échéant.
Cet atelier de programmation vous explique comment migrer du Blobstore App Engine vers Cloud Storage. Il existe également des migrations implicites depuis :
- Framework Web
webapp2vers Flask (abordé dans le module 1) - App Engine NDB vers Cloud NDB pour l'accès à Datastore (abordé dans le module 2)
- Python 2 vers Python 3 (l'application migrée est compatible avec Python 2 et Python 3)
Pour en savoir plus, consultez les modules de migration associés.
Vous apprendrez à
- Ajouter l'utilisation de l'API/bibliothèque Blobstore d'App Engine
- Stocker les importations des utilisateurs dans le service Blobstore
- Préparer l'étape suivante pour migrer vers Cloud Storage
Prérequis
- Un projet Google Cloud Platform avec un compte de facturation GCP actif
- Des connaissances de base en Python
- Une connaissance correcte des commandes Linux courantes
- Connaissances de base sur le développement et le déploiement d'applications App Engine
- Une application App Engine du module 15 fonctionnelle : suivez l'atelier de programmation du module 15 (recommandé) ou copiez l'application du module 15 depuis le dépôt.
Enquête
Comment allez-vous utiliser ce tutoriel ?
Quel est votre niveau d'expérience avec Python ?
Quel est votre niveau d'expérience avec les services Google Cloud ?
2. Arrière-plan
Cet atelier de programmation commence par l'application exemple du module 15 et montre comment migrer de Blobstore (et NDB) vers Cloud Storage (et Cloud NDB). Le processus de migration implique de remplacer les dépendances aux anciens services groupés d'App Engine, ce qui vous permet de déplacer vos applications vers une autre plate-forme sans serveur Cloud ou une autre plate-forme d'hébergement si vous le souhaitez.
Cette migration nécessite un peu plus d'efforts que les autres migrations de cette série. Blobstore dépend de l'environnement logiciel webapp d'origine. C'est pourquoi l'application exemple utilise l'environnement logiciel webapp2 au lieu de Flask. Ce tutoriel présente les migrations vers Cloud Storage, Cloud NDB, Flask et Python 3.
L'application enregistre toujours les "visites" des utilisateurs finaux et affiche les dix plus récentes, mais l'atelier de programmation précédent (module 15) a ajouté une nouvelle fonctionnalité pour prendre en compte l'utilisation de Blobstore : l'application invite les utilisateurs finaux à importer un artefact (un fichier) correspondant à leur "visite". Ils peuvent le faire ou sélectionner "Ignorer" pour refuser. Quelle que soit la décision de l'utilisateur, la page suivante affiche le même résultat que les versions précédentes de cette application, en affichant les visites les plus récentes. Autre particularité : les visites avec des artefacts correspondants comportent un lien "view" (afficher) permettant d'afficher l'artefact d'une visite. Cet atelier de programmation implémente les migrations mentionnées précédemment tout en préservant les fonctionnalités décrites.
3. Configuration/Préparation
Avant de passer à la partie principale du tutoriel, nous allons configurer notre projet, obtenir le code, puis déployer l'application de référence pour nous assurer que nous commençons avec un code fonctionnel.
1. Configurer le projet
Si vous avez déjà déployé l'application du module 15, 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 activé.
2. Obtenir un exemple d'application de référence
L'un des prérequis de cet atelier de programmation est de disposer d'une application exemple du module 15 fonctionnelle. Si vous n'en avez pas, vous pouvez l'obtenir à partir du dossier "START" du module 15 (lien ci-dessous). Cet atelier de programmation vous guide à travers chaque étape, pour aboutir à un code semblable à celui du dossier "FINISH" du module 16.
- DÉBUT : dossier du module 15 (Python 2)
- FINISH: Dossier du module 16 (Python 2)
- Dépôt complet (pour cloner ou télécharger le fichier ZIP)
Le répertoire des fichiers de départ du module 15 doit se présenter comme suit :
$ ls README.md app.yaml main-gcs.py main.py templates
Le fichier main-gcs.py est une version alternative de main.py du module 15. Il permet de sélectionner un bucket Cloud Storage différent de l'URL par défaut attribuée à une application en fonction de l'ID du projet : PROJECT_ID.appspot.com. Ce fichier ne joue aucun rôle dans cet atelier de programmation (module 16), mais des techniques de migration similaires peuvent lui être appliquées si vous le souhaitez.
3. (Re)Déployer l'application de référence
Étapes préliminaires restantes :
- Familiarisez-vous avec l'outil de ligne de commande
gcloud - Redéployez l'exemple d'application avec
gcloud app deploy - Vérifier que l'application s'exécute sans problème sur App Engine
Une fois que vous avez suivi ces étapes et confirmé que votre application du module 15 fonctionne, La page initiale présente aux utilisateurs un formulaire leur demandant d'importer un fichier d'artefact de visite, ainsi qu'une option (un bouton "Ignorer") pour désactiver cette fonctionnalité :

Une fois que les utilisateurs ont importé un fichier ou ignoré l'étape, l'application affiche la page "Visites les plus récentes" :

Les visites comportant un artefact incluent un lien "Afficher" à droite du code temporel de la visite pour afficher (ou télécharger) l'artefact. Une fois que vous avez vérifié le fonctionnement de l'application, vous pouvez migrer des anciens services App Engine (webapp2, NDB, Blobstore) vers des alternatives contemporaines (Flask, Cloud NDB, Cloud Storage).
4. Mettre à jour les fichiers de configuration
Trois fichiers de configuration entrent en jeu pour la version mise à jour de notre application. Les tâches requises sont les suivantes :
- Mettre à jour les bibliothèques tierces intégrées requises dans
app.yamlet laisser la porte ouverte à une migration vers Python 3 - Ajoutez un fichier
requirements.txtqui spécifie toutes les bibliothèques requises qui ne sont pas intégrées. - Ajoutez
appengine_config.pypour que l'application soit compatible avec les bibliothèques tierces intégrées et non intégrées.
app.yaml
Modifiez votre fichier app.yaml en mettant à jour la section libraries. Supprimez jinja2 et ajoutez grpcio, setuptools et ssl. Choisissez la dernière version disponible pour les trois bibliothèques. Ajoutez également la directive Python 3 runtime, mais mettez-la en commentaire. Lorsque vous avez terminé, le résultat doit se présenter comme suit (si vous avez sélectionné Python 3.9) :
AVANT :
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
APRÈS :
#runtime: python39
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: latest
- name: setuptools
version: latest
- name: ssl
version: latest
Les modifications concernent principalement les bibliothèques intégrées Python 2 disponibles sur les serveurs App Engine (vous n'avez donc pas besoin de les regrouper vous-même). Nous avons supprimé Jinja2, car il est fourni avec Flask, que nous allons ajouter à reqs.txt. Chaque fois que des bibliothèques clientes Google Cloud sont utilisées, telles que celles pour Cloud NDB et Cloud Storage, grpcio et setuptools sont nécessaires. Enfin, Cloud Storage nécessite la bibliothèque SSL. La directive d'exécution mise en commentaire en haut est destinée au moment où vous serez prêt à porter cette application vers Python 3. Nous aborderons ce sujet à la fin de ce tutoriel.
requirements.txt
Ajoutez un fichier requirements.txt, qui nécessite le framework Flask, ainsi que les bibliothèques clientes Cloud NDB et Cloud Storage, qui ne sont pas intégrées. Créez le fichier avec le contenu suivant :
flask
google-cloud-ndb
google-cloud-storage
L'environnement d'exécution Python 2 d'App Engine nécessite l'auto-regroupement des bibliothèques tierces non intégrées. Exécutez donc la commande suivante pour installer ces bibliothèques dans le dossier "lib" :
pip install -t lib -r requirements.txt
Si vous disposez à la fois de Python 2 et Python 3 sur votre ordinateur de développement, vous devrez peut-être utiliser la commande pip2 pour vous assurer d'obtenir les versions Python 2 de ces bibliothèques. Une fois que vous êtes passé à Python 3, vous n'avez plus besoin de regrouper vous-même les dépendances.
appengine_config.py
Ajoutez un fichier appengine_config.py compatible avec les bibliothèques tierces intégrées et non intégrées. Créez le fichier avec le contenu suivant :
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)
Les étapes que vous venez d'effectuer doivent être similaires ou identiques à celles de la section Installer des bibliothèques pour les applications Python 2 de la documentation App Engine. Plus précisément, le contenu de appengine_config.py doit correspondre à celui de l'étape 5.
La configuration des fichiers est terminée. Passons maintenant à l'application.
5. Modifier les fichiers d'application
Importations
La première série de modifications pour main.py consiste à remplacer tous les éléments à remplacer. Voici ce qui va changer :
webapp2est remplacé par Flask.- Au lieu d'utiliser Jinja2 depuis
webapp2_extras, utilisez le Jinja2 fourni avec Flask. - Le Blobstore App Engine et NDB sont remplacés par Cloud NDB et Cloud Storage
- Les gestionnaires Blobstore de
webappsont remplacés par une combinaison du module de bibliothèque standardio, de Flask et des utilitaireswerkzeug. - Par défaut, Blobstore écrit dans un bucket Cloud Storage nommé d'après l'URL de votre application (
PROJECT_ID.appspot.com). Comme nous effectuons un portage vers la bibliothèque cliente Cloud Storage,google.authest utilisé pour obtenir l'ID du projet afin de spécifier exactement le même nom de bucket. (Vous pouvez modifier le nom du bucket, car il n'est plus codé en dur.)
AVANT :
import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
Implémentez les modifications de la liste ci-dessus en remplaçant la section d'importation actuelle dans main.py par l'extrait de code ci-dessous.
APRÈS :
import io
from flask import (Flask, abort, redirect, render_template,
request, send_file, url_for)
from werkzeug.utils import secure_filename
import google.auth
from google.cloud import exceptions, ndb, storage
Initialisation et compatibilité Jinja2 inutile
Le bloc de code suivant à remplacer est le BaseHandler spécifiant l'utilisation de Jinja2 à partir de webapp2_extras. Cela n'est pas nécessaire, car Jinja2 est fourni avec Flask et est son moteur de création de modèles par défaut. Supprimez-le donc.
Du côté du module 16, instanciez les objets que nous n'avions pas dans l'ancienne application. Cela inclut l'initialisation de l'application Flask et la création de clients API pour Cloud NDB et Cloud Storage. Enfin, nous assemblons le nom du bucket Cloud Storage comme décrit ci-dessus dans la section "Importations". Voici un aperçu avant et après l'implémentation de ces modifications :
AVANT :
class BaseHandler(webapp2.RequestHandler):
'Derived request handler mixing-in Jinja2 support'
@webapp2.cached_property
def jinja2(self):
return jinja2.get_jinja2(app=self.app)
def render_response(self, _template, **context):
self.response.write(self.jinja2.render_template(_template, **context))
APRÈS :
app = Flask(__name__)
ds_client = ndb.Client()
gcs_client = storage.Client()
_, PROJECT_ID = google.auth.default()
BUCKET = '%s.appspot.com' % PROJECT_ID
Mettre à jour l'accès à Datastore
Cloud NDB est principalement compatible avec App Engine NDB. Une différence déjà abordée est la nécessité d'un client API. Une autre différence est que l'accès à Datastore doit être contrôlé par le gestionnaire de contexte Python du client API. En gros, cela signifie que tous les appels d'accès à Datastore utilisant la bibliothèque cliente Cloud NDB ne peuvent se produire que dans les blocs Python with.
C'est un changement.L'autre est que Blobstore et ses objets, par exemple les BlobKey, ne sont pas compatibles avec Cloud Storage. Remplacez donc file_blob par ndb.StringProperty. Vous trouverez ci-dessous la classe de modèle de données et les fonctions store_visit() et fetch_visits() mises à jour reflétant ces modifications :
AVANT :
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
file_blob = ndb.BlobKeyProperty()
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_blob=upload_key).put()
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
APRÈS :
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
file_blob = ndb.StringProperty()
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_blob=upload_key).put()
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
Voici une représentation visuelle des modifications apportées jusqu'à présent :

Mettre à jour les gestionnaires
Gestionnaire d'importation
Les gestionnaires dans webapp2 sont des classes, tandis que ce sont des fonctions dans Flask. Au lieu d'une méthode de verbe HTTP, Flask utilise le verbe pour décorer la fonction. Blobstore et ses gestionnaires webapp sont remplacés par les fonctionnalités de Cloud Storage, ainsi que par Flask et ses utilitaires :
AVANT :
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
'Upload blob (POST) handler'
def post(self):
uploads = self.get_uploads()
blob_id = uploads[0].key() if uploads else None
store_visit(self.request.remote_addr, self.request.user_agent, blob_id)
self.redirect('/', code=307)
APRÈS :
@app.route('/upload', methods=['POST'])
def upload():
'Upload blob (POST) handler'
fname = None
upload = request.files.get('file', None)
if upload:
fname = secure_filename(upload.filename)
blob = gcs_client.bucket(BUCKET).blob(fname)
blob.upload_from_file(upload, content_type=upload.content_type)
store_visit(request.remote_addr, request.user_agent, fname)
return redirect(url_for('root'), code=307)
Voici quelques informations concernant cette mise à jour :
- Plutôt que par un
blob_id, les artefacts de fichier sont désormais identifiés par leur nom de fichier (fname) s'il est présent, et parNonesinon (l'utilisateur a choisi de ne pas importer de fichier). - Les gestionnaires Blobstore ont fait abstraction du processus d'importation pour les utilisateurs, mais pas Cloud Storage. Vous pouvez donc voir le code récemment ajouté qui définit l'objet blob et l'emplacement (bucket) du fichier, ainsi que l'appel qui effectue l'importation proprement dite. (
upload_from_file()). webapp2utilise une table de routage au bas du fichier d'application, tandis que les routes Flask se trouvent dans chaque gestionnaire décoré.- Les deux gestionnaires terminent leur fonctionnalité en redirigeant vers la page d'accueil (
/) tout en conservant la requêtePOSTavec un code de retour HTTP 307.
Gestionnaire de téléchargement
La mise à jour du gestionnaire de téléchargement suit un schéma similaire à celui du gestionnaire d'importation, mais il y a beaucoup moins de code à examiner. Remplacez les fonctionnalités Blobstore et webapp par les équivalents Cloud Storage et Flask :
AVANT :
class ViewBlobHandler(blobstore_handlers.BlobstoreDownloadHandler):
'view uploaded blob (GET) handler'
def get(self, blob_key):
self.send_blob(blob_key) if blobstore.get(blob_key) else self.error(404)
APRÈS :
@app.route('/view/<path:fname>')
def view(fname):
'view uploaded blob (GET) handler'
blob = gcs_client.bucket(BUCKET).blob(fname)
try:
media = blob.download_as_bytes()
except exceptions.NotFound:
abort(404)
return send_file(io.BytesIO(media), mimetype=blob.content_type)
Remarques sur cette mise à jour :
- Là encore, Flask décore les fonctions de gestionnaire avec leur route, tandis que
webapple fait dans une table de routage en bas. Vous devez donc reconnaître la syntaxe de correspondance de modèles de ce dernier (('/view/([^/]+)?') par rapport à celle de Flask ('/view/<path:fname>'). - Comme pour le gestionnaire d'importation, un peu plus de travail est nécessaire côté Cloud Storage pour les fonctionnalités abstraites par les gestionnaires Blobstore, à savoir l'identification du fichier (blob) en question et le téléchargement explicite du binaire, par rapport à l'appel de méthode
send_blob()unique du gestionnaire Blobstore. - Dans les deux cas, une erreur HTTP 404 est renvoyée à l'utilisateur si un artefact est introuvable.
Gestionnaire principal
Les dernières modifications apportées à l'application principale ont lieu dans le gestionnaire principal. Les méthodes de verbe HTTP webapp2 sont remplacées par une seule fonction combinant leurs fonctionnalités. Remplacez la classe MainHandler par la fonction root() et supprimez la table de routage webapp2, comme indiqué ci-dessous :
AVANT :
class MainHandler(BaseHandler):
'main application (GET/POST) handler'
def get(self):
self.render_response('index.html',
upload_url=blobstore.create_upload_url('/upload'))
def post(self):
visits = fetch_visits(10)
self.render_response('index.html', visits=visits)
app = webapp2.WSGIApplication([
('/', MainHandler),
('/upload', UploadHandler),
('/view/([^/]+)?', ViewBlobHandler),
], debug=True)
APRÈS :
@app.route('/', methods=['GET', 'POST'])
def root():
'main application (GET/POST) handler'
context = {}
if request.method == 'GET':
context['upload_url'] = url_for('upload')
else:
context['visits'] = fetch_visits(10)
return render_template('index.html', **context)
Plutôt que de séparer les méthodes get() et post(), elles sont essentiellement une instruction if-else dans root(). De plus, comme root() est une fonction unique, il n'y a qu'un seul appel pour afficher le modèle pour GET et POST, alors que ce n'est pas vraiment possible dans webapp2.
Voici une représentation visuelle de ce deuxième et dernier ensemble de modifications apportées à main.py :

(Facultatif) "Amélioration" de la rétrocompatibilité
La solution créée ci-dessus fonctionne donc parfaitement, mais seulement si vous partez de zéro et que vous n'avez pas de fichiers créés par Blobstore. Comme nous avons mis à jour l'application pour identifier les fichiers par leur nom de fichier plutôt que par leur BlobKey, l'application du module 16 terminée ne pourra pas afficher les fichiers blobstore. En d'autres termes, nous avons apporté une modification non rétrocompatible en effectuant cette migration. Nous présentons maintenant une version alternative de main.py appelée main-migrate.py (disponible dans le dépôt) qui tente de combler cette lacune.
La première "extension" compatible avec les fichiers créés par Blobstore est un modèle de données qui comporte un BlobKeyProperty (en plus d'un StringProperty pour les fichiers créés par Cloud Storage) :
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
file_blob = ndb.BlobKeyProperty() # backwards-compatibility
file_gcs = ndb.StringProperty()
La propriété file_blob sera utilisée pour identifier les fichiers créés par Blobstore, tandis que file_gcs sera utilisée pour les fichiers Cloud Storage. Maintenant, lorsque vous créez des visites, stockez explicitement une valeur dans file_gcs au lieu de file_blob. Ainsi, store_visit est légèrement différent :
AVANT :
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_blob=upload_key).put()
APRÈS :
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_gcs=upload_key).put()
Lors de la récupération des visites les plus récentes, "normalisez" les données avant de les envoyer au modèle :
AVANT :
@app.route('/', methods=['GET', 'POST'])
def root():
'main application (GET/POST) handler'
context = {}
if request.method == 'GET':
context['upload_url'] = url_for('upload')
else:
context['visits'] = fetch_visits(10)
return render_template('index.html', **context)
APRÈS :
@app.route('/', methods=['GET', 'POST'])
def root():
'main application (GET/POST) handler'
context = {}
if request.method == 'GET':
context['upload_url'] = url_for('upload')
else:
context['visits'] = etl_visits(fetch_visits(10))
return render_template('index.html', **context)
Ensuite, confirmez l'existence de file_blob ou de file_gcs (ou d'aucun des deux). Si un fichier est disponible, sélectionnez celui qui existe et utilisez cet identifiant (BlobKey pour les fichiers créés par Blobstore ou le nom de fichier pour les fichiers créés par Cloud Storage). Par "fichiers créés par Cloud Storage", nous entendons les fichiers créés à l'aide de la bibliothèque cliente Cloud Storage. Blobstore écrit également dans Cloud Storage, mais dans ce cas, il s'agit de fichiers créés par Blobstore.
Plus important encore, qu'est-ce que cette fonction etl_visits() utilisée pour normaliser ou ETL (extraire, transformer et charger) les données pour l'utilisateur final ? Elle se présente comme suit :
def etl_visits(visits):
return [{
'visitor': v.visitor,
'timestamp': v.timestamp,
'file_blob': v.file_gcs if hasattr(v, 'file_gcs') \
and v.file_gcs else v.file_blob
} for v in visits]
Le résultat est probablement celui que vous attendiez : le code parcourt toutes les visites et, pour chacune d'elles, prend les données de visiteur et de code temporel telles quelles, puis vérifie si file_gcs ou file_blob existe. Si c'est le cas, il en choisit un (ou None si aucun n'existe).
Voici une illustration des différences entre main.py et main-migrate.py :

Si vous partez de zéro sans fichiers créés par Blobstore, utilisez main.py. En revanche, si vous effectuez une transition et que vous souhaitez prendre en charge les fichiers créés par Blobstore et Cloud Storage, consultez main-migrate.py pour obtenir un exemple de gestion de ce scénario afin de vous aider à planifier les migrations de vos propres applications. Lors de migrations complexes, des cas particuliers sont susceptibles de se produire. Cet exemple est donc destiné à montrer une plus grande affinité pour la modernisation d'applications réelles avec des données réelles.
6. Résumé/Nettoyage
Cette section conclut cet atelier de programmation en déployant l'application, en vérifiant qu'elle fonctionne comme prévu et en examinant les résultats. Après la validation de l'application, effectuez les étapes de nettoyage et réfléchissez aux étapes suivantes.
Déployer et vérifier l'application
Avant de redéployer votre application, veillez à exécuter pip install -t lib -r requirements.txt pour obtenir ces bibliothèques tierces auto-intégrées dans le dossier lib. Si vous souhaitez exécuter la solution rétrocompatible, renommez d'abord main-migrate.py en main.py. Exécutez maintenant gcloud app deploy et vérifiez que l'application fonctionne de la même manière que celle du module 15. L'écran du formulaire se présente comme suit :

La page des visites les plus récentes se présente comme suit :

Félicitations ! Vous avez terminé cet atelier de programmation qui vous a permis de remplacer App Engine Blobstore par Cloud Storage, App Engine NDB par Cloud NDB et webapp2 par Flask. Votre code doit maintenant correspondre à celui du dossier FINISH (Module 16). L'alternative main-migrate.py est également présente dans ce dossier.
"Migration" vers Python 3
La directive Python 3 runtime mise en commentaire en haut de app.yaml est tout ce dont vous avez besoin pour porter cette application vers Python 3. Le code source lui-même est déjà compatible avec Python 3. Aucune modification n'est donc nécessaire. Pour déployer cette application en tant qu'application Python 3, procédez comme suit :
- Supprimez les commentaires de la directive Python 3
runtimeen haut deapp.yaml. - Supprimez toutes les autres lignes de
app.yaml. - Supprimez le fichier
appengine_config.py. (non utilisé dans l'environnement d'exécution Python 3) - Supprimez le dossier
libs'il existe. (inutile avec l'environnement d'exécution Python 3)
Effectuer un nettoyage
Général
Si vous avez terminé pour le moment, nous vous recommandons de désactiver votre application App Engine pour éviter d'être facturé. Toutefois, si vous souhaitez effectuer d'autres tests ou essais, la plate-forme App Engine dispose d'un quota sans frais. Tant que vous ne dépassez pas ce niveau d'utilisation, aucuns frais ne devraient vous être facturés. Cela concerne le calcul, mais des frais peuvent également s'appliquer pour les services App Engine concernés. Pour en savoir plus, consultez la page des tarifs. Si cette migration implique d'autres services Cloud, ceux-ci sont facturés séparément. Dans les deux cas, le cas échéant, consultez la section "Spécifique à cet atelier de programmation" ci-dessous.
Pour être tout à fait transparent, le déploiement sur une plate-forme d'informatique sans serveur Google Cloud comme App Engine entraîne des coûts de compilation et de stockage mineurs. Cloud Build dispose de son propre quota sans frais, tout comme Cloud Storage. Le stockage de cette image utilise une partie de ce quota. Cependant, il est possible que vous viviez dans une région qui ne propose pas de niveau sans frais. Surveillez donc votre utilisation de l'espace de stockage pour minimiser les coûts potentiels. Voici quelques "dossiers" Cloud Storage spécifiques que vous devriez examiner :
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- Les liens de stockage ci-dessus dépendent de votre
PROJECT_IDet de votre *LOC*ation, par exemple "us" si votre application est hébergée aux États-Unis.
En revanche, si vous ne souhaitez pas continuer à utiliser cette application ou d'autres ateliers de programmation de migration associés et que vous souhaitez tout supprimer, arrêtez votre projet.
Spécifique à cet atelier de programmation
Les services listés ci-dessous sont spécifiques à cet atelier de programmation. Pour en savoir plus, consultez la documentation de chaque produit :
- Le service Blobstore d'App Engine est soumis aux quotas et limites de données stockées. Consultez-les, ainsi que la page des tarifs des anciens services groupés.
- Cloud Storage propose un niveau sans frais pour certaines régions. Pour en savoir plus, consultez également la page des tarifs généraux.
- Le service App Engine Datastore est fourni par Cloud Datastore (Cloud Firestore en mode Datastore), qui propose également un niveau sans frais. Pour en savoir plus, consultez la page des tarifs."
Notez que si vous avez migré du module 15 au module 16, vous aurez toujours des données dans Blobstore. C'est pourquoi nous incluons ses informations tarifaires ci-dessus.
Étapes suivantes
Au-delà de ce tutoriel, d'autres modules de migration axés sur l'abandon des anciens services groupés sont à prendre en compte :
- Module 2 : Migrer d'App Engine
ndbvers Cloud NDB - Modules 7 à 9 : migrer des tâches d'envoi de files d'attente de tâches App Engine vers Cloud Tasks
- Modules 12 et 13 : migrer du Memcache d'App Engine vers Cloud Memorystore
- Modules 18 et 19 : migrer des tâches de retrait de files d'attente de tâches depuis App Engine vers Cloud Pub/Sub
App Engine n'est plus la seule plate-forme sans serveur de Google Cloud. Si vous disposez d'une petite application App Engine ou d'une application aux fonctionnalités limitées et que vous souhaitez la transformer en microservice autonome, ou si vous souhaitez diviser une application monolithique en plusieurs composants réutilisables, vous pouvez envisager de passer à Cloud Functions. Si la conteneurisation fait partie de votre workflow de développement d'applications, en particulier s'il s'agit d'un pipeline CI/CD (intégration continue/livraison ou déploiement continus), envisagez de migrer vers Cloud Run. Ces scénarios sont couverts par les modules suivants :
- Migrer d'App Engine vers Cloud Functions : consultez le module 11.
- Migrer d'App Engine vers Cloud Run : consultez le module 4 pour conteneuriser votre application avec Docker ou le module 5 pour le faire sans conteneurs, sans connaissances de Docker ou sans
Dockerfile.
Le passage à une autre plate-forme sans serveur est facultatif. Nous vous recommandons d'examiner les meilleures options pour vos applications et vos cas d'utilisation avant d'apporter des modifications.
Quel que soit le module de migration que vous envisagez d'utiliser, vous pouvez accéder à l'ensemble du contenu de la station de migration sans serveur (ateliers de programmation, vidéos, code source [si disponible]) dans son dépôt Open Source. Le fichier README du dépôt fournit également des conseils sur les migrations à envisager et l'ordre pertinent des modules de migration.
7. Ressources supplémentaires
Problèmes/commentaires concernant l'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 les liens vers les dossiers du dépôt pour le module 15 (START) et le module 16 (FINISH) dans le tableau ci-dessous. Vous pouvez également y accéder à partir du dépôt de 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 |
Module 15 | N/A | |
Module 16 (cet atelier de programmation) | (identique à Python 2) |
Ressources en ligne
Voici des ressources en ligne qui peuvent être utiles pour ce tutoriel :
Blobstore App Engine et Cloud Storage
- Service Blobstore App Engine
- Migrer vers la bibliothèque cliente Cloud Storage
- Page d'accueil Cloud Storage
- Documentation Cloud Storage
Plate-forme App Engine
- Documentation App Engine
- Environnement d'exécution Python 2 App Engine (environnement standard)
- Utiliser les bibliothèques intégrées d'App Engine sur App Engine Python 2
- Environnement d'exécution Python 3 App Engine (environnement standard)
- Différences entre les environnements d'exécution Python 2 et Python 3 d'App Engine (environnement standard)
- Guide de migration d'App Engine (environnement standard) de Python 2 vers Python 3
- Informations sur les tarifs et les quotas d'App Engine
- Lancement de la plate-forme App Engine de deuxième génération (2018)
- Comparer les plates-formes de première et de deuxième génération
- Support à long terme pour les anciens environnements d'exécution
- Dépôt d'exemples de migration de la documentation
- Dépôt d'exemples de migration fournis par la communauté
Informations sur les autres clouds
- Python sur Google Cloud Platform
- Bibliothèques clientes Google Cloud Python
- Niveau "Toujours sans frais" de Google Cloud
- Google Cloud SDK (outil de ligne de commande
gcloud) - Toute la documentation Google Cloud
Python
- Systèmes de modèles Django et Jinja2
- Framework Web
webapp2 - Documentation sur
webapp2 webapp2_extrasassociations- Documentation Jinja2
webapp2_extras - Framework Web Flask
Vidéos
- Serverless Migration Station
- Serverless Expeditions
- S'abonner à Google Cloud Tech
- S'abonner à Google Developers
Licence
Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.