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

Rafael K
9 min readOct 21, 2020

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

Material produzido para a Tera

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.

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 .
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.

Clique em ‘New’ para criar um novo repositório
Preencha com as opções desejadas.
Na aba inicial, seleciona ‘Add File’ e ‘Upload files’
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

Criando um novo aplicativo web
Escolhendo o nome e região
Selecione o GitHub como método de implemnetação
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.

Clique em “Deploy Branch” e aguarde alguns minutos

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

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.

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.

É 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

--

--