arrow_back

Développer des applications sur Google Cloud : ajouter une authentification utilisateur et une fonctionnalité intelligente à votre application

Accédez à plus de 700 ateliers et cours

Développer des applications sur Google Cloud : ajouter une authentification utilisateur et une fonctionnalité intelligente à votre application

Atelier 1 heure 30 minutes universal_currency_alt 5 crédits show_chart Intermédiaire
info Cet atelier peut intégrer des outils d'IA pour vous accompagner dans votre apprentissage.
Accédez à plus de 700 ateliers et cours

Présentation

Les bibliothèques clientes Cloud sont la méthode recommandée pour appeler les API Google Cloud à partir de vos applications. Elles utilisent les conventions et le style naturels du langage de programmation dont vous vous servez pour votre application. Les bibliothèques clientes Cloud gèrent la communication de bas niveau avec le serveur, y compris l'authentification et la logique de nouvelle tentative.

Conçu pour le scaling automatique et les hautes performances, Firestore est une base de données de documents NoSQL sans serveur, entièrement gérée et rapide qui simplifie le développement d'applications.

Les API Google utilisent le protocole OAuth 2.0 pour l'authentification et l'autorisation.

Secret Manager vous permet de stocker des clés API, des mots de passe, des certificats et d'autres données sensibles sous forme de blobs binaires ou de chaînes de texte.

L'API Cloud Translation permet à vos sites Web et à vos applications de traduire dynamiquement du texte de manière programmatique. Cloud Translation peut traduire du texte dans plus de 100 langues et détecter la langue du texte source.

Dans cet atelier, vous allez mettre à jour une application Python qui gère une liste de livres. Vous allez ajouter la possibilité de se connecter à l'application à l'aide d'OAuth et d'exiger que l'utilisateur se connecte pour ajouter, modifier ou supprimer des livres.

Vous allez également utiliser l'API Cloud Translation pour traduire les descriptions des livres dans une autre langue. Vous allez ajouter un profil utilisateur qui stocke la langue préférée de l'utilisateur.

Objectifs de l'atelier

Dans cet atelier, vous apprendrez à effectuer les tâches suivantes :

  • Créer une application Web Python Flask simple
  • Utiliser Secret Manager pour stocker les données d'application sensibles
  • Utiliser OAuth 2.0 pour ajouter la connexion utilisateur à une application
  • Utiliser l'API Cloud Translation pour détecter la langue du texte et le traduire

Préparation

Avant de cliquer sur le bouton "Démarrer l'atelier"

Remarque : Lisez ces instructions.

Les ateliers sont minutés, et vous ne pouvez pas les mettre en pause. Le minuteur, qui démarre lorsque vous cliquez sur Démarrer l'atelier, indique combien de temps les ressources Google Cloud resteront accessibles.

Cet atelier pratique Qwiklabs vous permet de suivre vous-même les activités dans un véritable environnement cloud, et non dans un environnement de simulation ou de démonstration. Des identifiants temporaires vous sont fournis pour vous permettre de vous connecter à Google Cloud le temps de l'atelier.

Conditions requises

Pour réaliser cet atelier, vous devez :

  • avoir accès à un navigateur Internet standard (nous vous recommandons d'utiliser Chrome) ;
  • disposer de suffisamment de temps pour effectuer l'atelier en une fois.
Remarque : Si vous possédez déjà votre propre compte ou projet Google Cloud, veillez à ne pas l'utiliser pour réaliser cet atelier. Remarque : Si vous utilisez un Pixelbook, veuillez exécuter cet atelier dans une fenêtre de navigation privée.

Démarrer votre atelier et vous connecter à la console

  1. Cliquez sur le bouton Démarrer l'atelier. Si l'atelier est payant, un pop-up s'affiche pour vous permettre de sélectionner un mode de paiement. Sur la gauche, vous verrez un panneau contenant les identifiants temporaires à utiliser pour cet atelier.

    Panneau d'identifiants

  2. Copiez le nom d'utilisateur, puis cliquez sur Ouvrir la console Google. L'atelier lance les ressources, puis la page Sélectionner un compte dans un nouvel onglet.

    Remarque : Ouvrez les onglets dans des fenêtres distinctes, placées côte à côte.
  3. Sur la page "Sélectionner un compte", cliquez sur Utiliser un autre compte. La page de connexion s'affiche.

    Boîte de dialogue "Sélectionner un compte" avec l'option "Utiliser un autre compte" encadrée.

  4. Collez le nom d'utilisateur que vous avez copié dans le panneau "Détails de connexion". Copiez et collez ensuite le mot de passe.

Remarque : Vous devez utiliser les identifiants fournis dans le panneau "Détails de connexion", et non vos identifiants Google Cloud Skills Boost. Si vous possédez un compte Google Cloud, ne vous en servez pas pour cet atelier (vous éviterez ainsi que des frais vous soient facturés).
  1. Accédez aux pages suivantes :
  • Acceptez les conditions d'utilisation.
  • N'ajoutez pas d'options de récupération ni d'authentification à deux facteurs (ce compte est temporaire).
  • Ne vous inscrivez pas aux essais offerts.

Après quelques instants, la console Cloud s'ouvre dans cet onglet.

Remarque : Vous pouvez afficher le menu qui contient la liste des produits et services Google Cloud en cliquant sur le menu de navigation en haut à gauche. Menu de la console Cloud

Activer Google Cloud Shell

Google Cloud Shell est une machine virtuelle qui contient de nombreux outils pour les développeurs. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud.

Google Cloud Shell vous permet d'accéder à vos ressources Google Cloud grâce à une ligne de commande.

  1. Dans la barre d'outils située en haut à droite dans la console Cloud, cliquez sur le bouton "Ouvrir Cloud Shell".

    Icône Cloud Shell encadrée

  2. Cliquez sur Continuer.

Le provisionnement et la connexion à l'environnement prennent quelques instants. Une fois connecté, vous êtes en principe authentifié et le projet est défini sur votre ID_PROJET. Par exemple :

ID de projet mis en évidence dans le terminal Cloud Shell

gcloud est l'outil de ligne de commande pour Google Cloud. Il est préinstallé sur Cloud Shell et permet la complétion par tabulation.

  • Vous pouvez lister les noms des comptes actifs à l'aide de cette commande :
gcloud auth list

Résultat :

Credentialed accounts: - @.com (active)

Exemple de résultat :

Credentialed accounts: - google1623327_student@qwiklabs.net
  • Vous pouvez lister les ID de projet à l'aide de cette commande :
gcloud config list project

Résultat :

[core] project =

Exemple de résultat :

[core] project = qwiklabs-gcp-44776a13dea667a6 Remarque : Pour consulter la documentation complète sur gcloud, accédez au guide de présentation de la gcloud CLI.

Tâche 1 : Configurer l'application Python et les ressources nécessaires

Dans cette tâche, vous allez télécharger l'application Python et créer les ressources utilisées par la version actuelle de l'application.

Remarque : La plupart des langages utilisent le retrait pour rendre le code plus lisible. En Python, le retrait sert à indiquer un bloc de code. Il doit donc être correct. Le nombre d'espaces de retrait doit être cohérent. Utiliser à la fois des espaces et des tabulations comme indicateurs de retrait peut également entraîner des problèmes. Dans cet atelier, un retrait en Python correspond à une série de quatre espaces.

Créer la base de données Firestore

  1. Pour créer la base de données Firestore, exécutez la commande suivante dans Cloud Shell :

    gcloud firestore databases create --location={{{ project_0.default_region | region }}}

    La base de données Firestore est utilisée pour stocker les données des livres et des profils utilisateur.

  2. Si vous êtes invité à autoriser Cloud Shell, cliquez sur Autoriser.

Créer le bucket Cloud Storage avec les autorisations appropriées

  1. Pour créer le bucket Cloud Storage, exécutez la commande suivante :

    gcloud storage buckets create gs://{{{ project_0.project_id | project_id}}}-covers --location={{{ project_0.default_region | region }}} --no-public-access-prevention --uniform-bucket-level-access

    Le bucket Cloud Storage est utilisé pour stocker les images des couvertures de livres. Il dispose d'un accès uniforme au niveau du bucket et n'utilise pas la protection contre l'accès public.

    Remarque : Si la commande échoue avec un message d'erreur indiquant que les identifiants du compte ne sont pas valides, essayez de la réexécuter. Il se peut que les autorisations du compte participant Qwiklabs ne se soient pas encore propagées.
  2. Pour rendre tous les objets du bucket lisibles publiquement, exécutez la commande suivante :

    gcloud storage buckets add-iam-policy-binding gs://{{{ project_0.project_id | project_id}}}-covers --member=allUsers --role=roles/storage.legacyObjectReader

Cliquez sur Vérifier ma progression pour valider l'objectif. Configurer l'application Python et les ressources nécessaires

Copier le code Python dans Cloud Shell

  1. Pour copier le code Python d'un bucket Cloud Storage dans le répertoire d'accueil, exécutez la commande suivante :

    gcloud storage cp gs://cloud-training/devapps-foundations/code/lab2/bookshelf.zip ~ && unzip ~/bookshelf.zip -d ~ && rm ~/bookshelf.zip
  2. Pour vérifier le contenu du répertoire "bookshelf", exécutez la commande suivante :

    cd ~ ls -R bookshelf

    Vous devriez voir une liste contenant trois fichiers Python, un fichier d'exigences et quatre fichiers de modèle :

    bookshelf: booksdb.py main.py requirements.txt storage.py templates bookshelf/templates: base.html form.html list.html view.html

Installer les dépendances requises

  1. Pour lister les dépendances dans le fichier d'exigences, exécutez la commande suivante :

    cat ~/bookshelf/requirements.txt

    Le fichier d'exigences spécifie les dépendances suivantes :

    • Flask : module de framework Web utilisé pour concevoir des applications Web Python
    • Gunicorn : serveur HTTP Python qui s'exécute sous Linux
    • Cloud Logging : produit qui permet de consigner les informations de l'application
    • Firestore : base de données de documents NoSQL sans serveur, entièrement gérée et rapide, conçue pour simplifier le développement d'applications
    • Cloud Storage : solution unifiée de stockage d'objets de Google Cloud
  2. Pour installer les dépendances dans le fichier d'exigences, exécutez la commande suivante :

    pip3 install -r ~/bookshelf/requirements.txt --user

    pip est le programme d'installation de packages pour Python. La commande pip3 installe les packages spécifiés dans le fichier requirements.txt qui doivent être utilisés avec Python 3.

Tester l'application

  1. Pour démarrer l'application, exécutez la commande suivante :

    cd ~/bookshelf; ~/.local/bin/gunicorn -b :8080 main:app

    Si vous avez réussi à créer les fichiers, l'application doit maintenant être hébergée sur le port 8080.

  2. Pour exécuter l'application dans le navigateur Web, cliquez sur Aperçu sur le Web, puis sélectionnez Prévisualiser sur le port 8080.

    Aperçu sur le Web sur le port 8080

    Un nouvel onglet s'ouvre dans le navigateur et l'application s'exécute. Cette page affiche la liste de tous les livres existants. Aucun livre n'est disponible pour l'instant.

    Remarque : Si un message vous demande d'autoriser Cloud Shell, cliquez sur Autoriser.
  3. Effectuez un clic droit sur l'image de couverture du livre Le Magicien d'Oz, puis enregistrez-la sur votre ordinateur sous le nom oz.png :

    Couverture du livre "Le Magicien d'Oz"

  4. Dans l'onglet de l'application, cliquez sur + Ajouter un livre.

  5. Saisissez les informations suivantes dans le formulaire :

    Champ Valeur
    Titre Le Magicien d'Oz
    Auteur Frank L. Baum
    Date de publication 1900
    Description Une jeune fille et son chien sont transportés dans un pays magique, où ils rencontrent des gens étranges et découvrent qu'il vaut mieux ne pas se trouver sous une maison.
  6. Pour Image de couverture, cliquez sur Sélectionner un fichier.

  7. Sélectionnez le fichier que vous avez téléchargé (oz.png), puis cliquez sur Ouvrir.

  8. Cliquez sur Enregistrer.

    Vous revenez à la page de vue, qui contient les détails du livre.

  9. En haut de la page, cliquez sur Livres.

    Vous êtes redirigé vers la page de liste, et Le Magicien d'Oz s'affiche dans la liste, avec sa couverture. Les détails du livre sont stockés dans la base de données Firestore et l'image de couverture est stockée dans Cloud Storage.

    Remarque : Vous pouvez ajouter des livres, mais ne modifiez pas Le Magicien d'Oz. Vous allez l'utiliser pour le reste de l'atelier.
  10. Dans Cloud Shell, pour quitter l'application, appuyez sur Ctrl+C.

Cliquez sur Vérifier ma progression pour valider l'objectif. Tester l'application et créer un livre

Tâche 2 : Créer des identifiants d'autorisation OAuth pour votre application

Dans cette tâche, vous allez créer des identifiants d'autorisation qui permettront à votre application d'être identifiée auprès du serveur OAuth 2.0 de Google.

Créer l'écran de consentement OAuth

Lorsque vous utilisez OAuth 2.0 pour gérer les autorisations, votre application demande des autorisations pour un ou plusieurs niveaux d'accès d'un compte Google. Google affiche un écran de consentement dans lequel l'utilisateur décide d'autoriser ou non le partage de ses données avec l'application.

  1. Dans la console Google Cloud, accédez au menu de navigation (Icône du menu de navigation), puis cliquez sur API et services > Écran de consentement OAuth.

    Cette page vous permet de sélectionner le type d'utilisateurs de votre application. Les utilisateurs internes sont ceux qui appartiennent à votre organisation. Les utilisateurs externes sont tous ceux qui disposent d'un compte Google.

  2. Cliquez sur Commencer.

  3. Pour Nom de l'application, saisissez Bookshelf.

  4. Sous Adresse e-mail d'assistance utilisateur, sélectionnez l'adresse e-mail du participant.

  5. Cliquez sur Suivant.

  6. Sous Cible, sélectionnez Externe, puis cliquez sur Suivant.

    Les utilisateurs disposant d'un compte de test pourront se connecter à l'application.

  7. Dans le panneau de gauche des instructions de l'atelier, copiez le nom d'utilisateur.

    Copier le nom d'utilisateur

  8. Pour le champ Adresses e-mail, collez le nom d'utilisateur copié, puis cliquez sur Suivant.

  9. Cochez la case pour accepter le règlement sur les données utilisateur, puis cliquez sur Continuer.

  10. Cliquez sur Créer.

  11. Dans le menu de navigation, cliquez sur Branding.

  12. Cliquez sur + Ajouter un domaine.

  13. Dans la section Domaines autorisés, saisissez cloudshell.dev dans le champ Domaine autorisé 1.

    Lorsque l'application s'exécute dans Cloud Shell, cloudshell.dev est le nom de domaine.

  14. Cliquez sur Enregistrer.

  15. Dans le menu de navigation, cliquez sur Accès aux données.

    Ensuite, vous devez sélectionner les niveaux d'accès demandés aux utilisateurs pour votre application. Les niveaux d'accès reflètent les types de données utilisateur privées du compte Google de l'utilisateur auxquels l'application souhaite accéder.

    Il existe trois types de niveaux d'accès :

    • Les niveaux d'accès sensibles, qui doivent être validés par Google avant de pouvoir être présentés à l'utilisateur dans un écran de consentement
    • Les niveaux d'accès restreints, qui incluent des informations encore plus sensibles, provenant d'applications comme Gmail et Drive, et qui peuvent nécessiter un examen plus approfondi
    • Les niveaux d'accès non sensibles, qui sont moins sensibles et ne nécessitent pas la validation de Google
  16. Cliquez sur Ajouter ou supprimer des niveaux d'accès.

    La liste des niveaux d'accès s'affiche.

  17. Au début de la liste, cochez la case à côté de openid.

  18. Pour Filtrer, saisissez userinfo.profile, appuyez sur Entrée, puis cochez la case du niveau d'accès .../auth/userinfo.profile.

  19. Pour Filtrer, désactivez le filtre userinfo.profile, saisissez contacts, appuyez sur Entrée, puis cochez la case du niveau d'accès .../auth/contacts.

  20. Cliquez sur Mettre à jour.

    Vous devriez voir deux niveaux d'application non sensibles ("openid" et "userinfo.profile") et un niveau d'accès sensible ("contacts").

    Remarque : Dans cet atelier, nous n'utiliserons pas le niveau d'accès "contacts", mais nous nous en servons ici comme exemple. Vos applications doivent utiliser les niveaux d'accès minimaux requis.
  21. Cliquez sur Enregistrer.

  22. Dans le menu de navigation, cliquez sur Audience.

    Les utilisateurs tests sont nécessaires lorsque les utilisateurs sont des utilisateurs externes et que l'état de publication est défini sur Test.

  23. Cliquez sur + Ajouter des utilisateurs.

  24. Dans le panneau de gauche des instructions de l'atelier, copiez à nouveau le nom d'utilisateur.

  25. Dans le volet Ajouter des utilisateurs, collez le nom d'utilisateur copié dans le champ prévu à cet effet, puis cliquez sur Enregistrer.

Créer les identifiants OAuth 2.0

  1. Dans le menu de navigation, cliquez sur Clients, puis sur + Créer un client.

  2. Dans la liste Type d'application, sélectionnez Application Web.

  3. Dans le champ Nom, saisissez Bookshelf.

  4. Sous URI de redirection autorisés, cliquez sur + Ajouter un URI.

    L'URI spécifié ici sera utilisé lorsque Google redirigera le navigateur vers l'application après que l'utilisateur aura donné son consentement.

  5. Pour obtenir l'URI de redirection, exécutez la commande suivante dans Cloud Shell :

    echo "https://8080-${WEB_HOST}/oauth2callback"
  6. Copiez l'URI créé par la commande echo, puis collez-le dans le champ URI 1.

  7. Cliquez sur Créer.

  8. Cliquez sur Télécharger au format JSON, puis enregistrez le fichier JSON du code secret du client sur votre machine locale.

    Le fichier du code secret du client sera utilisé pour valider votre application auprès de Google.

  9. Cliquez sur Fermer.

  10. Dans Cloud Shell, cliquez sur Plus (Icône Plus) dans la barre d'outils en haut à droite, puis sur Importer.

  11. Cliquez sur Sélect. fichiers, sélectionnez le fichier JSON du code secret du client, puis cliquez sur Ouvrir.

  12. Cliquez sur Importer.

    Le fichier JSON du code secret du client est désormais disponible dans le répertoire d'accueil. Le contenu de ce fichier sera utilisé pendant le processus OAuth.

  13. Dans Cloud Shell, exécutez la commande suivante :

    cat ~/client_secret_*.json

    Le contenu JSON inclut la valeur client_secret, qui doit être traitée comme un mot de passe. Par exemple, vous ne devez jamais stocker ce fichier JSON dans un dépôt de code.

Stocker le fichier JSON du code secret du client dans Secret Manager

Secret Manager est un emplacement sécurisé et recommandé où stocker le fichier JSON du code secret du client.

  1. Pour activer l'API Secret Manager, exécutez la commande suivante :

    gcloud services enable secretmanager.googleapis.com
  2. Pour renommer le fichier du code secret du client, exécutez la commande suivante :

    mv ~/client_secret*.json ~/client_secret.json
  3. Pour créer le secret, exécutez la commande suivante :

    gcloud secrets create bookshelf-client-secrets --data-file=$HOME/client_secret.json

    Un secret nommé bookshelf-client-secrets est désormais accessible depuis votre application.

    Votre application a également besoin d'une autre valeur de secret : la clé secrète Flask, qui sert à signer les informations dans les cookies.

  4. Afin de créer un secret pour la clé secrète Flask, exécutez la commande suivante :

    tr -dc A-Za-z0-9 </dev/urandom | head -c 20 | gcloud secrets create flask-secret-key --data-file=-

    Cette commande crée un mot de passe alphanumérique aléatoire de 20 caractères, puis le stocke dans un secret nommé flask-secret-key.

Cliquez sur Vérifier ma progression pour valider l'objectif. Créer des identifiants d'autorisation OAuth pour votre application

Tâche 3 : Utiliser Secret Manager pour récupérer les secrets dans l'application

Dans cette tâche, vous allez modifier l'application de façon à utiliser Secret Manager.

Modifier le fichier d'exigences pour ajouter Secret Manager

  1. Dans nano, ouvrez le fichier requirements.txt à l'aide de la commande suivante :

    nano ~/bookshelf/requirements.txt
  2. Dans le fichier d'exigences, utilisez la flèche vers le bas pour accéder à la première ligne vide, puis ajoutez la ligne suivante :

    google-cloud-secret-manager==2.24.0

    Le fichier requirements.txt devrait maintenant se présenter comme suit :

    Flask==3.1.1 gunicorn==23.0.0 google-cloud-logging==3.12.1 google-cloud-firestore==2.21.0 google-cloud-storage==2.17.0 google-cloud-secret-manager==2.24.0
  3. Pour enregistrer le fichier et quitter, appuyez sur Ctrl+X, puis sur Y et sur Entrée.

  4. Pour installer les versions mises à jour des dépendances, exécutez la commande suivante :

    pip3 install -r ~/bookshelf/requirements.txt --user

Créer une fonction pour récupérer les secrets

Le fichier secrets.py contient le code permettant de récupérer les secrets à partir de Secret Manager.

  1. Pour créer le fichier secrets.py, exécutez la commande suivante :

    cat > ~/bookshelf/secrets.py <<EOF import os from google.cloud import secretmanager def get_secret(secret_id, version_id='latest'): # create the secret manager client client = secretmanager.SecretManagerServiceClient() # build the resource name of the secret version project_id = os.getenv('GOOGLE_CLOUD_PROJECT') name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}" # access the secret version response = client.access_secret_version(name=name) # return the decoded secret return response.payload.data.decode('UTF-8') EOF

    La fonction get_secret() accepte un ID de secret et un ID de version facultatif. Elle renvoie le secret demandé.

Modifier main.py pour utiliser Secret Manager

Le fichier de code main doit appeler Secret Manager pour récupérer les secrets.

  1. Dans un éditeur de fichiers, ouvrez le fichier ~/bookshelf/main.py.

  2. Une fois storage importé, ajoutez la ligne suivante :

    import secrets

    Cette ligne importe le fichier secrets.py que vous venez de créer.

  3. Dans l'appel de la fonction app.config.update, remplacez SECRET_KEY :

    SECRET_KEY='secret', # don't store SECRET_KEY in code in a production app

    par :

    SECRET_KEY=secrets.get_secret('flask-secret-key'),

    La clé secrète Flask n'est plus stockée dans le code de l'application.

  4. Enregistrez le fichier.

Tâche 4 : Créer des fonctions pour le flux OAuth

Dans cette tâche, vous allez ajouter des fonctions qui gèrent le flux de connexion OAuth.

Lorsqu'un utilisateur se connecte à l'application Web, celle-ci lance la séquence d'autorisation OAuth. OAuth permet à l'utilisateur de s'authentifier et d'autoriser l'accès demandé par l'application. La séquence d'autorisation OAuth se présente comme suit :

Séquence d&#39;autorisation OAuth

La séquence d'autorisation commence lorsque l'application redirige le navigateur vers une URL Google. Google gère l'authentification de l'utilisateur, la sélection de session et le consentement de l'utilisateur. Le résultat est un code d'autorisation, que l'application peut échanger contre un jeton d'accès et un jeton d'actualisation.

L'application stocke le jeton d'actualisation pour une utilisation ultérieure et se sert du jeton d'accès pour accéder aux API Google. L'application Bookshelf appelle une API Google pour récupérer des informations sur l'utilisateur. Lorsque le jeton d'accès expire, l'application utilise le jeton d'actualisation pour obtenir un nouveau jeton d'accès.

Ajouter des dépendances

Le client OAuth Python pour Google nécessite trois autres packages Python.

  1. Dans le fichier ~/bookshelf/requirements.txt, ajoutez les lignes suivantes :

    google-api-python-client==2.178.0 google-auth==2.40.3 google-auth-oauthlib==1.2.2

    Le fichier requirements.txt devrait maintenant se présenter comme suit :

    Flask==3.1.1 gunicorn==23.0.0 google-cloud-logging==3.12.1 google-cloud-firestore==2.21.0 google-cloud-storage==2.17.0 google-cloud-secret-manager==2.24.0 google-api-python-client==2.178.0 google-auth==2.40.3 google-auth-oauthlib==1.2.2
  2. Enregistrez le fichier.

  3. Pour installer les versions mises à jour des dépendances, exécutez la commande suivante :

    pip3 install -r ~/bookshelf/requirements.txt --user

Ajouter des fonctions OAuth pour gérer le flux d'autorisation

Le fichier oauth.py contient le code permettant de récupérer un jeton OAuth auprès de Google.

  1. Pour créer le fichier oauth.py, exécutez la commande suivante :

    cat > ~/bookshelf/oauth.py <<EOF import google.oauth2.credentials import google_auth_oauthlib.flow from uuid import uuid4 from googleapiclient.discovery import build from werkzeug.exceptions import Unauthorized def _credentials_to_dict(credentials): """ Convert credentials mapping (object) into a dictionary. """ return { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes, 'id_token': credentials.id_token, } def authorize(callback_uri, client_config, scopes): """ Builds the URL that will be used for redirection to Google to start the OAuth flow. """ # specify the flow configuration details flow = google_auth_oauthlib.flow.Flow.from_client_config( client_config=client_config, scopes=scopes, ) flow.redirect_uri = callback_uri # create a random state state = str(uuid4()) # get the authorization URL authorization_url, state = flow.authorization_url( # offline access allows access token refresh without reprompting the user # using online here to force log in access_type='online', state=state, prompt='consent', include_granted_scopes='false', ) return authorization_url, state def handle_callback(callback_uri, client_config, scopes, request_url, stored_state, received_state): """ Fetches credentials using the authorization code in the request URL, and retrieves user information for the logged-in user. """ # validate received state if received_state != stored_state: raise Unauthorized(f'Invalid state parameter: received={received_state} stored={stored_state}') # specify the flow configuration details flow = google_auth_oauthlib.flow.Flow.from_client_config( client_config=client_config, scopes=scopes ) flow.redirect_uri = callback_uri # get a token using the details in the request flow.fetch_token(authorization_response=request_url) credentials = flow.credentials oauth2_client = build('oauth2','v2',credentials=credentials, cache_discovery=False) user_info = oauth2_client.userinfo().get().execute() return _credentials_to_dict(credentials), user_info EOF

    La fonction authorize() lance la séquence d'autorisation. Elle configure le flux à l'aide du paramètre client_config transmis, qui sera créé à partir de la chaîne JSON de configuration OAuth stockée en tant que secret. callback_uri indique la cible d'appel de Google avec le code d'autorisation. Cet URI doit correspondre à un URI configuré en tant qu'URI de redirection autorisé pour l'application Bookshelf. L'appel flow.authorization_url() crée l'URL complète pour la redirection vers Google. Un état est créé et transmis. Il sera stocké dans la session pour associer cet appel au rappel ultérieur. L'URL d'autorisation et l'état sont renvoyés à l'appelant.

    La fonction handle_callback() est utilisée lorsque le rappel est reçu de Google. L'état spécifié dans l'URL de rappel doit correspondre à l'état stocké qui a été envoyé dans l'URL d'autorisation. L'appel flow.fetch_token() peut alors être utilisé pour extraire les identifiants, y compris les jetons d'actualisation et d'accès. Les identifiants renvoyés servent ensuite à appeler Google et à recevoir les informations de l'utilisateur connecté. Après cela, les identifiants et les informations de l'utilisateur sont renvoyés à l'appelant.

    Remarque : La ligne oauth2_client.userinfo() peut afficher un message d'erreur dans votre IDE indiquant qu'il n'y a aucun membre "userinfo". build() renvoie un objet "Resource", et les membres valides ne sont pas connus au moment de la compilation. Vous pouvez ignorer cette erreur.

Tâche 5 : Ajouter des points de terminaison de connexion, de rappel et de déconnexion

Dans cette tâche, vous allez utiliser les fonctions OAuth que vous venez de créer pour implémenter des points de terminaison de connexion, de déconnexion et de rappel.

Modifier les modèles HTML

  1. Pour créer un modèle d'erreur, exécutez la commande suivante :

    cat > ~/bookshelf/templates/error.html <<EOF {% extends "base.html" %} {% block content %} <h3>Error: {{error_message}}</h3> {% endblock %} EOF

    Lors de la connexion, l'utilisateur peut rencontrer une erreur. Cette page sera utilisée pour afficher l'erreur.

  2. Dans un éditeur de fichiers, ouvrez le fichier ~/bookshelf/templates/base.html.

    Des liens de connexion et de déconnexion seront ajoutés à l'application.

  3. Dans la section navbar, sur la ligne après la balise fermante (/ul) de la liste à puces (ul) avec class="nav navbar-nav", ajoutez la section suivante :

    <ul class="nav navbar-nav navbar-right"> {% if session['credentials'] %} <div class="navbar-brand">{{session['user'].email}}</div> <div class="navbar-brand"><a href="/logout">Logout</a></div> {% else %} <div class="navbar-brand"><a href="/login">Login</a></div> {% endif %} </ul>

    Le fichier se présente désormais comme suit :

    <!DOCTYPE html> <html lang="en"> <head> <title>Bookshelf</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> </head> <body> <div class="navbar navbar-default"> <div class="container"> <div class="navbar-header"> <div class="navbar-brand">Bookshelf</div> </div> <ul class="navbar-nav"> <li><a href="/">Books</a></li> </ul> <ul class="nav navbar-nav navbar-right"> {% if session['credentials'] %} <div class="navbar-brand">{{session['user'].email}}</div> <div class="navbar-brand"><a href="/logout">Logout</a></div> {% else %} <div class="navbar-brand"><a href="/login">Login</a></div> {% endif %} </ul> </div> </div> <div class="container"> {% block content %}{% endblock %} </div> </body> </html>

    Le modèle de base utilise à présent la session pour vérifier si l'utilisateur est connecté. Si c'est le cas, son adresse e-mail et un lien de déconnexion s'affichent. Si l'utilisateur n'est pas connecté, un lien de connexion apparaît.

  4. Enregistrez le fichier.

Modifier les importations

  1. Dans un éditeur de fichiers, ouvrez le fichier ~/bookshelf/main.py.

  2. Ajoutez session aux importations Flask.

    Les importations Flask doivent désormais se présenter comme suit :

    from flask import current_app, Flask, redirect, render_template from flask import request, url_for, session

    Une session permet d'accéder aux informations associées à l'utilisateur connecté. Les données de session seront stockées dans des cookies.

  3. Après la ligne cloud_logging import, ajoutez les lignes suivantes :

    import json import os from urllib.parse import urlparse

    Dans main.py, la bibliothèque json est utilisée pour convertir la chaîne de code secret du client en mappage (objet) et la bibliothèque os permet d'utiliser les variables d'environnement. La fonction urlparse() sera utilisée pour remplacer le schéma et le nom d'hôte dans une URL.

  4. Une fois secrets importé, ajoutez la ligne suivante :

    import oauth

    Vous importez ainsi les fonctions OAuth que vous avez créées.

Ajouter des éléments de configuration

  1. Dans l'appel de la fonction app.config.update(), ajoutez les lignes suivantes après la ligne ALLOWED_EXTENSIONS :

    CLIENT_SECRETS=json.loads(secrets.get_secret('bookshelf-client-secrets')), SCOPES=[ 'openid', 'https://www.googleapis.com/auth/contacts.readonly', 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile', ], EXTERNAL_HOST_URL=os.getenv('EXTERNAL_HOST_URL'),

    Les éléments de configuration suivants sont ajoutés :

    • CLIENT_SECRETS contient un mappage (objet) pour la configuration OAuth stockée dans Secret Manager.
    • SCOPES contient la liste des niveaux d'accès à demander.
    • EXTERNAL_HOST_URL sert à déterminer l'URL de rappel. Lorsque vous utilisez l'aperçu sur le Web avec Cloud Shell, l'application définie pour s'exécuter en tant que localhost (127.0.0.1) sur le port 80 est exposée à Internet sur https://8080-...-cloudshell.dev. Cette URL permettra de convertir l'URL localhost du point de terminaison de rappel en URL accessible publiquement. La valeur sera transmise en tant que variable d'environnement.

Ajouter des points de terminaison et des fonctions connexes

  1. Après la fonction log_request() (qui commence par def log_request():), ajoutez les fonctions suivantes :

    def logout_session(): """ Clears known session items. """ session.pop('credentials', None) session.pop('user', None) session.pop('state', None) session.pop('error_message', None) session.pop('login_return', None) return def external_url(url): """ Cloud Shell routes https://8080-***/ to localhost over http This function replaces the localhost host with the configured scheme + hostname """ external_host_url = current_app.config['EXTERNAL_HOST_URL'] if external_host_url is None: # force https if url.startswith('http://'): url = f"https://{url[7:]}" return url # replace the scheme and hostname with the external host URL parsed_url = urlparse(url) replace_string = f"{parsed_url.scheme}://{parsed_url.netloc}" new_url = f"{external_host_url}{url[len(replace_string):]}" return new_url @app.route('/error') def error(): """ Display an error. """ log_request(request) if "error_message" not in session: return redirect(url_for('.list')) # render error return render_template('error.html', error_message=session.pop('error_message', None)) @app.route("/login") def login(): """ Login if not already logged in. """ log_request(request) if not "credentials" in session: # need to log in current_app.logger.info('logging in') # get authorization URL authorization_url, state = oauth.authorize( callback_uri=external_url(url_for('oauth2callback', _external=True)), client_config=current_app.config['CLIENT_SECRETS'], scopes=current_app.config['SCOPES']) current_app.logger.info(f"authorization_url={authorization_url}") # save state for verification on callback session['state'] = state return redirect(authorization_url) # already logged in return redirect(session.pop('login_return', url_for('.list'))) @app.route("/oauth2callback") def oauth2callback(): """ Callback destination during OAuth process. """ log_request(request) # check for error, probably access denied by user error = request.args.get('error', None) if error: session['error_message'] = f"{error}" return redirect(url_for('.error')) # handle the OAuth2 callback credentials, user_info = oauth.handle_callback( callback_uri=external_url(url_for('oauth2callback', _external=True)), client_config=current_app.config['CLIENT_SECRETS'], scopes=current_app.config['SCOPES'], request_url=external_url(request.url), stored_state=session.pop('state', None), received_state=request.args.get('state', '')) session['credentials'] = credentials session['user'] = user_info current_app.logger.info(f"user_info={user_info}") return redirect(session.pop('login_return', url_for('.list'))) @app.route("/logout") def logout(): """ Log out and return to root page. """ log_request(request) logout_session() return redirect(url_for('.list'))

    La fonction logout_session() efface les entrées de session connues.

    La fonction external_url() remplace le schéma et le nom d'hôte d'une URL par un autre nom d'hôte pour l'accès externe. Si l'hôte de remplacement n'est pas spécifié, la fonction s'assure que l'URL renvoyée utilise "https".

    Le point de terminaison /error sert à afficher une erreur.

    Le point de terminaison /login vérifie la session pour déterminer si un utilisateur est connecté. Un utilisateur est connecté si des identifiants sont stockés dans la session. Si l'utilisateur n'est pas connecté, la fonction oauth.authorize() est appelée pour obtenir l'URL d'autorisation et l'état de la redirection vers Google. L'état est enregistré dans la session, puis le navigateur est redirigé vers l'URL d'autorisation.

    Le point de terminaison /oauth2callback est appelé par Google pendant le processus d'autorisation. En cas d'erreur, le processus échoue et l'utilisateur est redirigé vers la page d'erreur. Si aucune erreur n'est détectée, la fonction handle_callback() est appelée pour récupérer le jeton et les informations de l'utilisateur. À la fin du processus, l'utilisateur est redirigé vers la page précédente où la connexion a été lancée automatiquement ou vers la page racine (liste des livres) s'il n'y a pas d'emplacement de retour.

    Le point de terminaison /logout déconnecte l'utilisateur en supprimant les identifiants et les données utilisateur de la session, puis revient à la page racine.

Forcer la connexion pour ajouter, modifier ou supprimer des livres

Un utilisateur peut parcourir les livres de l'application Bookshelf sans se connecter. Toutefois, il est logique d'obliger l'utilisateur à se connecter avant de pouvoir modifier les livres.

Lorsqu'un utilisateur tente d'ajouter, de modifier ou de supprimer un livre sans être connecté, il doit y être invité.

  1. Dans la fonction add(), ajoutez les lignes suivantes juste après l'appel à log_request() :

    # must be logged in if "credentials" not in session: session['login_return'] = url_for('.add') return redirect(url_for('.login'))

    Dans add(), si l'utilisateur n'est pas connecté, il est redirigé vers la page d'ajout après s'être connecté.

  2. Dans la fonction edit(), ajoutez les lignes suivantes juste après l'appel à log_request() :

    # must be logged in if "credentials" not in session: session['login_return'] = url_for('.edit', book_id=book_id) return redirect(url_for('.login'))

    Dans edit(), si l'utilisateur n'est pas connecté, il est redirigé vers la page de modification du livre après s'être connecté.

  3. Dans la fonction delete(), ajoutez les lignes suivantes juste après l'appel à log_request() :

    # must be logged in if "credentials" not in session: session['login_return'] = url_for('.view', book_id=book_id) return redirect(url_for('.login'))

    Dans delete(), si l'utilisateur n'est pas connecté, il est redirigé vers la page de vue du livre après s'être connecté.

  4. Enregistrez le fichier.

Tester l'application

  1. Pour démarrer le serveur HTTP, exécutez la commande suivante dans Cloud Shell :

    cd ~/bookshelf; EXTERNAL_HOST_URL="https://8080-$WEB_HOST" ~/.local/bin/gunicorn -b :8080 main:app

    Une variable d'environnement est transmise à l'application :

    • EXTERNAL_HOST_URL spécifie le schéma et le nom d'hôte à utiliser dans l'URL de rappel. Si cette variable d'environnement n'est pas spécifiée, le paramètre redirect_uri transmis à Google dans l'URL d'autorisation utilisera le nom d'hôte que l'application voit dans les URL entrantes : 127.0.0.1:8080 (c'est-à-dire localhost). L'aperçu sur le Web transfère les requêtes de l'URL cloudshell.dev vers localhost (http://127.0.0.1:8080).
    Remarque : Si un message vous demande d'autoriser Cloud Shell, cliquez sur Autoriser.
  2. Pour ouvrir l'application dans le navigateur Web, cliquez sur Aperçu sur le Web, puis sélectionnez Prévisualiser sur le port 8080.

    Aperçu sur le Web sur le port 8080

    Un nouvel onglet s'ouvre dans le navigateur et l'application s'exécute. Le livre Le Magicien d'Oz doit s'afficher. L'utilisateur n'est pas connecté.

  3. Cliquez sur + Ajouter un livre.

    Comme vous devez être connecté pour ajouter un livre, vous devez choisir un compte pour vous connecter avec Google :

    Sélectionner un compte

  4. Cliquez sur l'adresse e-mail du participant, puis sur Continuer.

    Google obtiendra désormais un consentement pour tout niveau d'accès restreint ou non sensible demandé. Dans ce cas, télécharger tous vos contacts est niveau d'accès sensible.

    Obtenir le consentement

  5. Cliquez sur Autoriser.

    Vous êtes redirigé vers l'application, sur la page Ajouter un livre. Vous êtes connecté, et votre adresse e-mail s'affiche en haut à droite. Si vous examinez les journaux dans Cloud Shell, vous devriez voir l'appel de rappel de Google :

    INFO:main:REQ: GET http://127.0.0.1:8080/oauth2callback?state=88789b07-2474-423f-b572-f5d4a3240ace&code=4g0AfJohXm0vtB2eYHnRaAeM8m-VCmnssg5YgrjoJstTLmHaVq8nlbJo5uzIS67NbWTXTOqDw&scope=email%20profile%20openid%20https://www.googleapis.com/auth/contacts.readonly%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile&authuser=0&hd=qwiklabs.net&prompt=consent

    L'utilisateur a autorisé l'accès. Le paramètre code contient donc le code d'autorisation qui a ensuite été échangé contre les identifiants. Les niveaux d'accès autorisés sont également renvoyés.

  6. Cliquez sur Livres, puis sur + Ajouter un livre.

    Puisque vous êtes déjà connecté, vous pouvez accéder directement à la page Ajouter un livre.

  7. Cliquez sur Déconnexion, puis sur Connexion.

  8. Cliquez sur l'adresse e-mail du participant, puis sur Continuer et Annuler.

    Vous êtes redirigé vers la page d'erreur. Examinez les journaux dans Cloud Shell. Vous devriez voir le rappel effectué par Google, qui doit ressembler à ceci :

    INFO:main:REQ: GET http://127.0.0.1:8080/oauth2callback?error=access_denied&state=72342071-c8dc-43be-8184-9f6bd6069cd5

    Dans ce cas, le consentement n'a pas été donné. Le code d'autorisation n'a donc pas été renvoyé et l'application ne peut pas obtenir les identifiants de l'utilisateur.

  9. Dans Cloud Shell, pour quitter l'application, appuyez sur Ctrl+C.

Cliquez sur Vérifier ma progression pour valider l'objectif. Ajouter des points de terminaison de connexion, de rappel et de déconnexion

Tâche 6 : Créer des fonctions de traduction

Dans cette tâche, vous allez créer des fonctions qui utilisent l'API Cloud Translation pour détecter la langue du texte et le traduire.

Les appels de l'API Cloud Translation utilisent les identifiants de l'application.

Ajouter une dépendance Cloud Translation

L'application nécessite un autre package Python.

  1. Dans le fichier ~/bookshelf/requirements.txt, ajoutez la ligne suivante :

    google-cloud-translate==3.21.1

    Le fichier requirements.txt devrait maintenant se présenter comme suit :

    Flask==3.1.1 gunicorn==23.0.0 google-cloud-logging==3.12.1 google-cloud-firestore==2.21.0 google-cloud-storage==2.17.0 google-cloud-secret-manager==2.24.0 google-api-python-client==2.178.0 google-auth==2.40.3 google-auth-oauthlib==1.2.2 google-cloud-translate==3.21.1
  2. Enregistrez le fichier.

  3. Pour installer les dépendances mises à jour, exécutez la commande suivante :

    pip3 install -r ~/bookshelf/requirements.txt --user

Ajouter des fonctions de traduction

Le fichier translate.py contient le code permettant d'effectuer la traduction.

  1. Pour créer le fichier translate.py, exécutez la commande suivante :

    cat > ~/bookshelf/translate.py <<EOF import os from google.cloud import translate PROJECT_ID = os.getenv('GOOGLE_CLOUD_PROJECT') PARENT = f"projects/{PROJECT_ID}" supported_languages = None def get_languages(): """ Gets the list of supported languages. """ # use the global variable global supported_languages # retrieve supported languages if not previously retrieved if not supported_languages: client = translate.TranslationServiceClient() response = client.get_supported_languages( parent=PARENT, display_language_code='en', ) supported_languages = response.languages return supported_languages def detect_language(text): """ Detect the language of the supplied text. Returns the most likely language. """ client = translate.TranslationServiceClient() response = client.detect_language( parent=PARENT, content=text, ) return response.languages[0] def translate_text(text, target_language_code): """ Translate the text to the target language. """ client = translate.TranslationServiceClient() response = client.translate_text( parent=PARENT, contents=[text], target_language_code=target_language_code, ) return response.translations[0] EOF

    La fonction get_languages() récupère la liste des langues acceptées par l'API Cloud Translation. Chaque langue de la liste présente un ID (language_code) et le texte à afficher (display_name).

    La fonction detect_language() détecte la langue d'une chaîne de texte.

    La fonction translate_language() traduit le texte dans une langue donnée.

Tâche 7 : Créer un profil utilisateur pour la sélection de la langue et traduire les descriptions

Dans cette tâche, vous allez créer un profil utilisateur pour les utilisateurs connectés. L'utilisateur peut sélectionner sa langue préférée.

Le profil sera stocké dans une collection Firestore nommée profiles. Un profil par défaut avec l'anglais comme langue préférée sera utilisé jusqu'à ce que l'utilisateur mette à jour le profil.

Ajouter des fonctions pour lire et mettre à jour les profils

Le fichier profiledb.py contient le code permettant de lire et de mettre à jour les profils utilisateur. L'adresse e-mail de l'utilisateur servira de clé de profil. Dans cette implémentation, le seul élément du profil sera la langue préférée.

  1. Pour créer le fichier profiledb.py, exécutez la commande suivante :

    cat > ~/bookshelf/profiledb.py <<EOF from google.cloud import firestore default_profile = { "preferredLanguage": "en" } def __document_to_dict(doc): if not doc.exists: return None doc_dict = doc.to_dict() doc_dict['id'] = doc.id return doc_dict def read(email): """ Return a profile by email. """ db = firestore.Client() # retrieve a profile from the database by ID profile_ref = db.collection("profiles").document(email) profile_dict = __document_to_dict(profile_ref.get()) # return empty dictionary if no profile if profile_dict is None: profile_dict = default_profile.copy() return profile_dict def read_entry(email, key, default_value=''): """ Return a profile entry by email and key. """ profile_dict = read(email) return profile_dict.get(key, default_value) def update(data, email): """ Update a profile, and return the updated profile's details. """ db = firestore.Client() # update profile in database profile_ref = db.collection("profiles").document(email) profile_ref.set(data) return __document_to_dict(profile_ref.get()) EOF

    La fonction read() récupère le profil d'un utilisateur spécifié. Si aucun profil n'est trouvé, une copie du profil par défaut est renvoyée.

    La fonction read_entry() renvoie une seule valeur à partir du profil d'un utilisateur. Si la clé est introuvable dans le profil de l'utilisateur, la valeur par défaut transmise est renvoyée à la place.

    La fonction update() crée ou écrase le profil de l'utilisateur avec les données spécifiées.

Ajouter le point de terminaison "profile" pour afficher et modifier un profil utilisateur

  1. Afin de créer un modèle pour le profil utilisateur dans profile.html, exécutez la commande suivante :

    cat > ~/bookshelf/templates/profile.html <<EOF {# [START form] #} {% extends "base.html" %} {% block content %} <h3>Profile for {{session['user']['email']}}</h3> <form method="POST" enctype="multipart/form-data"> <div class="form-group"> <label for="preferredLanguage">Preferred Language</label> <select id="preferredLanguage" name="preferredLanguage"> {% for l in languages %} {% if l.language_code == profile['preferredLanguage'] %} <option value="{{l.language_code}}" selected>{{l.display_name}}</option> {% else %} <option value="{{l.language_code}}">{{l.display_name}}</option> {% endif %} {% endfor %} </select> </div> <button type="submit" class="btn btn-success">Save</button> </form> {% endblock %} {# [END form] #} EOF

    Ce modèle crée un formulaire unique avec une commande de sélection et un bouton d'envoi. La commande de sélection est chargée avec toutes les langues transmises à l'aide de la variable de liste languages. La valeur de chaque entrée est language_code, et le nom display_name est indiqué dans la commande de sélection. La langue affichée au départ est la langue preferredLanguage spécifiée dans le profil.

  2. Dans un éditeur de fichiers, ouvrez le fichier ~/bookshelf/main.py.

  3. Une fois oauth importé, ajoutez les lignes suivantes :

    import translate import profiledb

    Vous importez ainsi les fichiers translate.py et profiledb.py que vous venez de créer.

  4. Pour ajouter le point de terminaison /profile, ajoutez la fonction suivante après le point de terminaison /books/<book_id>/delete :

    @app.route('/profile', methods=['GET', 'POST']) def profile(): """ If GET, show the form to collect updated details for the user profile. If POST, update the profile based on the specified form. """ log_request(request) # must be logged in if "credentials" not in session: session['login_return'] = url_for('.profile') return redirect(url_for('.login')) # read existing profile email = session['user']['email'] profile = profiledb.read(email) # Save details if form was posted if request.method == 'POST': # get book details from form data = request.form.to_dict(flat=True) # update profile profiledb.update(data, email) session['preferred_language'] = data['preferredLanguage'] # return to root return redirect(url_for('.list')) # render form to update book return render_template('profile.html', action='Edit', profile=profile, languages=translate.get_languages())

    Le profil n'est accessible qu'aux utilisateurs connectés. Si l'utilisateur n'est pas connecté, il est redirigé vers la page de connexion.

    L'adresse e-mail de l'utilisateur connecté est extraite des informations de l'utilisateur dans la session, puis le profil actuel est lu.

    Le profil est affiché à l'aide du modèle profile.html.

    Une fois que vous avez cliqué sur le bouton d'envoi, le profil est mis à jour dans la base de données, la langue préférée de l'utilisateur est stockée dans la session et le navigateur est redirigé vers la page racine.

  5. Enregistrez le fichier.

Accéder au profil en cliquant sur l'adresse e-mail de l'utilisateur

  1. Dans un éditeur de fichiers, ouvrez le fichier ~/bookshelf/templates/base.html.

  2. Dans ce fichier, remplacez la ligne suivante :

    <div class="navbar-brand">{{session['user'].email}}</div>

    par :

    <div class="navbar-brand"><a href="/profile">{{session['user'].email}}</a></div>

    L'adresse e-mail affichée est alors remplacée par un lien cliquable qui redirige vers le point de terminaison /profile.

  3. Enregistrez le fichier.

Traduire la description sur la page de vue

  1. Dans un éditeur de fichiers, ouvrez le fichier ~/bookshelf/templates/view.html.

  2. Dans ce fichier, remplacez la ligne suivante :

    <p class="book-description">{{book.description}}</p>

    par :

    {% if translation_language is not none %} <p class="book-description"><strong>Description ({{description_language}}): </strong>{{book.description}}</p> <p class="book-description"><strong>Translation ({{translation_language}}): </strong>{{translated_text}}</p> {% else %} <p class="book-description"><strong>Description: </strong>{{book.description}}</p> {% endif %}

    Si la valeur translation_language n'est pas spécifiée, la description ne change pas. Toutefois, si une langue de traduction est indiquée, la langue de la description d'origine est affichée, et la version traduite du texte est visible sur la ligne suivante. Le point de terminaison de vue doit transmettre ces informations supplémentaires.

  3. Enregistrez le fichier.

  4. Dans un éditeur de fichiers, ouvrez le fichier ~/bookshelf/main.py.

  5. Après la fonction log_request() (qui commence par def log_request():), ajoutez le code suivant :

    # build a mapping of language codes to display names display_languages = {} for l in translate.get_languages(): display_languages[l.language_code] = l.display_name

    La fonction detect_language() renvoie le code de langue détecté, mais pas le nom à afficher. Ce code crée un mappage entre le code de langue et le nom à afficher. Il sera utilisé pour afficher la langue détectée dans le modèle de vue.

  6. Remplacez le code du point de terminaison de vue complet par le code suivant :

    @app.route('/books/<book_id>') def view(book_id): """ View the details of a specified book. """ log_request(request) # retrieve a specific book book = booksdb.read(book_id) current_app.logger.info(f"book={book}") # defaults if logged out description_language = None translation_language = None translated_text = '' if book['description'] and "credentials" in session: preferred_language = session.get('preferred_language', 'en') # translate description translation = translate.translate_text( text=book['description'], target_language_code=preferred_language, ) description_language = display_languages[translation.detected_language_code] translation_language = display_languages[preferred_language] translated_text = translation.translated_text # render book details return render_template('view.html', book=book, translated_text=translated_text, description_language=description_language, translation_language=translation_language, )

    Le code traduit désormais la description du livre dans la langue préférée de l'utilisateur, puis transmet la traduction et les langues au modèle.

  7. Enregistrez le fichier.

Tâche 8 : Tester l'application

  1. Pour démarrer le serveur HTTP, exécutez la commande suivante :

    cd ~/bookshelf; EXTERNAL_HOST_URL="https://8080-$WEB_HOST" ~/.local/bin/gunicorn -b :8080 main:app
  2. Pour ouvrir l'application dans le navigateur Web, cliquez sur Aperçu sur le Web, puis sélectionnez Prévisualiser sur le port 8080.

    Aperçu sur le Web sur le port 8080

    Un nouvel onglet s'ouvre dans le navigateur et l'application s'exécute. Le livre Le Magicien d'Oz doit s'afficher.

    Remarque : Si un message vous demande d'autoriser Cloud Shell, cliquez sur Autoriser.
  3. Si l'utilisateur n'est pas connecté, cliquez sur Connexion, puis connectez-le en lui demandant son autorisation.

    L'adresse e-mail doit désormais être un lien.

  4. Cliquez sur l'adresse e-mail.

    Le profil est affiché. La commande de sélection de la langue doit afficher English.

  5. Définissez la langue préférée sur Swahili, puis cliquez sur Enregistrer.

  6. Cliquez sur le livre Le Magicien d'Oz.

    La page de vue contient désormais à la fois la description d'origine en anglais et la traduction en swahili.

Cliquez sur Vérifier ma progression pour valider l'objectif. Tester l'application

Félicitations !

Vous avez modifié une application de façon à utiliser OAuth pour la connexion des utilisateurs. Vous avez ensuite ajouté un profil utilisateur avec une langue préférée, et vous vous êtes servi de l'API Cloud Translation pour fournir des traductions de descriptions de livres.

Étapes suivantes et informations supplémentaires

Terminer l'atelier

Une fois l'atelier terminé, cliquez sur Terminer l'atelier. Google Cloud Skills Boost supprime les ressources que vous avez utilisées, puis efface le compte.

Si vous le souhaitez, vous pouvez noter l'atelier. Sélectionnez un nombre d'étoiles, saisissez un commentaire, puis cliquez sur Envoyer.

Le nombre d'étoiles correspond à votre degré de satisfaction :

  • 1 étoile = très insatisfait(e)
  • 2 étoiles = insatisfait(e)
  • 3 étoiles = ni insatisfait(e), ni satisfait(e)
  • 4 étoiles = satisfait(e)
  • 5 étoiles = très satisfait(e)

Si vous ne souhaitez pas donner votre avis, vous pouvez fermer la boîte de dialogue.

Pour soumettre des commentaires, suggestions ou corrections, veuillez accéder à l'onglet Assistance.

Copyright 2024 Google LLC Tous droits réservés. Google et le logo Google sont des marques de Google LLC. Tous les autres noms de société et de produit peuvent être des marques des sociétés auxquelles ils sont associés.

Avant de commencer

  1. Les ateliers créent un projet Google Cloud et des ressources pour une durée déterminée.
  2. Les ateliers doivent être effectués dans le délai imparti et ne peuvent pas être mis en pause. Si vous quittez l'atelier, vous devrez le recommencer depuis le début.
  3. En haut à gauche de l'écran, cliquez sur Démarrer l'atelier pour commencer.

Utilisez la navigation privée

  1. Copiez le nom d'utilisateur et le mot de passe fournis pour l'atelier
  2. Cliquez sur Ouvrir la console en navigation privée

Connectez-vous à la console

  1. Connectez-vous à l'aide des identifiants qui vous ont été attribués pour l'atelier. L'utilisation d'autres identifiants peut entraîner des erreurs ou des frais.
  2. Acceptez les conditions d'utilisation et ignorez la page concernant les ressources de récupération des données.
  3. Ne cliquez pas sur Terminer l'atelier, à moins que vous n'ayez terminé l'atelier ou que vous ne vouliez le recommencer, car cela effacera votre travail et supprimera le projet.

Ce contenu n'est pas disponible pour le moment

Nous vous préviendrons par e-mail lorsqu'il sera disponible

Parfait !

Nous vous contacterons par e-mail s'il devient disponible

Un atelier à la fois

Confirmez pour mettre fin à tous les ateliers existants et démarrer celui-ci

Utilisez la navigation privée pour effectuer l'atelier

Ouvrez une fenêtre de navigateur en mode navigation privée pour effectuer cet atelier. Vous éviterez ainsi les conflits entre votre compte personnel et le compte temporaire de participant, qui pourraient entraîner des frais supplémentaires facturés sur votre compte personnel.