Implementar una aplicación web de Flask escrita en Python en el entorno flexible de App Engine

Resumen

En este codelab, aprenderás a implementar una aplicación web de Flask escrita en Python en el entorno flexible de App Engine. La aplicación de ejemplo permite que el usuario suba una foto del rostro de alguien y descubra qué tan probable es que esa persona esté feliz. La aplicación usa API de Google Cloud para Vision, Storage y Datastore.

Acerca de App Engine

Las aplicaciones de Google App Engine son fáciles de crear, mantener y escalar a medida que cambian sus necesidades de almacenamiento de datos y tráfico. Con App Engine, no tendrá que mantener servidores. Solo debe subir su aplicación y estará lista para usar.

Las aplicaciones de App Engine cuentan con ajuste de escala automático según el tráfico entrante. El balanceo de cargas, los microservicios, la autorización, las bases de datos SQL y NoSQL, la división del tráfico, el registro, la búsqueda, el control de versiones, el lanzamiento y las reversiones, y el análisis de seguridad son compatibles de forma nativa y sumamente personalizables.

El entorno flexible de App Engine es compatible con todos los lenguajes de programación siguientes: C#, Go, Java, Node.js, PHP, Python y Ruby. El entorno flexible de App Engine ejecuta su aplicación dentro de contenedores de Docker que se ejecutan en máquinas virtuales de Google Compute Engine. El entorno estándar de App Engine es una opción alternativa para algunos lenguajes, incluido Python. El entorno estándar de App Engine ejecuta tu aplicación en un entorno de zona de pruebas más restrictivo. Consulta Elige un entorno de App Engine para obtener más información.

Qué aprenderás

  • Cómo implementar una aplicación web sencilla para el entorno flexible de App Engine
  • Cómo acceder a bibliotecas cliente de Google Cloud para Vision, Storage y Datastore
  • Cómo usar Google Cloud Console y el SDK de Google Cloud para administrar varios recursos de la nube
  • Cómo usar Cloud Shell

Requisitos

  • Conocimientos de Python
  • Conocimientos de editores de texto estándares de Linux, como Vim, Emacs o Nano

Creación de proyectos

Si aún no tienes una Cuenta de Google (Gmail o Google Apps), debes crear una. Accede a Google Cloud Platform Console (console.cloud.google.com) y crea un proyecto nuevo:

Recuerde el ID de proyecto, un nombre único en todos los proyectos de Google Cloud (el nombre anterior ya se encuentra en uso y no lo podrá usar). Más adelante en este codelab, se hará referencia a él como PROJECT_ID.

Facturación

A continuación, debes habilitar la facturación en Cloud Console para usar los recursos de Google Cloud.

Ejecutar este codelab no debería costar más que unos pocos dólares, pero podría ser más si decides usar más recursos o si los dejas en ejecución.

Los usuarios nuevos de Google Cloud Platform son aptos para obtener una prueba gratuita de USD 300.

Si bien Google Cloud se puede operar de forma remota desde su laptop, en este codelab usaremos Google Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube. Esta máquina virtual basada en Debian está cargada con todas las herramientas de desarrollo que necesita (gcloud, python, gke, pip y más), ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que mejora en gran medida el rendimiento y la autenticación de la red. Esto significa que todo lo que necesitarás para este Codelab es un navegador (sí, funciona en una Chromebook).

Para activar Google Cloud Shell, en Developer Console, simplemente haz clic en el botón que se encuentra en la esquina superior derecha (el aprovisionamiento y la conexión al entorno debería llevar solo unos minutos):

Una vez conectado a Cloud Shell, debería ver que ya está autenticado y que el proyecto ya está configurado con su PROJECT_ID:

gcloud auth list
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
gcloud config list project
[core]
Project = <PROJECT_ID>

Si, por algún motivo, el proyecto no se configuró, simplemente ejecuta el siguiente comando:

gcloud config set project <PROJECT_ID>

¿Busca su PROJECT_ID? Verifica el ID del proyecto que usaste en los pasos de configuración o búscalo en el panel de la consola:

En la línea de comandos de Cloud Shell, ejecute el siguiente comando para clonar el repositorio de GitHub:

git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

Cambie al directorio python-docs-samples/codelabs/flex_and_vision:

cd python-docs-samples/codelabs/flex_and_vision

Antes de comenzar a usar las API de Vision, Storage y Datastore, debe habilitar las API con los siguientes comandos:

gcloud services enable vision.googleapis.com
gcloud services enable storage-component.googleapis.com
gcloud services enable datastore.googleapis.com

Para realizar solicitudes a las API de Vision, Storage y Datastore, necesitará credenciales de cuentas de servicio. Las credenciales de la cuenta de servicio de tu proyecto se pueden generar con la herramienta gcloud.

Configure una variable de entorno para su PROJECT_ID. Para ello, reemplace [YOUR_PROJECT_ID] por su propio ID del proyecto:

export PROJECT_ID=[YOUR_PROJECT_ID]

Cree una cuenta de servicio para acceder a las API de Google Cloud cuando realice pruebas locales:

gcloud iam service-accounts create codelab \
  --display-name "My Codelab Service Account"

Otorgue los permisos adecuados a su nueva cuenta de servicio:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:codelab@${PROJECT_ID}.iam.gserviceaccount.com \
--role roles/owner

Después de crear su cuenta de servicio, cree una clave para ella:

gcloud iam service-accounts keys create ~/key.json \
--iam-account codelab@${PROJECT_ID}.iam.gserviceaccount.com

Este comando genera una clave de cuenta de servicio que se almacena en un archivo JSON llamado key.json en su directorio principal.

Use la ruta de acceso absoluta de la clave generada y configure una variable de entorno para su clave de cuenta de servicio en Cloud Shell:

export GOOGLE_APPLICATION_CREDENTIALS="/home/${USER}/key.json"

Obtén más información sobre cómo autenticar la API de Vision.

Cómo iniciar su entorno virtual e instalar dependencias

Cree un entorno aislado de Python 3 llamado env con HOWMANY:

virtualenv -p python3 env

Ingrese el Anthos recién creado, denominado env:

source env/bin/activate

Use pip a fin de instalar dependencias para su proyecto desde el archivo requirements.txt:

pip install -r requirements.txt

El archivo requirements.txt es una lista de las dependencias de paquetes que necesita para su proyecto. El comando anterior descargó todas estas dependencias de paquetes en virtualenv.

Cómo crear una aplicación de App Engine

A continuación, cree una instancia de App Engine usando lo siguiente:

gcloud app create

Cómo crear un depósito de Storage

Primero, defina la variable de entorno CLOUD_STORAGE_BUCKET para que sea igual al nombre de su PROJECT_ID. Generalmente, se recomienda que asigne a su depósito el mismo nombre que para PROJECT_ID por conveniencia.

export CLOUD_STORAGE_BUCKET=${PROJECT_ID}

Nuestra aplicación usa un bucket de Cloud Storage, que deberá crear desde Cloud Shell con una herramienta llamada gsutil. Ejecute el siguiente comando, que crea un bucket con el mismo nombre que ID_DE_PROYECTO.

gsutil mb gs://${PROJECT_ID}

Ejecute la aplicación

python main.py

Cuando se inicie la aplicación, haga clic en el ícono de Vista previa en la Web en la barra de herramientas de Cloud Shell y elija “Vista previa en el puerto 8080”.

En su navegador, se abrirá una pestaña y se conectará al servidor que acaba de iniciar. Debería ver algo como esto:

Captura de pantalla 23 de febrero de 2017 a las 7.22.50 p.m.png

Intenta subir una foto que contenga un rostro humano. Haga clic en el botón Elegir archivo, seleccione una imagen de su computadora y, luego, haga clic en Enviar.

Después de subir una foto, debería ver algo como esto:

Captura de pantalla 23 de febrero de 2017 a las 7.32.08 p.m.png

Diseño de muestra del código

La muestra tiene el siguiente diseño:

templates/
  homepage.html   /* HTML template that uses Jinja2 */
app.yaml          /* App Engine application configuration file */
main.py           /* Python Flask web application */
requirements.txt  /* List of dependencies for the project */

main.py

Este archivo de Python es una aplicación web de Flask. La aplicación permite que los usuarios envíen fotos (preferentemente de rostros), las cuales se almacenan en Cloud Storage y se analizan con la función de detección de rostro de la API de Cloud Vision. La información clave sobre cada foto se almacena en Datastore, la base de datos NoSQL de Google Cloud Platform, a la que se accede cada vez que un usuario visita el sitio web.

Esta aplicación usa las bibliotecas cliente de Google Cloud Platform para Storage, Datastore y Vision. Estas bibliotecas cliente facilitan el acceso a las API de Cloud desde sus lenguajes de programación preferidos.

Veamos algunos fragmentos clave del código.

En la sección de importaciones, ubicada en la parte superior, importamos los distintos paquetes que necesitamos para nuestro código. Importamos las bibliotecas cliente de Google Cloud para Datastore, Storage y Vision de esta manera:

from google.cloud import datastore
from google.cloud import storage
from google.cloud import vision

Este código muestra lo que sucede cuando un usuario visita la URL raíz del sitio web. Creamos un objeto de cliente de Datastore, que se usa para acceder a la biblioteca cliente de Datastore. Luego, ejecutamos una consulta en Datastore para entidades del tipo Faces. Finalmente, renderizamos nuestra plantilla HTML y pasamos las image_entities que extrajimos de Datastore como una variable.

@app.route('/')
def homepage():
    # Create a Cloud Datastore client.
    datastore_client = datastore.Client()

    # Use the Cloud Datastore client to fetch information from Datastore about
    # each photo.
    query = datastore_client.query(kind='Faces')
    image_entities = list(query.fetch())

    # Return a Jinja2 HTML template and pass in image_entities as a parameter.
    return render_template('homepage.html', image_entities=image_entities)

Analicemos cómo se guardan las entidades en Datastore. Datastore es la solución de base de datos NoSQL de Google Cloud. Los datos se almacenan en objetos llamados entidades. A cada entidad se le asigna una clave única de identificación, que se puede crear usando un tipo y una string de nombre de clave. Un tipo es un depósito de organización que designa el tipo de entidad que es. Por ejemplo, es posible que desee configurar tipos para fotos, personas y animales.

Cada entidad puede tener muchas propiedades definidas por el desarrollador, las cuales pueden tener valores de varios tipos, incluidos números enteros, flotantes, strings, fechas o datos binarios.

    # Create a Cloud Datastore client.
    datastore_client = datastore.Client()

    # Fetch the current date / time.
    current_datetime = datetime.now()

    # The kind for the new entity.
    kind = 'Faces'

    # The name/ID for the new entity.
    name = blob.name

    # Create the Cloud Datastore key for the new entity.
    key = datastore_client.key(kind, name)

    # Construct the new entity using the key. Set dictionary values for entity
    # keys blob_name, storage_public_url, timestamp, and joy.
    entity = datastore.Entity(key)
    entity['blob_name'] = blob.name
    entity['image_public_url'] = blob.public_url
    entity['timestamp'] = current_datetime
    entity['joy'] = face_joy

    # Save the new entity to Datastore.
    datastore_client.put(entity)

De manera similar a Datastore, se puede acceder a las bibliotecas cliente de Storage y Vision de forma programática. Puede abrir el archivo main.py usted mismo con vim, emacs o nano para explorar todo el código de muestra.

Más información sobre Flask en http://flask.pocoo.org/.

Obtén más información sobre las bibliotecas cliente en https://googlecloudplatform.github.io/google-cloud-python/.

Página principal.html

El marco de trabajo web de Flask aprovecha Jinja2 como un motor de plantillas. Esto nos permite pasar variables y expresiones de main.py a homepage.html que se reemplazan por valores cuando la página se procesa.

Obtenga más información sobre Jinja2 en http://jinja.pocoo.org/docs/2.9/templates/.

Esta plantilla HTML de Jinja2 muestra un formulario para que los usuarios envíen fotos a la base de datos. También muestra cada imagen que se envió antes junto con su nombre de archivo, hora y fecha de carga, y la probabilidad de que el rostro detectado por la API de Vision esté feliz.

homepage.html

<h1>Google Cloud Platform - Face Detection Sample</h1>

<p>This Python Flask application demonstrates App Engine Flexible, Google Cloud
Storage, Datastore, and the Cloud Vision API.</p>

<br>

<html>
  <body>
    <form action="upload_photo" method="POST" enctype="multipart/form-data">
      Upload File: <input type="file" name="file"><br>
      <input type="submit" name="submit" value="Submit">
    </form>
    
  </body>
</html>

El entorno flexible de App Engine utiliza un archivo llamado app.yaml para describir la configuración de implementación de una aplicación. Si falta ese archivo, App Engine intentará deducir la configuración de la implementación. Sin embargo, se recomienda proporcionar este archivo.

Luego, modificará app.yaml con el editor que desee. vim, nano o emacs. Usaremos el editor nano:

nano app.yaml

app.yaml

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
    python_version: 3

env_variables:
    CLOUD_STORAGE_BUCKET: <your-cloud-storage-bucket>

Esta es la configuración básica que se necesita para implementar una aplicación de Python 3 en el entorno flexible de App Engine. Obtenga más información para configurar App Engine aquí.

Cuando app.yaml esté abierto, reemplace < your-cloud-storage-bucket > por el nombre de su bucket de Cloud Storage. (Si olvidó el nombre de su bucket de Cloud Storage, copie el ID del proyecto de GCP de Qwiklabs, que es el mismo). La sección env_variables define las variables de entorno que se usarán en main.py cuando se implemente la aplicación.

Ahora puede guardar y cerrar el archivo en nano con (Ctrl + x), que mostrará lo siguiente:

Captura de pantalla del 2017-02-17 a las 4.47.12 PM.png

Escriba una letra y y, luego, presione la tecla ENTER una vez más para confirmar el nombre del archivo en el siguiente mensaje:

Captura de pantalla 24 de febrero de 2017 a las 4.18.23 p.m.png

Use gcloud para implementar su aplicación en App Engine:

gcloud app deploy

Después de implementar la aplicación, puede acceder a ella abriendo la URL https://< PROJECT_ID >.appspot.com en su navegador web.

Resumen

En este paso, configurarás una aplicación web de Python y la implementarás en el entorno flexible de App Engine.

Aprendió a escribir e implementar su primera aplicación web flexible de App Engine.

Limpieza

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud Platform por los recursos de esta guía de inicio rápido:

  • Ve a Cloud Platform Console.
  • Selecciona el proyecto que deseas cerrar y haz clic en "Delete" (Borrar). En la parte superior, se programa la eliminación del proyecto.

Más información

Licencia

Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.