arrow_back

Desarrollo de aplicaciones en Google Cloud: agrega la autenticación de usuarios y la inteligencia a tu aplicación

Acceder Unirse
Obtén acceso a más de 700 labs y cursos

Desarrollo de aplicaciones en Google Cloud: agrega la autenticación de usuarios y la inteligencia a tu aplicación

Lab 1 hora 30 minutos universal_currency_alt 5 créditos show_chart Intermedio
info Es posible que este lab incorpore herramientas de IA para facilitar tu aprendizaje.
Obtén acceso a más de 700 labs y cursos

Descripción general

Las bibliotecas cliente de Cloud son el método recomendado para llamar a las APIs de Google Cloud desde tus aplicaciones. Las bibliotecas cliente de Cloud usan las convenciones y el estilo naturales del lenguaje de programación que utilizas en tu aplicación. Las bibliotecas cliente de Cloud controlan la comunicación de bajo nivel con el servidor, incluida la autenticación y la lógica de reintentos.

Firestore es una base de datos NoSQL de documentos rápida, completamente administrada y sin servidores diseñada para el escalado automático, el alto rendimiento y la facilidad de desarrollo de aplicaciones.

Las APIs de Google usan el protocolo OAuth 2.0 para la autenticación y la autorización.

Secret Manager te permite almacenar claves de API, contraseñas, certificados y otros datos sensibles como BLOB binarios o cadenas de texto.

La API de Cloud Translation permite que tus sitios web y aplicaciones traduzcan texto de manera dinámica y programática. Cloud Translation puede traducir texto en más de 100 idiomas y reconocer el idioma del texto fuente.

En este lab, actualizarás una aplicación de Python que administra una lista de libros. Agregarás la capacidad de acceder a la aplicación con OAuth y exigir que el usuario acceda cuando agregue, edite o borre libros.

También usarás la API de Cloud Translation para traducir las descripciones de los libros a otro idioma. Agregarás un perfil de usuario en el que se almacene el idioma preferido del usuario.

Qué aprenderás

En este lab, aprenderás a realizar las siguientes tareas:

  • Crear una aplicación web simple con Flask de Python
  • Usar Secret Manager para almacenar datos sensibles de la aplicación
  • Usar OAuth 2.0 para agregar el acceso de usuario a una aplicación
  • Usar la API de Cloud Translation para detectar el idioma de un texto y traducirlo

Configuración y requisitos

Antes de hacer clic en el botón Comenzar lab

Nota: Lee estas instrucciones.

Los labs son cronometrados y no se pueden pausar. El cronómetro, que comienza a funcionar cuando haces clic en Comenzar lab, indica por cuánto tiempo tendrás a tu disposición los recursos de Google Cloud.

En este lab práctico de Qwiklabs, se te proporcionarán credenciales temporales nuevas para acceder a Google Cloud y realizar las actividades en un entorno de nube real, no en uno de simulación o demostración.

Requisitos

Para completar este lab, necesitarás lo siguiente:

  • Acceso a un navegador de Internet estándar (se recomienda el navegador Chrome)
  • Tiempo para completar el lab
Nota: Si ya tienes un proyecto o una cuenta personal de Google Cloud, no los uses para el lab. Nota: Si usas una Pixelbook, abre una ventana de incógnito para ejecutar el lab.

Cómo iniciar tu lab y acceder a la consola

  1. Haz clic en el botón Comenzar lab. Si debes pagar por el lab, se abrirá una ventana emergente para que selecciones tu forma de pago. A la izquierda, verás un panel con las credenciales temporales que debes usar para este lab.

    Panel de credenciales

  2. Copia el nombre de usuario y, luego, haz clic en Abrir la consola de Google. El lab inicia los recursos y abre otra pestaña que muestra la página Elige una cuenta.

    Sugerencia: Abre las pestañas en ventanas separadas, una junto a la otra.
  3. En la página Elige una cuenta, haz clic en Usar otra cuenta. Se abrirá la página de acceso.

    Cuadro de diálogo Elige una cuenta el que se destaca la opción Usar otra cuenta

  4. Pega el nombre de usuario que copiaste del panel Detalles de la conexión. Luego, copia y pega la contraseña.

Nota: Debes usar las credenciales del panel Detalles de la conexión. No uses tus credenciales de Google Cloud Skills Boost. Si tienes una cuenta propia de Google Cloud, no la utilices para este lab para no incurrir en cargos.
  1. Haz clic para avanzar por las páginas siguientes:
  • Acepta los Términos y Condiciones.
  • No agregues opciones de recuperación o autenticación de dos factores (esta es una cuenta temporal).
  • No te registres para obtener pruebas gratuitas.

Después de un momento, se abrirá la consola de Cloud en esta pestaña.

Nota: Para ver el menú con una lista de los productos y servicios de Google Cloud, haz clic en el menú de navegación que se encuentra en la parte superior izquierda de la pantalla. Menú de la consola de Cloud

Activa Google Cloud Shell

Google Cloud Shell es una máquina virtual que cuenta con herramientas para desarrolladores. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud.

Google Cloud Shell proporciona acceso de línea de comandos a tus recursos de Google Cloud.

  1. En la consola de Cloud, en la barra de herramientas superior derecha, haz clic en el botón Abrir Cloud Shell.

    Ícono de Cloud Shell destacado

  2. Haz clic en Continuar.

El aprovisionamiento y la conexión al entorno demorarán unos minutos. Cuando te conectes, habrás completado la autenticación, y el proyecto estará configurado con tu PROJECT_ID. Por ejemplo:

ID del proyecto destacado en la terminal de Cloud Shell

gcloud es la herramienta de línea de comandos de Google Cloud. Viene preinstalada en Cloud Shell y es compatible con el completado de línea de comando.

  • Puedes solicitar el nombre de la cuenta activa con este comando:
gcloud auth list

Resultado:

Credentialed accounts: - @.com (active)

Resultado de ejemplo:

Credentialed accounts: - google1623327_student@qwiklabs.net
  • Puedes solicitar el ID del proyecto con este comando:
gcloud config list project

Resultado:

[core] project =

Resultado de ejemplo:

[core] project = qwiklabs-gcp-44776a13dea667a6 Nota: La documentación completa de gcloud está disponible en la guía de descripción general de gcloud CLI .

Tarea 1: Configura la aplicación de Python y los recursos necesarios

En esta tarea, descargarás la aplicación de Python y crearás los recursos que usa la versión actual de la app.

Nota: En la mayoría de los lenguajes, se usa sangría para que el código sea más legible. Python usa la sangría para indicar un bloque de código, por lo que debe ser correcta. La cantidad de espacios que se usan para la sangría debe ser coherente. Mezclar espacios y tabulaciones para la sangría también puede causar problemas. En este lab, se usan cuatro espacios para la sangría de Python.

Crea la base de datos de Firestore

  1. Para crear la base de datos de Firestore, ejecuta el siguiente comando en Cloud Shell:

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

    La base de datos de Firestore se usa para almacenar datos de libros y perfiles de usuarios.

  2. Si se te solicita que autorices Cloud Shell, haz clic en Autorizar.

Crea el bucket de Cloud Storage con los permisos correctos

  1. Para crear el bucket de Cloud Storage, ejecuta el siguiente comando:

    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

    El bucket de Cloud Storage se usa para almacenar imágenes de portadas de libros, tiene acceso uniforme a nivel de bucket y no usa la prevención del acceso público.

    Nota: Si el comando falla y el error indica que la cuenta no tiene credenciales válidas, vuelve a intentarlo. Es posible que los permisos de la cuenta de estudiante de Qwiklabs aún no se hayan propagado.
  2. Para que todos los objetos del bucket se puedan leer de forma pública, ejecuta el siguiente comando:

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

Para verificar este objetivo, haz clic en Revisar mi progreso. Configurar la aplicación de Python y los recursos necesarios

Copia el código de Python en Cloud Shell

  1. Para copiar el código de Python de un bucket de Cloud Storage en el directorio principal, ejecuta el siguiente comando:

    gcloud storage cp gs://cloud-training/devapps-foundations/code/lab2/bookshelf.zip ~ && unzip ~/bookshelf.zip -d ~ && rm ~/bookshelf.zip
  2. Para verificar el contenido del directorio bookshelf, ejecuta el siguiente comando:

    cd ~ ls -R bookshelf

    Deberías ver una lista que contiene tres archivos de Python, un archivo de requisitos y cuatro archivos de plantillas:

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

Instala las dependencias requeridas

  1. Para enumerar las dependencias en el archivo de requisitos, ejecuta el siguiente comando:

    cat ~/bookshelf/requirements.txt

    El archivo de requisitos especifica las siguientes dependencias:

    • Flask: Un módulo de framework web que se usa para diseñar aplicaciones web de Python
    • Gunicorn: Un servidor HTTP de Python que se ejecuta en Linux
    • Cloud Logging: Se usa para registrar información de la aplicación
    • Firestore: Una base de datos NoSQL de documentos rápida, completamente administrada y sin servidores diseñada para facilitar el desarrollo de aplicaciones
    • Cloud Storage: Almacenamiento de objetos unificado de Google Cloud
  2. Para instalar las dependencias en el archivo de requisitos, ejecuta el siguiente comando:

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

    pip es el instalador de paquetes para Python. Este comando pip3 instala los paquetes especificados en el archivo requirements.txt para usarlos con la versión 3 de Python.

Prueba la aplicación

  1. Para iniciar la aplicación, ejecuta el siguiente comando:

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

    Si creaste los archivos correctamente, la aplicación ahora debería estar alojada en el puerto 8080.

  2. Para ejecutar la aplicación en el navegador web, haz clic en Vista previa en la Web y, luego, selecciona Vista previa en el puerto 8080.

    Vista previa en el puerto 8080

    Se abre una nueva pestaña en el navegador y la aplicación se ejecuta. En esta página, se muestra una lista de todos los libros existentes. Aún no hay libros.

    Nota: Si se te solicita que autorices Cloud Shell, haz clic en Autorizar.
  3. Haz clic con el botón derecho en la imagen de la portada del libro El mago de Oz y guárdala en tu computadora como oz.png:

    Portada del libro El mago de Oz

  4. En la pestaña de la aplicación, haz clic en + Agregar libro.

  5. Ingresa la siguiente información en el formulario:

    Campo Valor
    Título El maravilloso mago de Oz
    Autor Frank L. Baum
    Fecha de publicación 1900
    Descripción Una niña y su perro son arrastrados a una tierra mágica, donde conocen a un grupo inusual de personas y aprenden a no pararse cerca de las casas.
  6. En Imagen de portada, haz clic en Elegir archivo.

  7. Selecciona el archivo que descargaste (oz.png) y haz clic en Abrir.

  8. Haz clic en Guardar.

    Regresarás a la página de vista y se mostrarán los detalles del libro.

  9. En la parte superior de la página, haz clic en Libros.

    Regresarás a la página de lista y verás El maravilloso mago de Oz en ella, junto con su portada. Los detalles del libro se almacenan en la base de datos de Firestore y la imagen de portada se guarda en Cloud Storage.

    Nota: Puedes agregar otros libros, pero no modificar El mago de Oz. Se usará en el resto de este lab.
  10. En Cloud Shell, ingresa CTRL-C para salir de la aplicación.

Para verificar este objetivo, haz clic en Revisar mi progreso. Probar la aplicación y crear un libro

Tarea 2: Crea credenciales de autorización de OAuth para tu aplicación

En esta tarea, crearás credenciales de autorización que identifiquen tu aplicación en el servidor OAuth 2.0 de Google.

Crea la pantalla de consentimiento de OAuth

Cuando usas OAuth 2.0 para la autorización, tu app solicita uno o más permisos de acceso de una Cuenta de Google. Google muestra una pantalla de consentimiento al usuario para registrar su autorización y, así, compartir datos con la aplicación.

  1. En la consola de Google Cloud, selecciona el menú de navegación (Ícono del menú de navegación) y, luego, APIs y servicios > Pantalla de consentimiento de OAuth.

    En esta página, puedes seleccionar el tipo de usuarios de tu aplicación. Los usuarios internos son los de tu organización. Los usuarios externos son los que tienen una Cuenta de Google.

  2. Haz clic en Comenzar.

  3. En Nombre de la app, ingresa Bookshelf.

  4. En Correo electrónico de asistencia del usuario, selecciona el correo electrónico del estudiante.

  5. Haz clic en Siguiente.

  6. En Público, selecciona Externoy, luego, haz clic en Siguiente.

    Los usuarios con una cuenta de prueba podrán acceder a la app.

  7. En el panel izquierdo de las instrucciones del lab, copia el nombre de usuario.

    Copiar nombre de usuario

  8. En Direcciones de correo electrónico, pega el nombre de usuario copiado y, luego, haz clic en Siguiente.

  9. Marca la casilla de verificación para aceptar la política de datos del usuario y, luego, haz clic en Continuar.

  10. Haz clic en Crear.

  11. En el menú de navegación, haz clic en Desarrollo de la marca.

  12. Haz clic en + Agregar un dominio.

  13. En la sección Dominios autorizados, ingresa cloudshell.dev en Dominio autorizado 1.

    Cuando la aplicación se ejecuta en Cloud Shell, cloudshell.dev es el nombre de dominio.

  14. Haz clic en Guardar.

  15. En el menú de navegación, haz clic en Acceso a los datos.

    Luego, debes seleccionar los permisos que se solicitarán a los usuarios para tu aplicación. Los permisos representan los tipos de datos privados del usuario en su Cuenta de Google a los que la aplicación quiere acceder.

    Hay tres tipos de permisos:

    • Los permisos sensibles son los que Google debe verificar antes de poder presentarlos a los usuarios en una pantalla de consentimiento.
    • Los permisos restringidos incluyen información aún más sensible, de apps como Gmail y Drive, y pueden requerir una revisión más profunda.
    • Los permisos no sensibles son menos sensibles y no requieren la verificación de Google.
  16. Haz clic en Agregar o quitar permisos.

    Se presentará una lista de permisos.

  17. Al principio de la lista, selecciona la casilla junto a openid.

  18. En Filtro, ingresa userinfo.profile, presiona Intro y, luego, selecciona la casilla junto al permiso …/auth/userinfo.profile.

  19. En Filtro, borra userinfo.profile, ingresa contacts, presiona Intro y, luego, selecciona la casilla del permiso .../auth/contacts.

  20. Haz clic en Actualizar.

    Deberías ver dos permisos no sensibles (openid y userinfo.profile) y un permiso sensible (contacts).

    Nota: En este lab, no se usará el permiso contacts, pero se muestra a modo de ejemplo. Tus aplicaciones deben usar los permisos mínimos necesarios.
  21. Haz clic en Guardar.

  22. En el menú de navegación, haz clic en Público.

    Los usuarios de prueba son obligatorios cuando son externos y el estado de publicación es Prueba.

  23. Haz clic en + Agregar usuarios.

  24. En el panel izquierdo de las instrucciones del lab, copia el nombre de usuario nuevamente.

  25. En el panel Agregar usuarios, pega el nombre de usuario copiado en el cuadro y, luego, haz clic en Guardar.

Crea las credenciales de OAuth 2.0

  1. En el menú de navegación, haz clic en Clientes y, luego, en + Crear cliente.

  2. En Tipo de aplicación, selecciona Aplicación web.

  3. En Nombre, ingresa Bookshelf.

  4. En URIs de redireccionamiento autorizados, haz clic en + Agregar URI.

    El URI especificado aquí se usará cuando Google redireccione el navegador a la aplicación después de registrar el consentimiento del usuario.

  5. Para obtener el URI de redireccionamiento, ejecuta el siguiente comando en Cloud Shell:

    echo "https://8080-${WEB_HOST}/oauth2callback"
  6. Copia el URI que se creó con el comando echo y pégalo en URIs 1.

  7. Haz clic en Crear.

  8. Haz clic en Descargar JSON para guardar el archivo JSON del secreto del cliente en tu máquina local.

    Este archivo se usará para verificar tu app con Google.

  9. Haz clic en Cerrar.

  10. En Cloud Shell, haz clic en Más (Ícono Más) en la barra de herramientas de la parte superior derecha y, luego, en Subir.

  11. Haz clic en Elegir archivos, selecciona el archivo JSON del secreto del cliente y, luego, haz clic en Abrir.

  12. Haz clic en Subir.

    El archivo JSON del secreto del cliente ahora está disponible en el directorio principal. El contenido de este archivo se usará durante el proceso de OAuth.

  13. En Cloud Shell, ejecuta el siguiente comando:

    cat ~/client_secret_*.json

    El contenido del archivo JSON incluye client_secret, que debe tratarse como una contraseña. Por ejemplo, nunca debes almacenar este archivo JSON en un repositorio de código.

Almacena el archivo JSON del secreto del cliente en Secret Manager

Secret Manager es un lugar seguro y recomendado para almacenar el archivo JSON del secreto del cliente.

  1. Para habilitar la API de Secret Manager, ejecuta el siguiente comando:

    gcloud services enable secretmanager.googleapis.com
  2. Para cambiar el nombre del archivo del secreto del cliente, ejecuta el siguiente comando:

    mv ~/client_secret*.json ~/client_secret.json
  3. Para crear el secreto, ejecuta el siguiente comando:

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

    Ahora hay un secreto llamado bookshelf-client-secrets al que se puede acceder desde la aplicación.

    Otro valor secreto que se necesita para la aplicación es la clave secreta de Flask, que se usa para firmar información en las cookies.

  4. Para crear un secreto de la clave secreta de Flask, ejecuta el siguiente comando:

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

    Este comando crea una contraseña aleatoria de 20 caracteres alfanuméricos y, luego, la almacena en un secreto llamado flask-secret-key.

Para verificar este objetivo, haz clic en Revisar mi progreso. Crear credenciales de autorización de OAuth para tu aplicación

Tarea 3: Usa Secret Manager para recuperar secretos en la aplicación

En esta tarea, modificarás la aplicación para que use Secret Manager.

Modifica el archivo de requisitos para agregar Secret Manager

  1. Para abrir el archivo llamado requirements.txt con nano, usa el siguiente comando:

    nano ~/bookshelf/requirements.txt
  2. En el archivo de requisitos, usa la flecha hacia abajo para ir a la primera línea vacía y, luego, agrega la siguiente línea:

    google-cloud-secret-manager==2.24.0

    El archivo requirements.txt ahora debería verse de la siguiente manera:

    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. Para guardar el archivo y salir, haz clic en CTRL-X, en Y y, luego, en Intro.

  4. Para instalar las versiones actualizadas de las dependencias, ejecuta el siguiente comando:

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

Crea una función para recuperar secretos

El archivo secrets.py contiene código para recuperar secretos de Secret Manager.

  1. Para crear el archivo secrets.py, ejecuta el siguiente comando:

    cat > ~/bookshelf/secrets.py <<EOF import os from google.cloud import secretmanager def get_secret(secret_id, version_id='latest'): # crea el cliente de secret manager client = secretmanager.SecretManagerServiceClient() # crea el nombre de recurso de la versión del secreto project_id = os.getenv('GOOGLE_CLOUD_PROJECT') name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}" # accede a la versión del secreto response = client.access_secret_version(name=name) # devuelve el secreto decodificado return response.payload.data.decode('UTF-8') EOF

    La función get_secret() acepta un ID de secreto y un ID de versión opcional. La función devuelve el secreto solicitado.

Modifica main.py para usar Secret Manager

El archivo de código principal debe llamar a Secret Manager para recuperar secretos.

  1. En un editor de archivos, abre el archivo ~/bookshelf/main.py.

  2. Después de la importación de storage, agrega la siguiente línea:

    import secrets

    Esta línea importa el archivo secrets.py que acabas de crear.

  3. En la llamada a función app.config.update, cambia SECRET_KEY de:

    SECRET_KEY='secret', # no almacenes SECRET_KEY en código en una app de productividad

    a:

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

    La clave secreta de Flask ya no se almacena en el código de la aplicación.

  4. Guarda el archivo.

Tarea 4: Crea funciones para el flujo de OAuth

En esta tarea, agregarás funciones que administren el flujo de acceso de OAuth.

Cuando un usuario acceda a la aplicación web, la app iniciará la secuencia de autorización de OAuth. OAuth permite que el usuario se autentique y dé su consentimiento para el acceso que solicita la aplicación. La secuencia de autorización de OAuth se ve de la siguiente manera:

Secuencia de autorización de OAuth

La secuencia de autorización comienza cuando la aplicación redirecciona el navegador a una URL de Google. Google se encarga de la autenticación del usuario, la selección de la sesión y el consentimiento del usuario. El resultado es un código de autorización que la aplicación puede intercambiar por un token de acceso y un token de actualización.

La aplicación almacena el token de actualización para usarlo en el futuro y usa el token de acceso para acceder a las APIs de Google. La aplicación Bookshelf llama a una API de Google para recuperar información sobre el usuario. Cuando el token de acceso vence, la aplicación usa el token de actualización para obtener uno nuevo.

Agrega dependencias

El cliente de OAuth de Python para Google requiere tres paquetes de Python más.

  1. En el archivo ~/bookshelf/requirements.txt, agrega las siguientes líneas:

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

    El archivo requirements.txt ahora debería verse de la siguiente manera:

    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. Guarda el archivo.

  3. Para instalar las versiones actualizadas de las dependencias, ejecuta el siguiente comando:

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

Agrega funciones de OAuth para administrar el flujo de autorización

El archivo oauth.py contiene código para recuperar un token de OAuth de Google.

  1. Para crear el archivo oauth.py, ejecuta el siguiente comando:

    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): """ Convierte la asignación de credenciales (objeto) en un diccionario. """ 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): """ Crea la URL que se usará para redireccionar a Google y para iniciar el flujo de OAuth. """ # especifica los detalles de configuración del flujo flow = google_auth_oauthlib.flow.Flow.from_client_config( client_config=client_config, scopes=scopes, ) flow.redirect_uri = callback_uri # crea un estado aleatorio state = str(uuid4()) # obtén la URL de autorización authorization_url, state = flow.authorization_url( # el acceso sin conexión hace posible la actualización del token de acceso sin volver a indicárselo al usuario # se usa en línea aquí para forzar el acceso 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): """ Recupera credenciales con el código de autorización en la URL de la solicitud y obtiene información del usuario que accedió. """ # valida el estado de recibido if received_state != stored_state: raise Unauthorized(f'Invalid state parameter: received={received_state} stored={stored_state}') # especifica los detalles de configuración del flujo flow = google_auth_oauthlib.flow.Flow.from_client_config( client_config=client_config, scopes=scopes ) flow.redirect_uri = callback_uri # obtén un token con los detalles en la solicitud 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 función authorize() inicia la secuencia de autorización. Configura el flujo con el parámetro client_config pasado, que se creará a partir de la cadena JSON de configuración de OAuth almacenada como secreto. La función callback_uri especifica a dónde llamará Google con el código de autorización. Este URI debe coincidir con un URI configurado como URI de redireccionamiento autorizado para la aplicación Bookshelf. La llamada flow.authorization_url() crea la URL completa para el redireccionamiento a Google. Se crea y pasa un estado, que se almacenará en la sesión para hacer coincidir esta llamada con la devolución de llamada final. La URL de autorización y el estado se devuelven al llamador.

    La función handle_callback() se usa cuando se recibe la devolución de llamada de Google. El estado especificado en la URL de devolución de llamada debe coincidir con el estado almacenado que se envió en la URL de autorización. La llamada flow.fetch_token() se puede usar para recuperar las credenciales, incluidos los tokens de acceso y de actualización. Las credenciales que se devuelven luego se usan para llamar a Google y recibir información del usuario que accedió. Luego, las credenciales y la información del usuario se devuelven al llamador.

    Nota: Es posible que la línea oauth2_client.userinfo() muestre un mensaje de error en el IDE que indique que no hay ningún miembro de userinfo. La función build() devuelve un objeto Resource, y los miembros válidos no se conocen en el momento de la creación. Este error se puede ignorar.

Tarea 5: Agrega extremos de acceso, devolución de llamada y cierre de sesión

En esta tarea, usarás las funciones de OAuth que acabas de crear para implementar los extremos de acceso, cierre de sesión y devolución de llamada.

Modifica las plantillas HTML

  1. Para crear una plantilla de error, ejecuta el siguiente comando:

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

    Cuando el usuario acceda, es posible que le aparezca un error. Esta página se utilizará para mostrar el error.

  2. En un editor de archivos, abre el archivo ~/bookshelf/templates/base.html.

    Se agregarán vínculos de acceso y cierre de sesión a la aplicación.

  3. En la sección navbar, en la línea después de la etiqueta de cierre (/ul) de la lista sin ordenar (ul) con class="nav navbar-nav", agrega la siguiente sección:

    <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>

    El archivo ahora se verá de la siguiente manera:

    <!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>

    La plantilla base ahora usa la sesión para verificar si el usuario accedió. Si el usuario accedió, se mostrarán su dirección de correo electrónico y un vínculo de cierre de sesión. Si el usuario no accedió, se mostrará un vínculo de acceso.

  4. Guarda el archivo.

Modifica las importaciones

  1. En un editor de archivos, abre el archivo ~/bookshelf/main.py.

  2. Agrega session a las importaciones flask.

    Las importaciones flask ahora deberían verse de la siguiente manera:

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

    La función session permitirá ver la información asociada con el usuario que accedió. Los datos de la sesión se almacenarán en cookies.

  3. Después de la línea cloud_logging import, agrega las siguientes líneas:

    import json import os from urllib.parse import urlparse

    En main.py, la biblioteca json se usa para convertir la cadena de secreto del cliente en una asignación (objeto), y la biblioteca os, para usar variables de entorno. La función urlparse() se usará para reemplazar el esquema y el nombre de host en una URL.

  4. Después de la importación de secrets, agrega la siguiente línea:

    import oauth

    De esta manera, se importarán las funciones de OAuth que creaste.

Agrega elementos de configuración

  1. En la llamada a función app.config.update(), agrega las siguientes líneas después de la línea 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'),

    Se agregan los siguientes elementos de configuración:

    • CLIENT_SECRETS contiene una asignación (objeto) para la configuración de OAuth que se almacenó en Secret Manager.
    • SCOPES contiene una lista de permisos que se solicitarán.
    • EXTERNAL_HOST_URL se usa para determinar la URL de devolución de llamada. Cuando usas Vista previa en la Web con Cloud Shell, la aplicación configurada para ejecutarse como localhost (127.0.0.1) en el puerto 80 se expone a Internet en https://8080-...-cloudshell.dev. Esta URL se usará para convertir la URL de localhost del extremo de devolución de llamada en la URL accesible de manera pública. El valor se pasará como una variable de entorno.

Agrega extremos y funciones complementarias

  1. Después de la función log_request(), que comienza con def log_request():, agrega las siguientes funciones:

    def logout_session(): """ Borra los elementos conocidos de la sesión. """ 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 enruta https://8080-***/ a localhost a través de http Esta función reemplaza el host localhost por el esquema configurado + nombre de host """ external_host_url = current_app.config['EXTERNAL_HOST_URL'] if external_host_url is None: # fuerza https if url.startswith('http://'): url = f"https://{url[7:]}" return url # reemplaza el esquema y el nombre de host por la URL del host externo 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(): """ Muestra un error. """ log_request(request) if "error_message" not in session: return redirect(url_for('.list')) # procesa error return render_template('error.html', error_message=session.pop('error_message', None)) @app.route("/login") def login(): """ Accede si aún no se hizo. """ log_request(request) if not "credentials" in session: # se necesita acceder current_app.logger.info('logging in') # obtén URL de autorización 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}") # guarda estado para verificación en devolución de llamada session['state'] = state return redirect(authorization_url) # ya accedió return redirect(session.pop('login_return', url_for('.list'))) @app.route("/oauth2callback") def oauth2callback(): """ Destino de devolución de llamada durante el proceso de OAuth. """ log_request(request) # verifica error, probablemente el usuario denegó el acceso error = request.args.get('error', None) if error: session['error_message'] = f"{error}" return redirect(url_for('.error')) # maneja la devolución de llamada de OAuth2 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(): """ Sal y regresa a la página raíz. """ log_request(request) logout_session() return redirect(url_for('.list'))

    La función logout_session() borra las entradas conocidas de sesión.

    La función external_url() reemplaza el esquema y el nombre de host de una URL por un nombre de host diferente para el acceso externo. Si no se especifica el nombre de host de reemplazo, la función se asegurará de que la URL devuelta use https.

    El extremo /error se usa para mostrar un error.

    El extremo /login verifica la sesión para saber si un usuario accedió. Un usuario accedió si las credenciales se almacenaron en la sesión. Si el usuario no accedió, se llama a oauth.authorize() para obtener la URL de autorización y el estado del redireccionamiento a Google. El estado se guarda en la sesión y, luego, el navegador se redirecciona a la URL de autorización.

    Google llama al extremo /oauth2callback durante el proceso de autorización. Si hubo un error, el proceso no se realizó correctamente y se redirecciona al usuario a la página de error. Si no hay un error, se llama a handle_callback() para recuperar el token y la información del usuario. Al final del proceso, se redirecciona al usuario a la página anterior en la que se inició el acceso automáticamente o a la página raíz (lista de libros) si no hay una ubicación de devolución.

    El extremo /logout cierra la sesión del usuario quitando las credenciales y los datos del usuario de la sesión, y regresa a la página raíz.

Fuerza el acceso cuando se agreguen, editen o borren libros

Un usuario puede explorar los libros de la biblioteca sin acceder. Sin embargo, tiene sentido forzarlo a acceder antes de que pueda modificar los libros de alguna forma.

Cuando un usuario intenta agregar, editar o borrar un libro, pero no ha accedido, se le debe forzar a hacerlo.

  1. En la función add(), justo después de la llamada a log_request(), agrega las siguientes líneas:

    # debe haber accedido if "credentials" not in session: session['login_return'] = url_for('.add') return redirect(url_for('.login'))

    En add(), si el usuario no accedió, se lo redirecciona a la página para agregar después de acceder.

  2. En la función edit(), justo después de la llamada a log_request(), agrega las siguientes líneas:

    # debe haber accedido if "credentials" not in session: session['login_return'] = url_for('.edit', book_id=book_id) return redirect(url_for('.login'))

    En editar(), si el usuario no accedió, se lo redirecciona a la página para editar de este libro después de acceder.

  3. En la función delete(), justo después de la llamada a log_request(), agrega las siguientes líneas:

    # debe haber accedido if "credentials" not in session: session['login_return'] = url_for('.view', book_id=book_id) return redirect(url_for('.login'))

    En delete(), si el usuario no accedió, se lo redirecciona a la página de vista de este libro después de acceder.

  4. Guarda el archivo.

Prueba la aplicación

  1. Para iniciar el servidor HTTP, ejecuta el siguiente comando en Cloud Shell:

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

    Se pasa una variable de entorno a la aplicación:

    • EXTERNAL_HOST_URL especifica el esquema y el nombre de host que se deben usar en la URL de devolución de llamada. Si no se especifica esta variable de entorno, el parámetro redirect_uri que se pasa a Google en la URL de autorización usará el nombre de host que la aplicación ve en las URLs entrantes, 127.0.0.1:8080, que es el localhost. Vista previa en la Web reenvía solicitudes de la URL de cloudshell.dev al localhost (http://127.0.0.1:8080).
    Nota: Si se te solicita que autorices Cloud Shell, haz clic en Autorizar.
  2. Para abrir la aplicación en el navegador web, haz clic en Vista previa en la Web y, luego, selecciona Vista previa en el puerto 8080.

    Vista previa en el puerto 8080

    Se abre una nueva pestaña en el navegador y la aplicación se ejecuta. Deberías ver el libro El mago de Oz. El usuario no accedió.

  3. Haz clic en + Agregar libro.

    Debes acceder para agregar un libro, por lo que se te pedirá que elijas una cuenta para acceder con Google:

    Elegir una cuenta

  4. Haz clic en el correo electrónico del estudiante y, luego, en Continuar.

    Google ahora obtendrá el consentimiento para cualquier permiso restringido o no sensible que se solicite. En este caso, descargar todos tus contactos es un permiso sensible.

    Obtener el consentimiento

  5. Haz clic en Permitir.

    Regresarás a la aplicación en la página Agregar libro. Ya accediste y tu correo electrónico se muestra en la esquina superior derecha. Si observas los registros en Cloud Shell, deberías ver la llamada de devolución de llamada 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

    El usuario dio su consentimiento para el acceso, por lo que el parámetro llamado code tiene el código de autorización que se intercambió posteriormente por las credenciales. También se devuelven los permisos admitidos.

  6. Haz clic en Libros y, luego, en + Agregar libro.

    Ya accediste a tu cuenta, así que puedes ir directamente a la página Agregar libro.

  7. Haz clic en Salir y, luego, en Acceder.

  8. Haz clic en el correo electrónico del estudiante, luego en Continuar y, después, en Cancelar.

    Regresarás a la página de error. Observa los registros en Cloud Shell. Deberías ver la devolución de llamada realizada por Google de la siguiente manera:

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

    En este caso, no se dio el consentimiento, por lo que no se devolvió el código de autorización y la aplicación no puede obtener las credenciales del usuario.

  9. En Cloud Shell, ingresa CTRL-C para salir de la aplicación.

Para verificar este objetivo, haz clic en Revisar mi progreso. Agregar extremos de acceso, devolución de llamada y cierre de sesión

Tarea 6: Crea funciones de traducción

En esta tarea, crearás funciones que usen la API de Cloud Translation para detectar el idioma del texto y traducirlo.

Las llamadas a la API de Cloud Translation usan las credenciales de la aplicación.

Agrega una dependencia de Cloud Translation

La aplicación requiere otro paquete de Python.

  1. En el archivo ~/bookshelf/requirements.txt, agrega la siguiente línea:

    google-cloud-translate==3.21.1

    El archivo requirements.txt ahora debería verse de la siguiente manera:

    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. Guarda el archivo.

  3. Para instalar las dependencias actualizadas, ejecuta el siguiente comando:

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

Agrega funciones de traducción

El archivo translate.py contiene el código para realizar la traducción.

  1. Para crear el archivo translate.py, ejecuta el siguiente comando:

    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(): """ Obtiene la lista de idiomas admitidos. """ # usa la variable global global supported_languages # recupera los idiomas admitidos si no se habían recuperado anteriormente 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): """ Detecta el idioma del texto proporcionado. Devuelve el idioma más probable. """ client = translate.TranslationServiceClient() response = client.detect_language( parent=PARENT, content=text, ) return response.languages[0] def translate_text(text, target_language_code): """ Traduce el texto al idioma de destino. """ client = translate.TranslationServiceClient() response = client.translate_text( parent=PARENT, contents=[text], target_language_code=target_language_code, ) return response.translations[0] EOF

    La función get_languages() recupera la lista de idiomas admitidos por la API de Cloud Translation. Cada idioma de la lista contiene un ID (language_code) y el texto visible (display_name).

    La función detect_language() detecta el idioma de una cadena de texto.

    La función translate_language() traduce texto a un idioma especificado.

Tarea 7: Crea un perfil de usuario para la selección de idioma y la traducción de descripciones

En esta tarea, crearás un perfil de usuario para los usuarios que accedieron. Se puede seleccionar un idioma preferido para el usuario.

El perfil se almacenará en una colección de Firestore llamada profiles. Se usará un perfil predeterminado con el idioma preferido en inglés hasta que el usuario actualice el perfil.

Agrega funciones para leer y actualizar perfiles

El archivo profiledb.py contiene código para leer y actualizar los perfiles de usuario. La dirección de correo electrónico del usuario se usará como clave de perfil. En esta implementación, el único elemento del perfil será el idioma preferido.

  1. Para crear el archivo profiledb.py, ejecuta el siguiente comando:

    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): """ Devuelve un perfil por correo electrónico. """ db = firestore.Client() # recupera un perfil de la base de datos por ID profile_ref = db.collection("profiles").document(email) profile_dict = __document_to_dict(profile_ref.get()) # recupera un diccionario vacío si no hay un perfil if profile_dict is None: profile_dict = default_profile.copy() return profile_dict def read_entry(email, key, default_value=''): """ Devuelve una entrada de perfil por correo electrónico y clave. """ profile_dict = read(email) return profile_dict.get(key, default_value) def update(data, email): """ Actualiza un perfil y devuelve los detalles del perfil actualizado. """ db = firestore.Client() # actualiza el perfil en la base de datos profile_ref = db.collection("profiles").document(email) profile_ref.set(data) return __document_to_dict(profile_ref.get()) EOF

    La función read() recupera un perfil para un usuario especificado. Si no se encuentra un perfil, se devuelve una copia del perfil predeterminado.

    La función read_entry() devuelve un solo valor del perfil de un usuario. Si no se encuentra la clave en el perfil del usuario, se devuelve el valor predeterminado pasado.

    La función update() crea o reemplaza el perfil del usuario por los datos especificados.

Agrega el extremo de perfil para ver y editar un perfil de usuario

  1. Para crear una nueva plantilla del perfil de usuario en profile.html, ejecuta el siguiente comando:

    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

    Esta plantilla crea un formulario único con un control de selección y un botón de envío. El control de selección se carga con todos los idiomas pasados mediante la variable de lista languages. El valor de cada entrada es language_code, y se muestra display_name en el control de selección. El idioma que se muestra inicialmente es la opción de preferredLanguage especificada en el perfil.

  2. En un editor de archivos, abre el archivo ~/bookshelf/main.py.

  3. Después de la importación de oauth, agrega las siguientes líneas:

    import translate import profiledb

    De esta forma, se importarán los archivos translate.py y profiledb.py que acabas de crear.

  4. Para agregar el extremo /profile, agrega la siguiente función después del extremo /books/<book_id>/delete:

    @app.route('/profile', methods=['GET', 'POST']) def profile(): """ Si es GET, muestra la forma de recopilar detalles actualizados para el perfil de usuario. Si es POST, actualiza el perfil según el formulario especificado. """ log_request(request) # debe haber accedido if "credentials" not in session: session['login_return'] = url_for('.profile') return redirect(url_for('.login')) # lee el perfil existente email = session['user']['email'] profile = profiledb.read(email) # Guarda detalles si el formulario se publicó if request.method == 'POST': # obtén detalles del libro del formulario data = request.form.to_dict(flat=True) # actualiza el perfil profiledb.update(data, email) session['preferred_language'] = data['preferredLanguage'] # regresa a la raíz return redirect(url_for('.list')) # procesa el formulario para actualizar el libro return render_template('profile.html', action='Edit', profile=profile, languages=translate.get_languages())

    Solo los usuarios que accedieron pueden ver el perfil, por lo que se redirecciona al usuario a la página de acceso si aún no lo ha hecho.

    El correo electrónico del usuario que accedió se toma de la información del usuario en la sesión y, luego, se lee el perfil actual.

    El perfil se procesa con la plantilla profile.html.

    Después de hacer clic en el botón de envío, el perfil se actualiza en la base de datos, el idioma preferido del usuario se almacena en la sesión y el navegador se redirecciona a la página raíz.

  5. Guarda el archivo.

Navega al perfil cuando hagas clic en la dirección de correo electrónico del usuario

  1. En un editor de archivos, abre el archivo ~/bookshelf/templates/base.html.

  2. En este archivo, cambia esta línea de la siguiente manera:

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

    a:

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

    De esta manera, cambiará la dirección de correo electrónico que se muestra por un vínculo en el que se puede hacer clic y que redirecciona al extremo /profile.

  3. Guarda el archivo.

Traduce la descripción en la página de vista

  1. En un editor de archivos, abre el archivo ~/bookshelf/templates/view.html.

  2. En este archivo, cambia esta línea de la siguiente manera:

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

    a:

    {% 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 no se especifica translation_language, la descripción no cambia. Sin embargo, si hay un idioma de traducción, se muestra el idioma de la descripción original y, en la siguiente línea, la versión traducida con el texto. El extremo de vista debe pasar esta información adicional.

  3. Guarda el archivo.

  4. En un editor de archivos, abre el archivo ~/bookshelf/main.py.

  5. Después de la función log_request(), que comienza con def log_request():, agrega el siguiente código:

    # crea una asignación de códigos de idioma a nombres visibles display_languages = {} for l in translate.get_languages(): display_languages[l.language_code] = l.display_name

    La función detect_language() devuelve un código de idioma detectado, pero no un nombre visible. Este código crea una asignación del código de idioma al nombre visible. Se usará para mostrar el idioma detectado en la plantilla de vista.

  6. Reemplaza el código del extremo de vista completo por lo siguiente:

    @app.route('/books/<book_id>') def view(book_id): """ Ve los detalles de un libro especificado. """ log_request(request) # recupera un libro específico book = booksdb.read(book_id) current_app.logger.info(f"book={book}") # establece la configuración predeterminada si se cierra sesión description_language = None translation_language = None translated_text = '' if book['description'] and "credentials" in session: preferred_language = session.get('preferred_language', 'en') # traduce la descripción 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 # procesa los detalles del libro return render_template('view.html', book=book, translated_text=translated_text, description_language=description_language, translation_language=translation_language, )

    El código ahora traduce la descripción del libro al idioma preferido del usuario y pasa la traducción y los idiomas a la plantilla.

  7. Guarda el archivo.

Tarea 8: Prueba la aplicación

  1. Para iniciar el servidor HTTP, ejecuta el siguiente comando:

    cd ~/bookshelf; EXTERNAL_HOST_URL="https://8080-$WEB_HOST" ~/.local/bin/gunicorn -b :8080 main:app
  2. Para abrir la aplicación en el navegador web, haz clic en Vista previa en la Web y, luego, selecciona Vista previa en el puerto 8080.

    Vista previa en el puerto 8080

    Se abre una nueva pestaña en el navegador y la aplicación se ejecuta. Deberías ver el libro El mago de Oz.

    Nota: Si se te solicita que autorices Cloud Shell, haz clic en Autorizar.
  3. Si el usuario no accedió, haz clic en Acceder y, luego, accede con el consentimiento del usuario.

    La dirección de correo electrónico ahora debería ser un vínculo.

  4. Haz clic en la dirección de correo electrónico.

    Se muestra el perfil. El control de selección de idioma debe mostrar English.

  5. Cambia el Idioma preferido a Suajili y, luego, haz clic en Guardar.

  6. Haz clic en el libro El maravilloso mago de Oz.

    La página de vista ahora contiene la descripción original en inglés y la traducción al suajili.

Para verificar este objetivo, haz clic en Revisar mi progreso. Probar la aplicación

¡Felicitaciones!

Modificaste correctamente una aplicación para que los usuarios accedan con OAuth. Luego, agregaste un perfil de usuario con un idioma preferido y usaste la API de Cloud Translation para proporcionar traducciones de la descripción de un libro.

Próximos pasos/Más información

Finalice su lab

Cuando haya completado el lab, haga clic en Finalizar lab. Google Cloud Skills Boost quitará los recursos que usó y limpiará la cuenta.

Tendrá la oportunidad de calificar su experiencia en el lab. Seleccione la cantidad de estrellas que corresponda, ingrese un comentario y haga clic en Enviar.

La cantidad de estrellas indica lo siguiente:

  • 1 estrella = Muy insatisfecho
  • 2 estrellas = Insatisfecho
  • 3 estrellas = Neutral
  • 4 estrellas = Satisfecho
  • 5 estrellas = Muy satisfecho

Puede cerrar el cuadro de diálogo si no desea proporcionar comentarios.

Para enviar comentarios, sugerencias o correcciones, use la pestaña Asistencia.

Copyright 2024 Google LLC. Todos los derechos reservados. Google y el logotipo de Google son marcas de Google LLC. El resto de los nombres de productos y empresas pueden ser marcas de las respectivas empresas a las que están asociados.

Antes de comenzar

  1. Los labs crean un proyecto de Google Cloud y recursos por un tiempo determinado
  2. .
  3. Los labs tienen un límite de tiempo y no tienen la función de pausa. Si finalizas el lab, deberás reiniciarlo desde el principio.
  4. En la parte superior izquierda de la pantalla, haz clic en Comenzar lab para empezar

Usa la navegación privada

  1. Copia el nombre de usuario y la contraseña proporcionados para el lab
  2. Haz clic en Abrir la consola en modo privado

Accede a la consola

  1. Accede con tus credenciales del lab. Si usas otras credenciales, se generarán errores o se incurrirá en cargos.
  2. Acepta las condiciones y omite la página de recursos de recuperación
  3. No hagas clic en Finalizar lab, a menos que lo hayas terminado o quieras reiniciarlo, ya que se borrará tu trabajo y se quitará el proyecto

Este contenido no está disponible en este momento

Te enviaremos una notificación por correo electrónico cuando esté disponible

¡Genial!

Nos comunicaremos contigo por correo electrónico si está disponible

Un lab a la vez

Confirma para finalizar todos los labs existentes y comenzar este

Usa la navegación privada para ejecutar el lab

Usa una ventana de navegación privada o de Incógnito para ejecutar el lab. Así evitarás cualquier conflicto entre tu cuenta personal y la cuenta de estudiante, lo que podría generar cargos adicionales en tu cuenta personal.