Implementa un "Google Traductor" app en Python 3 de Cloud Run (Docker)

1. Descripción general

Esta serie de codelabs (instructivos prácticos y de autoaprendizaje) tiene como objetivo ayudar a los desarrolladores a comprender las diversas opciones que tienen cuando implementan sus aplicaciones. En este codelab, aprenderás a usar la API de Google Cloud Translation con Python y a ejecutarla de forma local o implementarla en una plataforma de procesamiento sin servidores de Cloud (App Engine, Cloud Functions o Cloud Run). La app de ejemplo que se encuentra en el repo de este instructivo se puede implementar (al menos) de ocho maneras diferentes con solo cambios menores en la configuración:

  1. Servidor local de Flask (Python 2)
  2. Servidor local de Flask (Python 3)
  3. App Engine (Python 2)
  4. App Engine (Python 3)
  5. Cloud Functions (Python 3)
  6. Cloud Run (Python 2 a través de Docker)
  7. Cloud Run (Python 3 a través de Docker)
  8. Cloud Run (Python 3 a través de Cloud Buildpacks)

Este codelab se enfoca en implementar esta app en las plataformas en negrita mencionadas anteriormente.

Obtendrás información para hacer las siguientes acciones

Requisitos

Encuesta

¿Cómo usarás este instructivo?

Leer y completar los ejercicios Solo leer

¿Cómo calificarías tu experiencia en Python?

Principiante Intermedio Avanzado

¿Cómo calificarías tu experiencia en el uso de los servicios de Google Cloud?

Principiante Intermedio Avanzado

2. Configuración y requisitos

Configuración del entorno de autoaprendizaje

  1. Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una string de caracteres que no se utiliza en las API de Google y se puede actualizar en cualquier momento.
  • El ID del proyecto debe ser único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). Cloud Console genera automáticamente una string única, que, por lo general, no importa cuál sea. En la mayoría de los codelabs, debes hacer referencia al ID del proyecto (suele ser PROJECT_ID). Por lo tanto, si no te gusta, genera otro aleatorio o prueba con uno propio y comprueba si está disponible. Después de crear el proyecto, este ID se “congela” y no se puede cambiar.
  • Además, hay un tercer valor, el Número de proyecto, que usan algunas API. Obtén más información sobre estos tres valores en la documentación.
  1. A continuación, deberás habilitar la facturación en Cloud Console para usar las API o los recursos de Cloud. Ejecutar este codelab no debería costar mucho, tal vez nada. Si quieres cerrar los recursos para no se te facture más allá de este instructivo, sigue las instrucciones de “limpieza” que se encuentran al final del codelab. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de USD 300.

3. Habilita la API de Translation

Habilita las APIs de Cloud

En esta sección, aprenderás a habilitar las APIs de Google en general. En el caso de nuestra app de ejemplo, habilitarás la API de Cloud Translation, Cloud Run y Cloud Artifact Registry.

Introducción

Independientemente de la API de Google que quieras usar en tu aplicación, esta debe estar habilitada. En el siguiente ejemplo, se muestran dos formas de habilitar la API de Cloud Vision. Después de aprender a habilitar una API de Cloud, podrás habilitar otras APIs, ya que el proceso es similar.

Opción 1: Desde Cloud Shell o tu interfaz de línea de comandos

Si bien es más común habilitar las APIs desde la consola de Cloud, algunos desarrolladores prefieren hacer todo desde la línea de comandos. Para ello, debes buscar el "nombre del servicio" de una API. Parece una URL: SERVICE_NAME.googleapis.com. Puedes encontrarlos en el gráfico de productos compatibles o consultarlos de forma programática con la API de Google Discovery.

Con esta información, puedes habilitar una API con Cloud Shell (o tu entorno de desarrollo local con la herramienta de línea de comandos de gcloud instalada) de la siguiente manera:

gcloud services enable SERVICE_NAME.googleapis.com

Por ejemplo, este comando habilita la API de Cloud Vision:

gcloud services enable vision.googleapis.com

Este comando habilita App Engine:

gcloud services enable appengine.googleapis.com

También puedes habilitar varias APIs con una sola solicitud. Por ejemplo, esta línea de comandos habilita Cloud Run, Cloud Artifact Registry y la API de Cloud Translation:

gcloud services enable artifactregistry.googleapis.com run.googleapis.com translate.googleapis.com

Opción 2: Desde Cloud Console

También puedes habilitar la API de Vision en el Administrador de APIs. En Cloud Console, ve a API Manager y selecciona Biblioteca.

fb0f1d315f122d4a.png

Si quieres habilitar la API de Cloud Vision, comienza a ingresar "vision" en la barra de búsqueda y aparecerá todo lo que coincida con lo que ingresaste hasta el momento:

2275786a24f8f204.png

Selecciona la API que deseas habilitar y haz clic en Habilitar:

2556f923b628e31.png

Costo

Si bien muchas APIs de Google se pueden usar sin cargo, el uso de los productos y las APIs de Google Cloud no es gratuito. Cuando habilites las APIs de Cloud, es posible que se te solicite una cuenta de facturación activa. Sin embargo, es importante tener en cuenta que algunos productos de Google Cloud incluyen un nivel "Siempre gratis" (diario o mensual) que debes superar para incurrir en cargos de facturación. De lo contrario, no se te cobrará en la tarjeta de crédito (o en el instrumento de facturación especificado).

Los usuarios deben consultar la información de precios de cualquier API antes de habilitarla, y deben tener en cuenta si tiene un nivel gratuito y, si es así, cuál es. Si habilitaras la API de Cloud Vision, consultarías la página de información de precios. Cloud Vision tiene una cuota gratuita y, siempre que te mantengas dentro de sus límites de forma agregada (dentro de cada mes), no deberías incurrir en ningún cargo.

Los precios y los niveles gratuitos varían entre las APIs de Google. Ejemplos:

Los diferentes productos de Google se facturan de manera diferente, así que asegúrate de consultar la documentación de la API para obtener esa información.

Resumen

Ahora que sabes cómo habilitar las APIs de Google en general, ve al Administrador de APIs y habilita las APIs de Cloud Translation, Cloud Run y Cloud Artifact Registry (si aún no lo hiciste). Habilita el primero porque nuestra aplicación lo usa. Habilitarás la última opción porque allí se almacenan nuestras imágenes de contenedor antes de implementarse para iniciar tu servicio de Cloud Run, por lo que debes habilitar esa opción. Si prefieres habilitarlos todos con la herramienta de gcloud, ejecuta el siguiente comando desde tu terminal:

gcloud services enable artifactregistry.googleapis.com run.googleapis.com translate.googleapis.com

Si bien su cuota mensual no se indica en la página de resumen general del nivel "Siempre gratis", en la página de precios de la API de Translation se indica que todos los usuarios obtienen una cantidad fija de caracteres traducidos por mes. No se te cobrará ninguna tarifa por la API si te mantienes por debajo de ese umbral. Si hay otros cargos relacionados con Google Cloud, se analizarán al final en la sección "Limpieza".

4. Obtén el código de la app de ejemplo

Clona el código en el repo de forma local o en Cloud Shell (con el comando git clone), o descarga el archivo ZIP desde su botón verde Code, como se muestra en la siguiente captura de pantalla:

5cd6110c4414cf65.png

Ahora que tienes todo, crea una copia completa de la carpeta para realizar este instructivo específico, ya que es probable que debas borrar o cambiar los archivos. Si quieres realizar otra implementación, puedes copiar la original para no tener que clonarla ni descargarla de nuevo.

5. Recorrido por la app de ejemplo

La app de ejemplo es una derivada simple de Google Traductor que solicita a los usuarios que ingresen texto en inglés y reciban la traducción equivalente de ese texto en español. Ahora, abre el archivo main.py para que podamos ver cómo funciona. Si se omiten las líneas comentadas sobre la licencia, se verá de la siguiente manera en la parte superior e inferior:

from flask import Flask, render_template, request
import google.auth
from google.cloud import translate

app = Flask(__name__)
_, PROJECT_ID = google.auth.default()
TRANSLATE = translate.TranslationServiceClient()
PARENT = 'projects/{}'.format(PROJECT_ID)
SOURCE, TARGET = ('en', 'English'), ('es', 'Spanish')

# . . . [translate() function definition] . . .

if __name__ == '__main__':
    import os
    app.run(debug=True, threaded=True, host='0.0.0.0',
            port=int(os.environ.get('PORT', 8080)))
  1. Las importaciones incorporan la funcionalidad de Flask, el módulo google.auth y la biblioteca cliente de la API de Cloud Translation.
  2. Las variables globales representan la app de Flask, el ID del proyecto de Cloud, el cliente de la API de Translation, la "ruta de ubicación" principal para las llamadas a la API de Translation y los idiomas de origen y destino. En este caso, son inglés (en) y español (es), pero puedes cambiar estos valores por otros códigos de idioma admitidos por la API de Cloud Translation.
  3. El bloque if grande en la parte inferior se usa en el instructivo para ejecutar esta app de forma local. Utiliza el servidor de desarrollo de Flask para entregar nuestra app. Esta sección también se incluye para los instructivos de implementación de Cloud Run en caso de que el servidor web no se incluya en el contenedor. Se te pedirá que habilites la agrupación del servidor en el contenedor, pero, en caso de que lo pases por alto, el código de la app recurrirá al uso del servidor de desarrollo de Flask. (No es un problema con App Engine ni Cloud Functions, ya que son plataformas basadas en fuentes, lo que significa que Google Cloud proporciona y ejecuta un servidor web predeterminado).

Por último, en el medio de main.py, se encuentra el corazón de la aplicación, la función translate():

@app.route('/', methods=['GET', 'POST'])
def translate(gcf_request=None):
    """
    main handler - show form and possibly previous translation
    """

    # Flask Request object passed in for Cloud Functions
    # (use gcf_request for GCF but flask.request otherwise)
    local_request = gcf_request if gcf_request else request

    # reset all variables (GET)
    text = translated = None

    # if there is data to process (POST)
    if local_request.method == 'POST':
        text = local_request.form['text']
        data = {
            'contents': [text],
            'parent': PARENT,
            'target_language_code': TARGET[0],
        }
        # handle older call for backwards-compatibility
        try:
            rsp = TRANSLATE.translate_text(request=data)
        except TypeError:
            rsp = TRANSLATE.translate_text(**data)
        translated = rsp.translations[0].translated_text

    # create context & render template
    context = {
        'orig':  {'text': text, 'lc': SOURCE},
        'trans': {'text': translated, 'lc': TARGET},
    }
    return render_template('index.html', **context)

La función principal se encarga de tomar la entrada del usuario y llamar a la API de Translation para realizar el trabajo pesado. Veamos esto en detalle:

  1. Verifica si las solicitudes provienen de Cloud Functions con la variable local_request. Cloud Functions envía su propio objeto Request de Flask, mientras que todos los demás (que se ejecutan de forma local o se implementan en App Engine o Cloud Run) obtendrán el objeto de solicitud directamente de Flask.
  2. Restablece las variables básicas del formulario. Esto se aplica principalmente a las solicitudes GET, ya que las solicitudes POST tendrán datos que reemplazarán estos valores.
  3. Si es una solicitud POST, toma el texto para traducir y crea una estructura JSON que represente el requisito de metadatos de la API. Luego, llama a la API y vuelve a una versión anterior de la API si el usuario usa una biblioteca más antigua.
  4. De todos modos, formatea los resultados reales (POST) o los datos nulos (GET) en el contexto de la plantilla y renderiza.

La parte visual de la aplicación se encuentra en el archivo de plantilla index.html. Muestra los resultados traducidos anteriormente (en blanco, de lo contrario) seguidos del formulario que solicita algo para traducir:

<!doctype html>
<html><head><title>My Google Translate 1990s</title><body>
<h2>My Google Translate (1990s edition)</h2>

{% if trans['text'] %}
    <h4>Previous translation</h4>
    <li><b>Original</b>:   {{ orig['text'] }}  (<i>{{ orig['lc'][0] }}</i>)</li>
    <li><b>Translated</b>: {{ trans['text'] }} (<i>{{ trans['lc'][0] }}</i>)</li>
{% endif %}

<h4>Enter <i>{{ orig['lc'][1] }}</i> text to translate to <i>{{ trans['lc'][1] }}</i>:</h4>
<form method="POST"><input name="text"><input type="submit"></form>
</body></html>

6. Configura Docker para compilar la imagen de Python 3

Ahora, abre el archivo Dockerfile, que, sin la información de la licencia, se ve de la siguiente manera:

#FROM python:3-slim
FROM python:2-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
ENTRYPOINT ["python", "main.py"]

Como puedes ver, de forma predeterminada, está configurado para Python 2, así que cambiemos eso editando la línea FROM de python:2-slim a python:3-slim o quitando el comentario de la primera línea y borrando la línea FROM anterior. Cuando termines, el archivo Dockerfile debería verse así:

FROM python:3-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
ENTRYPOINT ["python", "main.py"]

7. Implemente el servicio

Ahora puedes implementar tu servicio de traducción en Cloud Run ejecutando este comando:

gcloud run deploy translate --source . --allow-unauthenticated --platform managed

El resultado debería ser el siguiente y proporcionar algunas instrucciones para los próximos pasos:

$ gcloud run deploy translate --source . --allow-unauthenticated --platform managed
Please specify a region:
 [1] asia-east1
 [2] asia-east2
. . . (other regions) . . .
 [28] us-west4
 [29] cancel
Please enter your numeric choice:  REGION_CHOICE

To make this the default region, run `gcloud config set run/region REGION`.

Deploying from source requires an Artifact Registry repository to
store build artifacts. A repository named [cloud-run-source-deploy] in
 region [REGION] will be created.

Do you want to continue (Y/n)?

This command is equivalent to running "gcloud builds submit --pack image=[IMAGE] ." and "gcloud run deploy translate --image [IMAGE]"

Building . . . and deploying container to Cloud Run service [translate] in project [PROJECT_ID] region [REGION]
✓ Building and deploying... Done.
  ✓ Creating Container Repository...
  ✓ Uploading sources...
  ✓ Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/60e1b
  9bb-b991-4b4e-8d8a-HASH?project=PROJECT_NUMBER].
  ✓ Creating Revision...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [translate] revision [translate-00001-xyz] has been deployed and is serving 100 percent of traffic.
Service URL: https://SVC_NAME-HASH-REG_ABBR.a.run.app

Ahora que tu app está disponible en todo el mundo, deberías poder acceder a ella en la URL que contiene el ID de tu proyecto, como se muestra en el resultado de la implementación:

169f6edf5f7d2068.png

Traduce algo para ver cómo funciona.

31554e71cb80f1b4.png

8. Conclusión

¡Felicitaciones! Aprendiste a habilitar la API de Cloud Translation, obtener las credenciales necesarias y, luego, implementar una app web simple en Python 3 de Cloud Run.

Limpia

La API de Cloud Translation te permite realizar una cantidad fija de traducciones de caracteres por mes de forma gratuita. App Engine también tiene una cuota gratuita, al igual que Cloud Functions y Cloud Run. Se te cobrarán cargos si se supera cualquiera de los límites. Si planeas continuar con el siguiente codelab, no es necesario que cierres la app.

Sin embargo, si aún no estás listo para continuar con el siguiente instructivo o te preocupa que Internet descubra la app que acabas de implementar, inhabilita tu app de App Engine, borra tu Cloud Function o inhabilita tu servicio de Cloud Run para evitar que se apliquen cargos. Cuando estés listo para pasar al siguiente codelab, puedes volver a habilitarla. Por otro lado, si no vas a continuar con esta aplicación ni con otros codelabs y quieres borrar todo por completo, puedes cerrar tu proyecto.

Además, la implementación en una plataforma de procesamiento sin servidores de Google Cloud genera costos menores de compilación y almacenamiento. Cloud Build tiene su propia cuota gratuita, al igual que Cloud Storage. Para mayor transparencia, Cloud Build compila la imagen de tu aplicación, que luego se almacena en Cloud Container Registry o en Artifact Registry, su sucesor. El almacenamiento de esa imagen usa parte de esa cuota, al igual que la salida de red cuando se transfiere la imagen al servicio. Sin embargo, es posible que vivas en una región que no tenga ese nivel gratuito, por lo que debes tener en cuenta tu uso de almacenamiento para minimizar los costos potenciales.

9. Recursos adicionales

En las siguientes secciones, encontrarás material de lectura adicional y ejercicios recomendados para aumentar los conocimientos que adquiriste al completar este instructivo.

Estudio adicional

Ahora que tienes algo de experiencia con la API de Translation, hagamos algunos ejercicios adicionales para desarrollar aún más tus habilidades. Para continuar con tu ruta de aprendizaje, modifica nuestra app de ejemplo de la siguiente manera:

  1. Completa todas las demás ediciones de este codelab para ejecutarlo de forma local o implementarlo en las plataformas de procesamiento sin servidores de Google Cloud (consulta el README del repo).
  2. Completar este instructivo con otro lenguaje de programación
  3. Cambia esta aplicación para que admita diferentes idiomas de origen o destino.
  4. Actualiza esta aplicación para poder traducir texto a más de un idioma. Cambia el archivo de plantilla para que tenga un menú desplegable de idiomas de destino admitidos.

Más información

Google App Engine

Google Cloud Functions

Google Cloud Run

Buildpacks de Google Cloud, Container Registry y Artifact Registry

Google Cloud Translation y Google ML Kit

Otros productos o páginas de Google Cloud

Python y Flask

Licencia

Este instructivo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons, mientras que el código fuente del repositorio cuenta con la licencia Apache 2.