TL;DR
Streamlit es una gran herramienta para crear hermosas aplicaciones data con bastante facilidad, pero cuando se trata de desplegarlas y hacerlas accesibles, puede resultar más complicado para los no especialistas. En este artículo pretendemos presentar nuestro viaje para desplegar nuestra aplicación en GCP asegurando un acceso restringido a personas concretas. Implementamos dos soluciones: una con Cloud Run, la otra con App Engine y optamos por quedarnos con App Engine por su facilidad para asegurar la aplicación con IAP (Identity-Aware Proxy).

Medio Blog por Artefact.

Este artículo se publicó inicialmente en Medium.com.
¡Síganos en nuestro Medium Blog !

Motivaciones para el despliegue

En este artículo, tomaremos como ejemplo el Explorador de texto Data, una aplicación Streamlit que hemos desarrollado con el objetivo de proporcionar información sobre el texto bruto data en pocos minutos y con unos pocos clics. Esta aplicación se presentará en un próximo artículo.

Example of the app that will be deployed on GCP

Ejemplo de la app que se desplegará en GCP

Existen dos opciones principales para poner en marcha esta aplicación y este proceso:

  • O bien el usuario clona el repositorio de GitHub en su ordenador, instala todas las dependencias y lanza la aplicación en un entorno local.

  • O el usuario tiene acceso directo a la aplicación mediante una URL dedicada sin ninguna instalación previa.

Para poner la aplicación a disposición del mayor número de personas dentro de nuestra empresa, y por tanto de personas que no están necesariamente acostumbradas a tratar con GitHub, hemos decidido desplegar la aplicación en GCP (Google Cloud Platform) y hacerla accesible a través de una única URL en un entorno seguro.

Despliegue paso a paso en GCP

Se han probado dos enfoques diferentes para desplegar la aplicación en GCP:

  • Uso de Cloud Run

  • Uso de App Engine

Sin embargo, existe un paso preliminar común a ambos enfoques que consiste en la “dockerización” de nuestra aplicación.

Dockerización de la aplicación

Si no está familiarizado con Docker, aquí tiene una pequeña introducción, pero no dude en consultar el documentación o artículos más específicos para más detalles.

¿Qué es docker?

Docker es una plataforma abierta para desarrollar, enviar y ejecutar aplicaciones. Permite empaquetar una aplicación con todas sus dependencias en una unidad estandarizada para el desarrollo de software. En la práctica, esto implica construir lo que se denomina una imagen Docker, es decir, los planos de la aplicación que forman la base de los contenedores Docker, el contenido en reposo. Para construir esta imagen, necesitamos definir un Dockerfile, es decir, un simple archivo de texto que contiene una lista de comandos que el cliente Docker llama al crear una imagen. Una vez construida, la imagen se almacena en un registro (por ejemplo, Container Registry en GCP) y puede desplegarse en una instancia dedicada, a través de Cloud Run o App Engine, por ejemplo.

Por lo tanto, en nuestro caso tenemos que hacerlo:

  • Crear un Dockerfile

  • Construir la imagen de nuestra aplicación

  • Almacenar la imagen en un registro

Comencemos con la creación del Dockerfile. Como ya se ha mencionado, consiste en una sucesión de comandos utilizados para crear la imagen Docker. En el caso de una aplicación Streamlit, el Dockerfile puede dividirse en varios bloques:

  • Definir el entorno de ejecución: en nuestro caso python 3.7

  • Defina el puerto en el que se ejecutará la aplicación

  • Instale las bibliotecas necesarias y sus dependencias utilizando un archivo requirements.txt

  • Copie el código de su aplicación y defina el directorio de trabajo desde el que se lanzará la aplicación

  • Defina el comando para ejecutar la aplicación

├── app.py <- Script principal para lanzar la aplicación Streamlit.
├── text_explorer <- Carpeta que reúne todas las funciones y el código.
├── requirements.txt <- Archivo que enumera las bibliotecas necesarias para instalar
Referencias └── <- Carpeta que contiene logotipos e imágenes.

Con esta estructura, he aquí un ejemplo del Dockerfile que utilizamos para nuestra aplicación:

DESDE python:3.7

# Exponga el puerto en el que desea su aplicación
EXPONER 8080

# Actualización pip y requisitos de instalación
COPIAR requisitos.txt requisitos.txt
EJECUTE pip install -U pip
EJECUTE pip install -r requisitos.txt

# Copie el código de la aplicación y establezca el directorio de trabajo
COPIAR texto_explorador texto_explorador
COPIA app.py app.py
COPIAR referencias referencias
DIRECTORIO DE TRABAJO .

Carrera #
ENTRYPOINT [“streamlit”, “run”, “app.py”, “-server.port=8080”, “-server.address=0.0.0.0”].

Una vez creado el Dockerfile, podemos construir nuestra imagen, siguiendo una convención de nomenclatura amigable para GCP que será útil para el despliegue más adelante. Esto se hace mediante el siguiente comando:

docker build -t eu.gcr.io/gcp_nombre_del_proyecto/nombre_de_la_app:v1 .

Para adaptarlo a su propia aplicación, sustituya el carácter ‘gcp_project_name’ por el nombre de su propio proyecto GCP y el símbolo ‘nombre_de_la_aplicacion’ por el nombre de su propia aplicación. También puede actualizar el número de versión a medida que evolucione su aplicación modificando el campo ‘v1’ con su versión actual.

A partir de ahí, con nuestra aplicación empaquetada en una imagen Docker, podemos desplegarla en GCP para hacerla accesible a nuestros compañeros de equipo.

Despliegue su aplicación con Cloud Run

Cloud Run es un servicio cloud sin servidor de GCP que se utiliza para desplegar fácilmente aplicaciones preconstruidas. Una de sus principales ventajas es que automatiza la mayor parte del proceso de gestión de recursos. Por lo tanto, todo lo que tiene que hacer es decirle a Cloud Run dónde está su imagen Docker, y entonces Cloud Run la desplegará en un entorno sin servidor sin necesidad de especificar el número óptimo de recursos, por ejemplo.

Para ello, puede seguir los pasos que se indican a continuación:

  • Inicialice gcloud módulo en el proyecto GCP correcto con el siguiente comando:

gcloud init

  • Empuje el docker al Registro de Contenedores de GCP con el siguiente comando:
docker push eu.gcr.io/gcp_nombre_del_proyecto/nombre_de_la_app:v1
  1. Vaya a su proyecto GCP, en la sección “Cloud run”. Haga clic en "Crear servicio", elija la región y defina el nombre de su servicio. A continuación, seleccione la imagen Docker que corresponda a su aplicación Streamlit y actualice el puerto con el que definió en su Dockerfile

Interfaz Cloud Run

  • Por último, puede probar su aplicación siguiendo la URL vinculada al servicio Cloud Run recién creado

Como puede ver, el despliegue se realiza en unos pocos pasos y resulta bastante sencillo, incluso para los recién llegados al despliegue de aplicaciones. Sin embargo, en nuestro caso, además del despliegue, también queríamos asegurar nuestra aplicación para que sólo fuera accesible dentro de nuestra empresa y, en ese momento, no encontramos ninguna solución “fácil” que encajara con Cloud Run. Por eso decidimos buscar una solución alternativa que nos permitiera tener esta capa de seguridad sin demasiada dificultad y finalmente acabamos con App Engine.

Despliegue su aplicación con App Engine

App Engine es un servicio informático basado en cloud que se utiliza para alojar aplicaciones web que ya se encuentran en la infraestructura de Google. En pocas palabras, le permite hacer lo mismo que Cloud Run en el sentido de que ambos son servicios cloud de Google que le permiten desplegar aplicaciones. Sin embargo, a diferencia de Cloud Run, donde sólo se paga por las solicitudes que llegan, en App Engine se paga por todo el tiempo de ejecución, haya o no solicitudes. Por lo tanto, al final, App Engine puede ser una solución más cara. A pesar de ello, nos decidimos por esta solución porque App Engine tiene la ventaja de contar con una integración nativa con IAP (Identity-Aware Proxy) que permite asegurar fácilmente su aplicación.

Los pasos para conseguir un despliegue en App Engine no son más numerosos ni más complicados que para Cloud Run, esto es lo que tiene que hacer:

  • Compruebe el puerto especificado en su Dockefile, tiene que ser 8080 para ser compatible con App Engine
  • Inicialice el módulo gcloud en el proyecto GCP derecho con el siguiente comando:
gcloud init
  • Cree un archivo YAML para su aplicación (denominado app.yaml) en la raíz de su proyecto (es decir, al mismo nivel que su script principal y su Dockerfile) con la siguiente plantilla:

app.yaml file exampleejemplo de archivo app.yaml

Actualice el nombre del servicio con su propio nombre de servicio de aplicación

Aquí definimos la opción runtime: custom porque los runtimes personalizados le permiten construir aplicaciones que se ejecutan en un entorno definido por un Dockerfile como es nuestro caso. La opción env:flex significa que nuestra aplicación se ejecutará en el entorno flexible (por oposición al entorno estándar). Esta elección se debe a que el entorno flexible ejecuta la aplicación en contenedores Docker en máquinas virtuales (VM) de Google Compute Engine, que tienen menos restricciones que en el entorno estándar (por ejemplo, su aplicación no puede escribir en disco). Encontrará más detalles sobre las principales diferencias en la documentación de Google.

También puede incluir ajustes más detallados de red, recursos y escalado dentro del archivo YAML, como el número mínimo de instancias que se le da a su servicio o el número de CPU, por ejemplo. También puede definir algunas variables de entorno en ese archivo para que sean accesibles a su aplicación.

  • Ejecute el siguiente comando (puede tardar varios minutos):
gcloud app deploy app.yaml
  • Una vez realizado el comando deploy, la aplicación estará disponible en App Engine y encontrará su URL dedicada directamente en GCP

Si desea asegurar su aplicación y dar un acceso restringido a algunas personas, vaya a su proyecto GCP, en la sección “IAM & Admin” / “Identity-Aware Proxy”:

  • En “Todos los servicios web” debería ver una sección “App Engine app”. Si IAP está desactivado, actívelo y haga clic en su servicio Streamlit.

Secciones IAP para gestionar los permisos

  • A la derecha, haga clic en “Añadir miembro”, introduzca todas las direcciones de correo electrónico que desee (o un alias vinculado a una lista de correo) y seleccione el rol “IAP-secured Web App User”.

Y ya está. Su aplicación ya está desplegada y asegurada.

Consejos si tiene problemas con la visualización de imágenes en su aplicación desplegada

Cuando utilice st.pyplot() o st.image(), puede encontrarse con algunos problemas de visualización al ver su aplicación desplegada (es decir, que aparezca “0” en lugar de su gráfico o imagen). Le recomendamos utilizar st.plotly_chart() siempre que pueda para evitarlo y utilizar fragmentos de código HTML en caso contrario. Por ejemplo, en nuestro caso, queríamos visualizar algunas wordcloud y eso no podía hacerse con Plotly. Así que decidimos guardar la imagen wordcloud como PNG en un cubo GCS dedicado, descargarla como bytes y mostrarla con algún código HTML como este:

def mostrar_palabracloud(imagen):
st.markdown(
f"""

""",
unsafe_allow_html=Verdadero
)
st.markdown("")
st.markdown("")

En ese ejemplo, la variable “imagen” es un objeto bytes procedente del método .dowload_as_bytes() del paquete python de almacenamiento Google cloud.

Conclusión

El objetivo de este artículo era ofrecerle algunos consejos y ejemplos de servicios cloud que pueden utilizarse para desplegar aplicaciones Streamlit. Según nuestra experiencia, si necesita una capa de seguridad para garantizar el acceso restringido a algunas personas, App Engine será la solución adecuada. De lo contrario, Cloud Run sigue siendo una forma sencilla de desplegar una aplicación Streamlit.

Créditos: Paul Devienne, Amale El Hamri