TL;DR
O Streamlit é uma ótima ferramenta para criar belos aplicativos data com bastante facilidade, mas quando se trata de implantá-los e torná-los acessíveis, isso pode ser mais complicado para quem não é especialista. Neste artigo, pretendemos apresentar nossa jornada para implantar nosso aplicativo no GCP, garantindo um acesso restrito a pessoas específicas. Implementamos duas soluções: uma com o Cloud Run e a outra com o App Engine, e optamos por manter o App Engine pela facilidade de proteger o aplicativo com o IAP (Identity-Aware Proxy).

Média Blog por Artefact.

Este artigo foi publicado inicialmente no Medium.com.
Siga-nos em nosso Medium Blog !

Motivações para a implantação

Neste artigo, usaremos o exemplo do Text Data Explorer, um aplicativo Streamlit que desenvolvemos com o objetivo de fornecer insights sobre o texto bruto data em poucos minutos e poucos cliques. Esse aplicativo será apresentado em um artigo futuro.

Example of the app that will be deployed on GCP

Exemplo do aplicativo que será implantado no GCP

Há duas opções principais para iniciar esse aplicativo e esse processo:

  • Ou o usuário clona o repositório do GitHub em seu computador, instala todas as dependências e inicia o aplicativo em um ambiente local.

  • Ou o usuário tem acesso direto ao aplicativo usando um URL dedicado sem nenhuma instalação prévia.

Para disponibilizar o aplicativo para o maior número de pessoas em nossa empresa e, portanto, para pessoas que não estão necessariamente acostumadas a lidar com o GitHub, decidimos implantar o aplicativo no GCP (Google Cloud Platform) e torná-lo acessível por meio de um único URL em um ambiente seguro.

Implementação passo a passo no GCP

Duas abordagens diferentes foram testadas para implantar o aplicativo no GCP:

  • Usando o Cloud Run

  • Usando o App Engine

No entanto, há uma etapa preliminar comum que diz respeito a essas duas abordagens, que consiste na “dockerização” do nosso aplicativo.

Dockerização do aplicativo

Se o senhor não estiver familiarizado com o Docker, aqui está uma pequena introdução, mas não hesite em dar uma olhada no documentação ou artigos mais específicos para obter mais detalhes.

O que é docker?

O Docker é uma plataforma aberta para desenvolvimento, envio e execução de aplicativos. Ele permite que o senhor empacote um aplicativo com todas as suas dependências em uma unidade padronizada para o desenvolvimento de software. Na prática, isso envolve a criação do que é chamado de imagem do Docker, ou seja, os projetos do aplicativo que formam a base dos contêineres do Docker, o conteúdo em repouso. Para criar essa imagem, precisamos definir um Dockerfile, ou seja, um arquivo de texto simples que contém uma lista de comandos que o cliente Docker chama ao criar uma imagem. Depois de criada, a imagem é armazenada em um registro (por exemplo, Container Registry no GCP) e pode ser implementada em uma instância dedicada, por meio do Cloud Run ou do App Engine, por exemplo.

Portanto, em nosso caso, temos de fazê-lo:

  • Criar um Dockerfile

  • Criar nossa imagem do aplicativo

  • Armazenar a imagem em um registro

Vamos começar com a criação do Dockerfile. Conforme mencionado anteriormente, ele consiste em uma sucessão de comandos usados para criar a imagem do Docker. No caso de um aplicativo Streamlit, o Dockerfile pode ser dividido em vários blocos:

  • Definir o ambiente de tempo de execução: no nosso caso, python 3.7

  • Definir a porta na qual o aplicativo será executado

  • Instale as bibliotecas necessárias e suas dependências usando um arquivo requirements.txt

  • Copie o código de seu aplicativo e defina o diretório de trabalho a partir do qual o aplicativo será iniciado

  • Definir o comando para executar o aplicativo

├── app.py <- Script principal para iniciar o aplicativo Streamlit
├── text_explorer <- Pasta que reúne todas as funções e códigos
├── requirements.txt <- Arquivo que lista as bibliotecas necessárias para a instalação
└── Referências <- Pasta contendo logotipos e imagens

Com essa estrutura, aqui está um exemplo do Dockerfile que usamos para nosso aplicativo:

DE python:3.7

# Exponha a porta em que o senhor deseja que seu aplicativo esteja
EXPOSE 8080

Requisitos de instalação e pip de upgrade do #
COPY requirements.txt requirements.txt
Executar pip install -U pip
RUN pip install -r requirements.txt

# Copiar o código do aplicativo e definir o diretório de trabalho
COPY text_explorer text_explorer
COPY app.py app.py
COPY referências referências
WORKDIR .

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

Depois que o Dockerfile for criado, poderemos construir nossa imagem, seguindo uma convenção de nomenclatura amigável ao GCP que será útil para a implantação mais tarde. Isso é feito com o seguinte comando:

docker build -t eu.gcr.io/gcp_project_name/app_name:v1 .

Para adaptá-lo ao seu próprio aplicativo, substitua o ‘gcp_project_name’ por seu próprio nome de projeto GCP e o símbolo ‘nome_do_aplicativo’ pelo nome do seu próprio aplicativo. O senhor também pode atualizar o número da versão à medida que seu aplicativo evolui, modificando o parâmetro ‘v1’ com sua versão atual.

A partir daí, com nosso aplicativo empacotado em uma imagem do docker, podemos implantá-lo no GCP para torná-lo acessível aos nossos colegas de equipe.

Implemente seu aplicativo com o Cloud Run

O Cloud Run é um serviço cloud sem servidor do GCP usado para implementar facilmente aplicativos pré-criados. Uma de suas principais vantagens é que ele automatiza a maior parte do processo de gerenciamento de recursos. Portanto, tudo o que o senhor precisa fazer é informar ao Cloud Run onde está sua imagem do Docker e, em seguida, o Cloud Run a implantará em um ambiente sem servidor sem a necessidade de especificar o número ideal de recursos, por exemplo.

Para fazer isso, o senhor pode seguir as etapas listadas abaixo:

  • Inicializar gcloud no projeto GCP correto com o seguinte comando:

gcloud init

  • Envie a janela de encaixe para o Registro de contêineres do GCP com o seguinte comando:
docker push eu.gcr.io/gcp_project_name/app_name:v1
  1. Vá para o seu projeto do GCP, na seção Execução na nuvem. Clique em “Create service” (Criar serviço), escolha a região e defina o nome do serviço. Em seguida, selecione a imagem do Docker que corresponde ao seu aplicativo Streamlit e atualize a porta com a que você definiu no seu Dockerfile

Interface do Cloud Run

  • Por fim, o senhor pode testar seu aplicativo seguindo o URL vinculado ao serviço Cloud Run recém-criado

Como o senhor pode ver, a implementação é feita em apenas algumas etapas e é bastante fácil, mesmo para iniciantes na implementação de aplicativos. No entanto, no nosso caso, além da implementação, também queríamos proteger nosso aplicativo para que ele só pudesse ser acessado dentro da nossa empresa e, naquele momento, não encontramos nenhuma solução “fácil” que se encaixasse no Cloud Run. Por isso, decidimos procurar uma solução alternativa que nos permitisse ter essa camada de segurança sem muita dificuldade e, por fim, acabamos optando pelo App Engine.

Implante seu aplicativo com o App Engine

O App Engine é um serviço de computação baseado no cloud usado para hospedar aplicativos da Web que já estão na infraestrutura do Google. Em resumo, ele permite que o senhor faça a mesma coisa que o Cloud Run, no sentido de que ambos são serviços cloud do Google que permitem a implantação de aplicativos. No entanto, ao contrário do Cloud Run, em que o usuário paga apenas pelas solicitações recebidas, no App Engine o usuário paga por todo o tempo de execução, independentemente de haver solicitações ou não. Portanto, no final, o App Engine pode ser uma solução mais cara. Apesar disso, ainda decidimos optar por essa solução porque o App Engine tem a vantagem de ter uma integração nativa com o IAP (Identity-Aware Proxy), que permite proteger facilmente o aplicativo.

As etapas para realizar uma implantação no App Engine não são mais numerosas nem mais complicadas do que no Cloud Run:

  • Verifique a porta especificada em seu Dockefile, que deve ser 8080 para ser compatível com o App Engine
  • Inicialize o módulo gcloud no projeto GCP correto com o seguinte comando:
gcloud init
  • Crie um arquivo YAML para o seu aplicativo (chamado app.yaml) na raiz do seu projeto (ou seja, no mesmo nível do seu script principal e do seu Dockerfile) com o seguinte modelo:

app.yaml file exampleExemplo de arquivo app.yaml

Atualize o nome do serviço com seu próprio nome de serviço de aplicativo

Aqui definimos a opção runtime: custom porque os runtimes personalizados permitem que o senhor crie aplicativos que são executados em um ambiente definido por um Dockerfile, como é o nosso caso. A opção env:flex significa que nosso aplicativo será executado no ambiente flexível (em oposição ao ambiente padrão). Essa escolha foi feita porque o ambiente flexível executa o aplicativo em contêineres do Docker em máquinas virtuais (VMs) do Google Compute Engine, que têm menos restrições do que no ambiente padrão (por exemplo, seu aplicativo não pode gravar no disco). Mais detalhes sobre as principais diferenças estão disponíveis na documentação do Google.

O senhor também pode incluir configurações mais detalhadas de rede, recursos e dimensionamento no arquivo YAML, como o número mínimo de instâncias fornecidas ao seu serviço ou o número de CPUs, por exemplo. O senhor também pode definir algumas variáveis de ambiente nesse arquivo para torná-las acessíveis ao seu aplicativo.

  • Execute o seguinte comando (isso pode levar vários minutos):
gcloud implantação do aplicativo app.yaml
  • Depois de concluir o comando de implantação, o aplicativo estará disponível no App Engine e o senhor encontrará o URL dedicado diretamente no GCP

Se quiser proteger seu aplicativo e dar acesso restrito a algumas pessoas, acesse seu projeto GCP, na seção “IAM & Admin” / “Identity-Aware Proxy”:

  • Em “All Web Services”, o senhor deve ver uma seção “App Engine app”. Se o IAP estiver desativado, ative-o e clique em seu serviço Streamlit.

Seções do IAP para gerenciar permissões

  • À direita, clique em “Add member” (Adicionar membro), insira todos os endereços de e-mail desejados (ou um alias vinculado a uma lista de discussão) e selecione a função “IAP-secured Web App User” (Usuário de aplicativo da Web protegido por IAP).

E o senhor terminou. Seu aplicativo agora está implementado e protegido.

Dicas se o senhor tiver problemas com a exibição de imagens em seu aplicativo implantado

Ao usar st.pyplot() ou st.image(), o senhor pode encontrar alguns problemas de exibição ao olhar para o aplicativo implantado (ou seja, “0” exibido em vez do gráfico ou da imagem). Recomendamos que o senhor use st.plotly_chart() sempre que possível para evitar isso e, caso contrário, use trechos de código HTML. Por exemplo, em nosso caso, queríamos exibir algumas wordclouds e isso não poderia ser feito com o Plotly. Assim, decidimos salvar a imagem wordcloud como PNG em um bucket GCS dedicado, baixá-la como bytes e exibi-la com algum código HTML como este:

def display_wordcloud(image):
st.markdown(
f"""

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

Nesse exemplo, a variável “image” é um objeto de bytes proveniente do método .dowload_as_bytes() do pacote python de armazenamento do Google cloud.

Conclusão

O objetivo deste artigo foi dar aos senhores algumas dicas e exemplos de serviços cloud que podem ser usados para a implementação de aplicativos Streamlit. De acordo com nossa experiência, se o senhor precisar de uma camada de segurança para garantir acesso restrito a algumas pessoas, o App Engine será a solução adequada. Caso contrário, o Cloud Run continua sendo uma maneira fácil de implementar um aplicativo Streamlit.

Créditos: Paul Devienne, Amale El Hamri