1. Présentation
La série d'ateliers de programmation sur la station de migration sans serveur (tutoriels pratiques et d'auto-formation) et les vidéos associées visent à aider les développeurs sans serveur Google Cloud à moderniser leurs applications en les guidant dans une ou plusieurs migrations, principalement en abandonnant les anciens services. Vous améliorez ainsi la portabilité de vos applications, et vous bénéficiez de plus d'options et de flexibilité. Vous pouvez ainsi intégrer un plus large éventail de produits Cloud et y accéder, et passer plus facilement à de nouvelles langues. Bien qu'elle s'adresse initialement aux utilisateurs les plus anciens du cloud, principalement les développeurs d'environnements App Engine (standard), cette série est suffisamment large pour inclure d'autres plates-formes sans serveur telles que Cloud Functions et Cloud Run, ou ailleurs, le cas échéant.
Cet atelier de programmation du module 15 explique comment ajouter l'utilisation de blobstore
App Engine à l'application exemple du module 0. Vous serez ensuite prêt à migrer cette utilisation vers Cloud Storage dans le prochain module 16.
Vous apprendrez à
- Ajouter l'utilisation de l'API/de la bibliothèque Blobstore d'App Engine
- Stocker les importations des utilisateurs dans le service
blobstore
- Préparez la prochaine étape de migration 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 0 opérationnelle (obtenir 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 ?
<ph type="x-smartling-placeholder">2. Contexte
Pour effectuer la migration à partir de l'API Blobstore d'App Engine, ajoutez son utilisation à l'application ndb
App Engine de référence existante à partir du module 0. L'application exemple affiche les dix visites les plus récentes de l'utilisateur. Nous modifions l'application pour inviter l'utilisateur final à importer un artefact (un fichier) correspondant à sa "visite". Si l'utilisateur ne souhaite pas le faire, une option "Ignorer" . Quelle que soit la décision de l'utilisateur, la page suivante affiche la même sortie que l'application du module 0 (et de nombreux autres modules de cette série). Une fois l'intégration de blobstore
App Engine implémentée, nous pouvons la migrer vers Cloud Storage dans le prochain atelier de programmation (module 16).
App Engine permet d'accéder aux systèmes de création de modèles Django et Jinja2. Cet exemple est différent (outre l'ajout d'un accès au gsutil) : il passe de Django dans le module 0 à Jinja2 dans le module 15. Une étape clé de la modernisation des applications App Engine consiste à migrer les frameworks Web de webapp2
vers Flask. Ce dernier utilise Jinja2 comme système de création de modèles par défaut. Nous commençons donc à avancer dans cette direction en implémentant Jinja2 tout en restant sur webapp2
pour l'accès au StatefulSet. Étant donné que Flask utilise Jinja2 par défaut, aucune modification du modèle ne sera nécessaire dans le module 16.
3. Configuration/Préparation
Avant de passer à la partie principale du tutoriel, vous devez configurer votre projet, obtenir le code et déployer l'application de référence pour commencer avec du code fonctionnel.
1. Configurer le projet
Si vous avez déjà déployé l'application du module 0, 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'une des conditions préalables à cet atelier de programmation est de disposer d'une application exemple du module 0 qui fonctionne. Si vous ne l'avez pas, vous pouvez l'obtenir à partir du module 0 "DÉMARRER". (lien ci-dessous). Cet atelier de programmation présente chaque étape, se terminant par un code semblable à celui du module 15 "FINISH" .
- DÉBUT: dossier du module 0 (Python 2)
- FINISH: dossier du module 15 (Python 2)
- Dépôt complet (pour cloner ou télécharger le fichier ZIP)
Le répertoire des fichiers de démarrage du module 0 devrait ressembler à ceci:
$ ls README.md index.html app.yaml main.py
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 exécuté ces étapes et constaté que votre application Web fonctionne (avec un résultat semblable à celui ci-dessous), vous pouvez ajouter la mise en cache à votre application.
4. Mettre à jour les fichiers de configuration
app.yaml
Aucune modification importante n'a été apportée à la configuration de l'application. Toutefois, comme indiqué précédemment, nous passons du modèle Django (par défaut) à Jinja2. Pour effectuer cette transition, les utilisateurs doivent spécifier la dernière version de Jinja2 disponible sur les serveurs App Engine. Pour ce faire, ajoutez-la à la section des bibliothèques tierces intégrées de app.yaml
.
AVANT:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Modifiez votre fichier app.yaml
en ajoutant une nouvelle section libraries
comme dans cet exemple:
APRÈS:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
Aucun autre fichier de configuration n'a besoin d'être mis à jour. Passons donc aux fichiers d'application.
5. Modifier les fichiers d'application
Importations et prise en charge de Jinja2
Le premier ensemble de modifications pour main.py
inclut l'ajout de l'utilisation de l'API Blobstore et le remplacement des modèles Django par Jinja2. Voici ce qui va changer:
- L'objectif du module
os
est de créer un nom de chemin d'accès à un modèle Django. Étant donné que nous passons à Jinja2, où cela est géré, l'utilisation deos
ainsi que du moteur de rendu de modèle Django,google.appengine.ext.webapp.template
, ne sont plus nécessaires. Ils sont donc supprimés. - Importez l'API Blobstore:
google.appengine.ext.blobstore
- Importez les gestionnaires gsutil trouvés dans le framework
webapp
d'origine (ils ne sont pas disponibles danswebapp2
) :google.appengine.ext.webapp.blobstore_handlers
- Importer la prise en charge Jinja2 à partir du package
webapp2_extras
AVANT:
import os
import webapp2
from google.appengine.ext import ndb
from google.appengine.ext.webapp import template
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 webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
Après les importations, ajoutez du code récurrent pour permettre l'utilisation de Jinja2, tel que défini dans la documentation webapp2_extras
. L'extrait de code suivant encapsule la classe standard du gestionnaire de requêtes webapp2 avec la fonctionnalité Jinja2. Vous devez donc ajouter ce bloc de code à main.py
juste après les importations:
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))
Ajouter la prise en charge de Blobstore
Contrairement aux autres migrations de cette série, où nous gardons la fonctionnalité ou la sortie de l'application exemple identiques (ou presque identiques) sans modifier (beaucoup) l'expérience utilisateur, cet exemple s'écarte plus radicalement de la norme. Plutôt que d'enregistrer immédiatement une nouvelle visite et d'afficher les dix derniers, nous mettons à jour l'application pour demander à l'utilisateur un artefact de fichier dans lequel enregistrer sa visite. Les utilisateurs finaux peuvent alors importer un fichier correspondant ou sélectionner "Ignorer". de ne rien importer. Une fois cette étape terminée, les "visites les plus récentes" s'affiche.
Cette modification permet à notre application d'utiliser le service vTPM pour stocker (et éventuellement afficher ultérieurement) cette image ou un autre type de fichier sur la page des visites les plus récentes.
Mettre à jour le modèle de données et implémenter son utilisation
Nous stockons davantage de données, en particulier en mettant à jour le modèle de données pour stocker l'ID (appelé "BlobKey
") du fichier importé dans Blobstore et en ajoutant une référence pour l'enregistrer dans store_visit()
. Étant donné que ces données supplémentaires sont renvoyées avec tout le reste lors de la requête, fetch_visits()
reste le même.
Voici l'avant et l'après avec ces nouveautés avec file_blob
, un ndb.BlobKeyProperty
:
AVANT:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
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 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.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)
Voici une illustration des modifications apportées jusqu'à présent:
Permettre l'importation de fichiers
Le changement de fonctionnalité le plus important concerne la prise en charge des importations de fichiers, qu'il s'agisse de demander un fichier à l'utilisateur ou de prendre en charge l'option "Ignorer". ou encore l'affichage d'un fichier correspondant à une visite. Tout cela fait partie de l'image. Voici les modifications requises pour importer des fichiers:
- La requête du gestionnaire principal
GET
ne récupère plus les visites les plus récentes pour les afficher. Au lieu de cela, il invite l'utilisateur à effectuer une importation. - Lorsqu'un utilisateur final envoie un fichier à importer ou ignore ce processus, un
POST
du formulaire transmet le contrôle au nouveauUploadHandler
, dérivé degoogle.appengine.ext.webapp.blobstore_handlers.BlobstoreUploadHandler
. - La méthode
POST
deUploadHandler
effectue l'importation, appellestore_visit()
pour enregistrer la visite et déclenche une redirection HTTP 307 pour renvoyer l'utilisateur vers "/", où... - La méthode
POST
du gestionnaire principal recherche (viafetch_visits()
) et affiche les visites les plus récentes. Si l'utilisateur sélectionne « ignorer », aucun fichier n'est importé, mais la visite est tout de même enregistrée, suivie de la même redirection. - L'affichage des visites les plus récentes inclut un nouveau champ présenté à l'utilisateur : une "vue" sous forme de lien hypertexte. si un fichier d'importation est disponible ou "aucun" ; sinon. Ces modifications sont apportées au modèle HTML avec l'ajout d'un formulaire de téléchargement (plus d'informations à ce sujet bientôt).
- Si un utilisateur final clique sur l'option "Afficher" pour toute visite sur une vidéo mise en ligne, il envoie une requête
GET
à un nouveauViewBlobHandler
, dérivé degoogle.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandler
. Soit le fichier s'affiche si une image est disponible (dans le navigateur si compatible), soit il invite à télécharger le fichier si ce n'est pas le cas, ou une erreur HTTP 404 est renvoyée s'il est introuvable. - En plus de la nouvelle paire de classes de gestionnaire et d'une nouvelle paire de routes pour leur envoyer du trafic, le gestionnaire principal a besoin d'une nouvelle méthode
POST
pour recevoir la redirection 307 décrite ci-dessus.
Avant ces mises à jour, l'application du module 0 ne comportait qu'un gestionnaire principal avec une méthode GET
et une seule route:
AVANT:
class MainHandler(webapp2.RequestHandler):
'main application (GET) handler'
def get(self):
store_visit(self.request.remote_addr, self.request.user_agent)
visits = fetch_visits(10)
tmpl = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(tmpl, {'visits': visits}))
app = webapp2.WSGIApplication([
('/', MainHandler),
], debug=True)
Une fois ces mises à jour implémentées, trois gestionnaires sont désormais disponibles: 1) un gestionnaire d'importation avec une méthode POST
, 2) un "blob d'affichage" télécharger le gestionnaire avec une méthode GET
et 3) le gestionnaire principal avec les méthodes GET
et POST
. Apportez ces modifications pour que le reste de votre application se présente comme suit.
APRÈS:
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)
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)
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)
Ce code que nous venons d'ajouter contient plusieurs appels de clés:
- Dans
MainHandler.get
, un appel est envoyé àblobstore.create_upload_url
. Cet appel génère l'URL vers laquelle le formatPOST
est utilisé, appelant le gestionnaire d'importation pour envoyer le fichier à Blobstore. - Dans
UploadHandler.post
, un appel est envoyé àblobstore_handlers.BlobstoreUploadHandler.get_uploads
. C'est la magie qui consiste à placer le fichier dans le Blobstore et à renvoyer un ID unique et persistant pour ce fichier, sonBlobKey
. - Dans
ViewBlobHandler.get
, appelerblobstore_handlers.BlobstoreDownloadHandler.send
avec l'BlobKey
d'un fichier extrait le fichier et le transfère vers le navigateur de l'utilisateur final.
Ces appels représentent l'essentiel de l'accès aux fonctionnalités ajoutées à l'application. Voici une illustration de ce deuxième et dernier ensemble de modifications apportées à main.py
:
Mettre à jour le modèle HTML
Certaines des mises à jour apportées à l'application principale affectent l'interface utilisateur (UI) de l'application. Par conséquent, les modifications correspondantes sont requises dans le modèle Web. En fait, deux d'entre elles sont requises:
- Un formulaire d'importation de fichier est obligatoire. Il doit comporter trois éléments d'entrée: un fichier et deux boutons "Envoyer", respectivement pour importer et ignorer le fichier.
- Mettre à jour le nombre de visites les plus récentes en ajoutant une "vue" lien pour les visites avec une importation de fichier correspondante ou "aucun" sinon.
AVANT:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
</body>
</html>
Implémentez les modifications de la liste ci-dessus pour inclure le modèle mis à jour:
APRÈS:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>
<h1>VisitMe example</h1>
{% if upload_url %}
<h3>Welcome... upload a file? (optional)</h3>
<form action="{{ upload_url }}" method="POST" enctype="multipart/form-data">
<input type="file" name="file"><p></p>
<input type="submit"> <input type="submit" value="Skip">
</form>
{% else %}
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }}
<i><code>
{% if visit.file_blob %}
(<a href="/view/{{ visit.file_blob }}" target="_blank">view</a>)
{% else %}
(none)
{% endif %}
</code></i>
from {{ visit.visitor }}
</li>
{% endfor %}
</ul>
{% endif %}
</body>
</html>
Cette image illustre les mises à jour requises pour index.html
:
Une dernière modification est que Jinja2 préfère ses modèles dans un dossier templates
. Vous devez donc créer ce dossier et y déplacer index.html
. Vous avez apporté toutes les modifications nécessaires à l'ajout de l'utilisation de vTPM à l'application exemple du module 0.
(Facultatif) "Amélioration" Cloud Storage
Le stockage Blobstore a finalement évolué vers Cloud Storage lui-même. Cela signifie que les importations Blobstore sont visibles dans la console Cloud, et plus particulièrement dans le navigateur Cloud Storage. La question est de savoir où. La réponse est le bucket Cloud Storage par défaut de votre application App Engine. Son nom correspond au nom de domaine complet de votre application App Engine, PROJECT_ID
.appspot.com
. C'est très pratique, car tous les ID de projet sont uniques, n'est-ce pas ?
Les mises à jour apportées à l'exemple d'application suppriment les fichiers importés dans ce bucket, mais les développeurs ont la possibilité de choisir un emplacement plus spécifique. Le bucket par défaut est accessible de manière programmatique via google.appengine.api.app_identity.get_default_gcs_bucket_name()
, ce qui nécessite une nouvelle importation si vous souhaitez accéder à cette valeur (par exemple, pour l'utiliser comme préfixe pour organiser les fichiers importés). Par exemple, pour trier par type de fichier:
Pour implémenter ce type de code pour les images, par exemple, vous disposez d'un code semblable à celui-ci, ainsi que d'un autre code qui vérifie les types de fichiers pour choisir le nom de bucket souhaité:
ROOT_BUCKET = app_identity.get_default_gcs_bucket_name()
IMAGE_BUCKET = '%s/%s' % (ROOT_BUCKET, 'images')
Vous validerez également les images importées à l'aide d'un outil comme le module imghdr
de la bibliothèque standard Python pour confirmer le type d'image. Enfin, nous vous conseillons de limiter la taille des vidéos mises en ligne en cas d'utilisateurs malintentionnés.
Disons que tout a été fait. Comment pouvons-nous mettre à jour notre application afin qu'elle prenne en charge la spécification de l'emplacement de stockage des fichiers importés ? La clé consiste à modifier l'appel à blobstore.create_upload_url
dans MainHandler.get
afin de spécifier l'emplacement souhaité dans Cloud Storage pour l'importation en ajoutant le paramètre gs_bucket_name
comme suit:
blobstore.create_upload_url('/upload', gs_bucket_name=IMAGE_BUCKET))
Comme il s'agit d'une mise à jour facultative qui permet d'indiquer l'emplacement des importations, elle ne fait pas partie du fichier main.py
du dépôt. Vous disposez à la place d'une alternative nommée main-gcs.py
pour examen dans le dépôt. Plutôt que d'utiliser un "dossier" de bucket distinct, le code dans main-gcs.py
stocke les importations dans le répertoire "root" bucket (PROJECT_ID
.appspot.com
) comme main.py
, mais fournit l'échafaudage dont vous avez besoin si vous souhaitez extraire l'échantillon dans une autre structure, comme indiqué dans cette section. Voici une illustration des différences entre main.py
et main-gcs.py
.
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 dans tout résultat réfléchi. Après la validation de l'application, effectuez toutes les étapes de nettoyage et réfléchissez aux prochaines étapes.
Déployer et vérifier l'application
Redéployez votre application avec gcloud app deploy
et vérifiez qu'elle fonctionne comme annoncé, et que son expérience utilisateur est différente de celle de l'application du module 0. Votre application comporte désormais deux écrans différents, le premier étant l'invite du formulaire d'importation du fichier de visite:
Les utilisateurs finaux peuvent alors importer un fichier, puis cliquer sur "Envoyer". ou cliquez sur "Ignorer" de ne rien importer. Dans les deux cas, le résultat obtenu est l'écran de visite le plus récent, auquel est désormais ajouté la mention "view". liens ou "aucun" entre les codes temporels des visites et les informations sur les visiteurs:
Félicitations ! Vous avez terminé cet atelier de programmation, qui a permis d'utiliser le pool d'App Engine dans l'application exemple du module 0. Votre code devrait maintenant correspondre à ce qui se trouve dans le dossier FINISH (Module 15). Le fichier main-gcs.py
alternatif est également présent dans ce dossier.
Effectuer un nettoyage
Général
Si vous avez terminé, nous vous recommandons de désactiver votre application App Engine afin d'éviter que des frais ne vous soient facturés. Toutefois, si vous souhaitez effectuer d'autres tests, 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 vous seront 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 sa 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 "Informations spécifiques à cet atelier de programmation" ci-dessous.
Afin d'informer l'ensemble des utilisateurs, le déploiement sur une plate-forme de calcul sans serveur Google Cloud comme App Engine entraîne des coûts minimes de compilation et de stockage. Cloud Build et Cloud Storage disposent de leur propre quota sans frais. Le stockage de cette image utilise une partie de ce quota. Cependant, vous pouvez résider dans une région qui n'offre pas ce type de version sans frais. Vous devez donc surveiller l'utilisation de votre espace de stockage afin de réduire les coûts potentiels. "Dossiers" Cloud Storage spécifiques vous devez examiner:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
- Les liens de stockage ci-dessus dépendent de votre
PROJECT_ID
et de votre *LOC
*ation (par exemple, "us
") si votre application est hébergée aux États-Unis.
En revanche, si vous ne comptez pas utiliser cette application ou d'autres ateliers de programmation liés à la migration, et que vous souhaitez tout supprimer complètement, arrêtez votre projet.
Spécifique à cet atelier de programmation
Les services listés ci-dessous sont propres à 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 des données stockées. Nous vous invitons à le consulter, ainsi que la page des tarifs des anciens services groupés.
- Le service App Engine Datastore est fourni par Cloud Datastore (Cloud Firestore en mode Datastore), également disponible avec une version sans frais. consultez la page des tarifs pour en savoir plus.
Étapes suivantes
La prochaine migration logique à envisager est traitée dans le module 16, qui montre aux développeurs comment migrer du service Blobstore d'App Engine vers la bibliothèque cliente Cloud Storage. La mise à niveau présente plusieurs avantages, dont la possibilité d'accéder à davantage de fonctionnalités Cloud Storage et de se familiariser avec une bibliothèque cliente compatible avec les applications en dehors d'App Engine, que ce soit dans Google Cloud, dans d'autres clouds ou même sur site. Si vous n'avez pas l'impression d'avoir besoin de toutes les fonctionnalités disponibles dans Cloud Storage ou si vous êtes préoccupé par l'impact de leurs coûts sur les coûts, vous êtes libre de rester sur App Engine Blobstore.
Au-delà du module 16, il existe de nombreuses autres migrations possibles, telles que Cloud NDB et Cloud Datastore, Cloud Tasks ou Cloud Memorystore. Il existe également des migrations de produits vers Cloud Run et Cloud Functions. Le dépôt de migration contient tous les exemples de code, vous redirige vers l'ensemble des ateliers de programmation et des vidéos disponibles, et fournit également des indications sur les migrations à envisager et l'ordre d'exécution pertinent. des migrations.
7. Ressources supplémentaires
Commentaires et problèmes concernant les ateliers 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
Le tableau ci-dessous contient des liens vers les dossiers de dépôt des modules 0 (START) et 15 (FINISH). Vous pouvez également y accéder à partir du dépôt de toutes les migrations de l'atelier 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 0 | N/A | |
Module 15 (cet atelier de programmation) | N/A |
Ressources en ligne
Vous trouverez ci-dessous des ressources en ligne qui peuvent vous être utiles pour ce tutoriel:
App Engine
- Service Blobstore d'App Engine
- Quotas et limites des données stockées dans App Engine
- Documentation App Engine
- Environnement d'exécution App Engine (environnement standard) Python 2
- Utiliser les bibliothèques intégrées d'App Engine dans la version Python 2 d'App Engine
- Informations sur les tarifs et les quotas d'App Engine
- Lancement de la plate-forme App Engine de deuxième génération (2018)
- Comparaison entre les première et plates-formes de deuxième génération
- Compatibilité à long terme avec les anciens environnements d'exécution
- Dépôt d'exemples de migration de la documentation
- Dépôt d'exemples de migration provenant de la communauté
Google Cloud
- Python sur Google Cloud Platform
- Bibliothèques clientes Google Cloud Python
- "Toujours sans frais" de Google Cloud niveau
- SDK Google Cloud (outil de ligne de commande gcloud)
- Toute la documentation Google Cloud
Python
- Les systèmes de création de modèles Django et Jinja2
- Framework Web
webapp2
- Documentation sur
webapp2
webapp2_extras
lienswebapp2_extras
Documentation Jinja2
Vidéos
- Station de migration sans serveur
- Expéditions sans serveur
- S'abonner à Google Cloud Tech
- S'abonner à Google Developers
Licence
Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.