Streamlit 101: o básico para colocar seu projeto no ar

Palavras chaves: Streamlit, deployment, modelo em produção, GitHub, Heroku, projeto no ar

Material produzido para a Tera

Image for post
Image for post

Depois de gastar horas e horas no desenvolvimento de seu projeto de Ciência de Dados, você provavelmente deve ter se deparado com mais um obstáculo: como mostrar o valor do seu trabalho e fazer com que seu projeto possa ser utilizado por qualquer pessoa, independente de seu conhecimento técnico de programação?

Este artigo vai ensinar na prática como utilizar o básico do Streamlit, GitHub e Heroku para criar uma interface interativa de seu projeto e disponibilizá-lo na internet.

Image for post
Image for post
Photo by Bill Jelen on Unsplash

Conceitos Iniciais

É tão importante assim colocar o projeto no ar? Parece ser mais fácil simplesmente compartilhar o resultado final.

De fato, enviar um slide ou um relatório pode ser feito em alguns cliques. Contudo, é importante ressaltar que nem sempre as pessoas sabem o que querem. Quantas vezes você já se deparou em uma situação onde foi necessário executar seu modelo inúmeras vezes a fim de atender as expectativas?

Você depois do milésimo ajuste no modelo

Ao oferecer uma solução que seja acessível e de fácil entendimento, o usuário ganha autonomia para explorar suas possibilidades e tirar suas próprias conclusões. Isso é valioso porque, ao invés de simplesmente oferecer um resultado estático, a solução colocada no ar pode ser customizada pelo usuário de acordo com sua preferência.

Transformar o projeto em uma solução intuitiva e simples é uma habilidade importante para pessoas que trabalham com Ciência de Dados. É com essa proposta que o Streamlit vem ganhando popularidade no cenário atual.

O que é o Streamlit?

O Streamlit é uma biblioteca de código aberto do Python que foi criada especificamente para o desenvolvimento de aplicativos web baseados em modelos de Machine Learning. A biblioteca permite criar elementos gráficos interativos em poucas linhas de código.

Uma das vantagens da ferramenta é que ela dispensa o domínio técnico de Front-End, ou seja, é possível criar aplicativos web mesmo sem saber HTML, CSS ou JavaScript.

O site oficial do Streamlit contém casos reais de aplicativos web, como o Udacity Self-driving Car Image Browser e Uber Pickups in New York City.

OK, como começar?

Como todas as outras bibliotecas: primeiro instalando e depois entendendo como utilizar suas funcionalidades.

pip install streamlit
streamlit hello
Agora sim, vamos começar

Estruturas básicas

Dentre as diversas funcionalidades do Streamlit, é possível apontar uma série de elementos básicos que podem ser usados na maioria das aplicações web: a barra lateral, textos, tabelas, objetos interativos, gráficos e imagens.

Para facilitar o entendimento sobre essas estruturas básicas, é recomendado que você faça a leitura abaixo acompanhando este link, que contém exemplos dessas estruturas na interface do Streamlit.

Barra lateral

Talvez a estrutura mais comum de qualquer projeto em Streamlit, a barra lateral serve como um menu e concentra os elementos principais que são relevantes em qualquer momento da solução, seja no início, meio ou fim.

Nos exemplo, a barra lateral encontra-se logo à esquerda e contém uma caixa de seleção da categoria. Esse recurso é criada pelo comando streamlit.sidebar e, normalmente, é combinado com outras estruturas. Em nosso caso, o código utilizado foi st.sidebar.selectbox('Escolha a espécie a ser visualizada')

Textos

Os textos podem ser diferenciados por tamanho da fonte e formatação:

import streamlit as st#Diferentes tamanhos de texto
st.title('Isso é um título')
st.header('Isso é um cabeçalho')
st.subheader('Isso é um subcabeçalho')
st.text('Isso é um texto normal')
#formatação
st.markdown('Texto em **negrito** ou _itálico_')
#Utilização para guardar html
st.markdown('[Isso é um texto com html](https://docs.streamlit.io/en/stable/api.html#display-text)',False)

Tabelas

É possível apresentar dados em tabelas interativas ou em tabelas estáticas. Apesar da tabela interativa permitir a ordenação de colunas, a tabela fixa carrega uma layout mais harmônico.

import pandas as pd
import numpy as np
#gerando um dataframe aleatório
df = pd.DataFrame(
np.random.randn(15,10),
columns=('col_%d' % i for i in range(10))
)
#tabelas interativas
st.dataframe(df)
#tabelas fixas
st.table(df)

Objetos interativos

Essa categoria representa um dos principais motivos pelo qual o Streamlit é considerado uma ferramenta altamente versátil. Os objetos interativos são os meios de interação entre a solução e os usuários, servido para definir desde os parâmetros específicos de modelos, as variáveis a compor o modelo ou mesmo as janelas temporais utilizadas nas amostras.

Dentre as diversas funcionalidades, é possível implementar desde botões,…

#Botão
if st.button('Gerar número aleatório'):
st.write(randint(0, 1000000))
else:
st.write('Clique no botão acima')
#Radio
chute = st.radio(
"por que essa função se chama radio?",
('Opção 1: porque o rádio é um osso muito bonito',
'Opção 2: é uma homenagem à Marie Curie',
'Opção 3: as opções lembram botões de rádio')
)
if chute == 'as opções lembram botões de rádio':
st.write('Correto!')
else:
st.write("Incorreto, tente novamente.")

…barras de arraste, …

#Barra de arraste
bar = st.slider('Isso é um slider',
min_value=0,
max_value=10,
value=5,
step=1)
st.write("você selecionou: ",bar)

…caixas de seleção e…

#caixa de multiseleção
#obs.: utilizando o dataframe criado anteriormente
cx_mult = st.multiselect(
'Selecione as colunas abaixos',
df.columns
)
st.dataframe(df[cx_mult])

…a possibilidade do usuário inserir seus próprios dados.

#input de números
input_num = st.number_input(
'Escreva um número entre 0 e 10',
min_value = 0,
max_value = 10,
value = 0,
step = 1
)
st.write('O número inputado foi: ', input_num)
#input de texto
input_txt = st.text_input(
'Escreva uma palavra com até 5 letras',
value = 'juiz',
max_chars = 5
)
st.write('A palavra inputada foi: ', input_txt)

Gráficos

E o que seriam de soluções de Ciência de Dados sem gráficos?

#vamos aproveitar o dataframe criado anteriormente
df2 = pd.DataFrame(df, columns=['col_0','col_1','col_2'])
#exemplo de gráfico
st.area_chart(df2)

Adicionalmente aos gráficos da própria biblioteca, o Streamlit também permite a integração com a biblioteca Plotly. A única diferença é a necessidade da inclusão de uma estrutura específica, o st.plotly_chart() . O exemplo utiliza o código abaixo:

#dataset de iris do sklearn
df = px.data.iris()
#lista de possíveis especies
lista_especie = ('setosa','versicolor','virginica')
#caixa de seleção à esquerda
var_especie = st.sidebar.selectbox(
'Escolha a espécie a ser visualizada',
lista_especie
)
#dicionários de cores a serem visualizadas no gráficos
dict_flor={
lista_especie[0]:'blue',
lista_especie[1]:'red',
lista_especie[2]:'green'
}
#gráfico 3D gerado a partir do plotly
fig = go.Figure(
data=go.Scatter3d(
x=df['sepal_length'],
y=df['sepal_width'],
z=df['petal_width'],
mode='markers',
marker=dict(
size=4,
color=np.where(
df['species'] == var_especie,
dict_flor[var_especie],
'lightgray'
)
)
)
)
st.plotly_chart(fig)

Mídias

Por fim, fotos, vídeos ou áudios podem ser instrumentos eficientes de se comunicar um conceito complexo. Segue um exemplo de como incluir uma imagem no Streamlit:

from PIL import Imagefoto = Image.open('foto.png')st.image(foto,
caption='Logo do Streamlit',
use_column_width=False)

Legal, mas essa foto está desalinhada. Não há como centralizar essas estruturas?

Essa limitação do Streamlit persistiu por muito tempo, porém, felizmente, os desenvolvedores ouviram as sugestões da comunidade e estão buscando auma solução definitiva nesse exato momento (literalmente, pois recebi essa atualização pela newletter do Streamlit a alguns dias atrás).

Uma solução desenvolvida foi o st.beta_columns(). Essa funcionalidade divide a interface da página em colunas. Para centralizar uma imagem, portanto, basta dividir nossa interface em três colunas e utilizar a do meio.

#criando 3 colunas 
col1, col2, col3 = st.beta_columns(3)
foto = Image.open('foto.png')#inserindo na coluna 2
col2.image(foto, use_column_width=True)

Disclaimer: no momento de produção deste material, a estrutura acima encontra-se em fase beta. Recomenda-se a verificação na documentação oficial da biblioteca antes de sua utilização.

Bônus

Já deu para perceber que o Streamlit carrega uma vasta coletânea de estruturas. E por esse mesmo motivo, é comum se confundir em relação a sintaxe.

Pensando nisso, foi criada uma estrutura coringa (os próprios desenvolvedores se referem a ela como swiss-army knife): ost.write() .

O negócio é tão bom que até ele gostou
#precisa escrever o texto? Beleza
st.write('hola!')
#quer mostrar a tabela? Não tem problema
st.write(df)
#aguenta gráficos? Tranquilo
st.write(plotlyfigure)
#e muito mais...

Executando o Streamlit

Acabei de montar meu código com as estruturas do Streamlit. E agora?

Após salvar seu arquivo com a extensão .py (por exemplo: app.py), é necessário executar o mesmo com o Streamlit via terminal de comando.

Abra seu terminal e localize a pasta raiz de seu script. Se for necessário, veja esse tutorial sobre comandos básicos no terminal.

streamlit run app.py 

Uma aba de seu navegador deve ter sido aberto com o aplicativo web. Caso contrário, basta acessar a URL disponibilizada no terminal.

Colocando no ar

Uma vez o script rodou, o próximo passo é colocá-lo no ar. Para isso utilizaremos o GitHub e o Heroku. Também será necessário criar três arquivos complementares: o “setup.sh”, o “requirements.txt” e o “Procfile” (sem extensão).

Definições iniciais (glossário)

  • GitHub: plataforma colaborativa que oferece controle de versão. Será utilizado para armazenarmos os arquivos em nuvem.
  • Heroku: serviço de implementação e administração de aplicativos web. Será utilizado para o deploy (i.e. “colocar no ar”).

Passo-a-passo

Passo 1: crie o documento setup.sh contendo o código abaixo de configuração das portas de conexão do Streamlit.

mkdir -p ~/.streamlit/echo "\
[server]\n\
port = $PORT\n\
enableCORS = false\n\
headless = true\n\
\n\
" > ~/.streamlit/config.toml

Passo 2: crie o documento Procfile (sem extensão) contendo o código abaixo a ser instruído ao aplicativo web durante a implementação:

web: sh setup.sh && streamlit run app.py

Passo 3: crie o documento requirements.txt contendo as bibliotecas e versões utilizadas no projeto. É possível fazê-lo manualmente ou pelo terminal:

pip install pipreqs#localize a pasta raiz
pipreqs --force .
Image for post
Image for post
Exemplo da pasta raiz do projeto

A pasta raiz do projeto deverá conter, além dos arquivos necessários ao projeto, o script e os três arquivos: Procfile, requirements.txt e setup.sh.

Passo 4: crie um novo repositório no GitHub e carregue com todos os arquivos.

Image for post
Image for post
Clique em ‘New’ para criar um novo repositório
Image for post
Image for post
Preencha com as opções desejadas.
Image for post
Image for post
Na aba inicial, seleciona ‘Add File’ e ‘Upload files’
Image for post
Image for post
Adicione seus arquivos no repositório

Embora o GitHub aceite arquivos com até 100MB, a funcionalidade de ‘arrasta-e-solta’ disponibilizada para o navegador funciona apenas para arquivos com menos de 25MB. Portanto, arquivos acima de 25MB deverão ser carregados no GitHub via terminal.

Passo 5: crie um novo aplicativo no Heroku, selecione o GitHub como método de implementação e atribua o repositório previamente no GitHub

Image for post
Image for post
Criando um novo aplicativo web
Image for post
Image for post
Escolhendo o nome e região
Image for post
Image for post
Selecione o GitHub como método de implemnetação
Image for post
Image for post
Preencha com o nome do repositório ou clique em “Search” e escolha

Passo 6: escolhe seu método de implementação e, finalmente, deploy.

Image for post
Image for post
Clique em “Deploy Branch” e aguarde alguns minutos

Passo 7: verifique se a implementação foi bem sucedida.

Image for post
Image for post
Agora é a hora da verdade

Parabéns! Você está oficialmente capacitado a implementar suas soluções na internet e permitir seu acesso a milhares de usuários ao redor do mundo.

Conclusão

Este artigo abordou uma maneira de permitir que notebooks sejam transformados em soluções acessíveis. Utilizando-se do framework do Streamlit para aplicações web, é possível criar uma interface de seu projeto em questões de horas.

E, repare, durante o processo não foi preciso escrever uma linha sequer de HTML ou JavaScript. Sem qualquer conhecimento de Front-End, criamos uma solução web altamente interativa e prática.

Os arquivos utilizados para a produção deste artigo encontram-se neste link.

FAQ

Meu Streamlit resultou em erro quando eu o executei localmente.

Image for post
Image for post
Exemplo de erro comum ao executar o Streamlit

O Streamlit indica em qual linha do código ele “engasgou”. No exemplo, o problema ocorreu na linha 104.

Basta revisar o código, salvar o arquivo e atualizar o navegador (Ctrl+R ou F5, por padrão).

A implementação não deu certo. Essa imagem de erro apareceu no navegador.

Image for post
Image for post

É necessário verificar se o problema está no script ou no conjunto de arquivos complementares (i.e. setup.sh, requirements.txt e Procfile).

A sugestão é avaliar os arquivos complementares primeiro, e caso o problema persistir, avaliar o script.

Para resolver problemas no script, é necessário avaliar os logs da implementação. Existem duas maneiras de se fazer isso: via logs disponíveis no próprio site do Heroku ou via terminal com o Heroku CLI. Para usar o Heroku CLI:

pip install herokuheroku logs --tail --app (substituir essa observação, incluindo o parênteses, pelo nome do aplicativo)

Exemplo: heroku logs --tail --app app-artigo-streamlit

Para saber mais

Currently, a data student.