Skip to content

Introdução ao Streamlit e Caching

Streamlit é uma biblioteca open-source em Python que permite aos desenvolvedores criar aplicações web interativas e amigáveis para projetos de aprendizado de máquina e ciência de dados. É projetado para ajudar cientistas de dados e engenheiros a transformar scripts de dados em aplicativos web compartilháveis, com apenas algumas linhas de código, sem a necessidade de habilidades de desenvolvimento front-end.

Caching, por outro lado, é uma técnica usada em computação para armazenar dados em uma área de armazenamento temporário, conhecida como cache, para acelerar a recuperação de dados. No contexto do Streamlit, o caching pode melhorar significativamente o desempenho de seus aplicativos web, especialmente ao trabalhar com conjuntos de dados grandes ou cálculos complexos.

O que é Streamlit?

Streamlit é um revolucionário no campo da ciência de dados e aprendizado de máquina. Permite que você construa aplicações de dados interativas e robustas rapidamente. Com o Streamlit, você pode criar belas aplicações web orientadas por dados com apenas algumas linhas de código Python. É projetado para manipular grandes conjuntos de dados e cálculos complexos, tornando-se uma ferramenta poderosa para cientistas de dados e engenheiros de aprendizado de máquina.

O que é Caching?

Caching é uma técnica usada para armazenar dados temporariamente em um cache, que é uma camada de armazenamento de dados de alta velocidade. O objetivo principal do caching é aumentar a velocidade de recuperação de dados, reduzindo a necessidade de acessar a camada de armazenamento lenta subjacente. Quando os dados são solicitados, o sistema primeiro verifica o cache. Se os dados forem encontrados, são retornados imediatamente. Caso contrário, o sistema busca os dados do armazenamento principal, os retorna e também os armazena no cache para futuras solicitações.

Por que você precisa de Caching no Streamlit?

No Streamlit, cada vez que ocorre uma interação no aplicativo, o script inteiro é executado novamente do início ao fim. Embora esse modelo simplifique o modelo de programação, pode levar a ineficiências. Por exemplo, se seu script incluir uma função que carrega um conjunto de dados grande ou realiza um cálculo demorado, você não gostaria de executar essa função toda vez que o script fosse executado novamente. É aí que entra o caching. Usando o caching do Streamlit, você pode garantir que determinadas funções só sejam executadas novamente quando suas entradas mudarem.

Os benefícios de usar o Caching do Streamlit

O caching no Streamlit oferece vários benefícios:

  • Desempenho aprimorado: Ao armazenar os resultados de chamadas de função caras no cache, você pode acelerar drasticamente seus aplicativos do Streamlit. Isso é particularmente benéfico ao trabalhar com conjuntos de dados grandes ou modelos de aprendizado de máquina complexos que levam muito tempo para carregar ou calcular.

  • Eficiência aumentada: O caching permite evitar cálculos desnecessários. Se uma função foi chamada anteriormente com os mesmos argumentos, o Streamlit pode recuperar o resultado do cache em vez de executar a função novamente.

  • Experiência do usuário aprimorada: Tempos de carregamento mais rápidos e aplicativos mais responsivos levam a uma melhor experiência do usuário. Com o caching, os usuários não precisam esperar que os dados sejam carregados ou os cálculos sejam concluídos toda vez que interagem com seu aplicativo.

O mecanismo de caching do Streamlit permite que os desenvolvedores armazenem os resultados de cálculos de funções em um cache, possibilitando uma recuperação de dados mais rápida e melhor desempenho do aplicativo. Esta seção irá explorar como o caching do Streamlit funciona, seus benefícios e os desafios que ele apresenta.

Desafios de usar o Caching do Streamlit

Embora o caching seja uma funcionalidade poderosa, também apresenta alguns desafios:

  • Gerenciamento de Cache: Gerenciar o cache pode ser complicado. Você precisa garantir que o cache não consuma muita memória e que seja invalidado corretamente quando as entradas de uma função em cache mudarem.

  • Debugging: O debugging pode ser mais complexo com o caching. Se a saída de uma função for lida do cache, nenhuma instrução print ou efeitos colaterais na função ocorrerão, o que pode tornar o debugging mais difícil.

  • Persistência do Cache: Por padrão, o cache do Streamlit é limpo toda vez que você reinicia o servidor Streamlit. Se você precisa de caching persistente em várias execuções, precisará usar opções avançadas de caching ou soluções de caching externas.

Como o Caching do Streamlit Funciona

O Streamlit fornece um decorador, @st.cache, que você pode adicionar antes de uma definição de função para habilitar o caching. Quando você marca uma função com o decorador @st.cache, o Streamlit verifica se essa função já foi chamada com as mesmas entradas antes. Se sim, o Streamlit lê a saída da função do cache, o que é muito mais rápido do que executar a função. Se não, ele executa a função, armazena o resultado no cache e retorna o resultado.

Aqui está um exemplo simples de como usar o caching do Streamlit:

@st.cache
def load_data():
    data = pd.read_csv('large_dataset.csv')
    return data

Neste exemplo, a função load_data será executada apenas uma vez, independentemente de quantas vezes o script seja executado novamente. O resultado é armazenado em cache para uso futuro, economizando tempo e recursos computacionais.

Mecanismos de Caching do Streamlit: @st.cache, st.cache_data e st.cache_resource

O Streamlit fornece vários mecanismos de caching que você pode usar, dependendo de suas necessidades. Esta seção explicará as diferenças entre @st.cache, st.cache_data e st.cache_resource.

@st.cache

@st.cache é um decorador que você pode adicionar antes de uma definição de função para habilitar o caching. Quando uma função marcada com @st.cache é chamada, o Streamlit verifica se a função já foi chamada antes com as mesmas entradas. Se sim, o Streamlit lê a saída da função do cache. Se não, ele executa a função, armazena o resultado no cache e retorna o resultado.

Aqui está um exemplo de como usar @st.cache:

@st.cache
def load_data():
    data = pd.read_csv('large_dataset.csv')
    return data

Neste exemplo, a função load_data será executada apenas uma vez, independentemente de quantas vezes o script for executado novamente. O resultado é armazenado em cache para uso futuro.

st.cache_data

O st.cache_data é um decorador usado para armazenar em cache funções que retornam dados, como transformações de dataframe, consultas de banco de dados ou inferência de aprendizado de máquina. Os objetos em cache são armazenados em uma forma "pickled", o que significa que o valor de retorno de uma função em cache deve ser "picklizable". Cada chamadora da função em cache obtém sua própria cópia dos dados em cache. Você pode limpar o cache de uma função com func.clear() ou limpar todo o cache com st.cache_data.clear(). Se você precisar armazenar em cache recursos globais, considere usar st.cache_resource em vez disso.

A assinatura da função é a seguinte:

st.cache_data(func=None, *, ttl, max_entries, show_spinner, persist, experimental_allow_widgets, hash_funcs=None)

Os parâmetros incluem a função a ser armazenada em cache, o tempo máximo para manter uma entrada em cache, o número máximo de entradas a serem mantidas em cache, se o spinner deve ser ativado, em qual local armazenar os dados em cache, se permitir o uso de widgets na função em cache e um mapeamento de tipos ou nomes de qualificação completa para funções de hash.

st.cache_resource

O st.cache_resource é um decorador usado para armazenar em cache funções que retornam recursos globais, como conexões de banco de dados ou modelos de aprendizado de máquina. Os objetos em cache são compartilhados entre todos os usuários, sessões e execuções. Eles devem ser thread-safe, pois podem ser acessados ​​de vários threads simultaneamente. Se a segurança dos threads for um problema, considere usar st.session_state para armazenar recursos por sessão. Você pode limpar o cache de uma função com func.clear() ou limpar todo o cache com st.cache_resource.clear().

A assinatura da função é a seguinte:

st.cache_resource(func, *, ttl, max_entries, show_spinner, validate, experimental_allow_widgets, hash_funcs=None)

Os parâmetros incluem a função que cria o recurso em cache, o tempo máximo para manter uma entrada em cache, o número máximo de entradas a serem mantidas em cache, se o spinner deve ser ativado, uma função de validação opcional para dados em cache, se permitir o uso de widgets na função em cache e um mapeamento de tipos ou nomes de qualificação completa para funções de hash.

Streamlit Caching na prática: casos de uso e exemplos

O armazenamento em cache do Streamlit pode ser usado em várias situações para melhorar o desempenho de seus aplicativos de dados. Esta seção explorará alguns casos de uso comuns e fornecerá exemplos de como implementar o cache no Streamlit.

Armazenamento em cache de modelos de aprendizado de máquina

O carregamento de modelos de aprendizado de máquina pode ser demorado, especialmente para modelos grandes. Ao armazenar em cache o processo de carregamento do modelo, você pode acelerar significativamente seus aplicativos do Streamlit. Aqui está um exemplo:

@st.cache(allow_output_mutation=True)
def load_model():
    model = load_your_model_here()  # substitua pelo seu código de carregamento do modelo
    return model

Neste exemplo, a opção allow_output_mutation=True é usada porque modelos de aprendizado de máquina frequentemente contêm tipos não hasháveis, que não são compatíveis com o cache padrão do Streamlit.

Armazenamento em cache de visualizações de dados

A visualização de dados pode ser um processo intensivo em termos computacionais, especialmente ao lidar com conjuntos de dados grandes. Armazenar em cache os resultados de suas funções de visualização de dados pode tornar seus aplicativos do Streamlit mais responsivos. Aqui está um exemplo:

@st.cache
def create_plot(data):
    fig = perform_expensive_plotting_here(data)  # substitua pelo seu código de plotagem
    return fig

Neste exemplo, a função create_plot será executada novamente apenas se a entrada data for alterada, economizando tempo e recursos computacionais.

Armazenamento em cache de chamadas de API

Se o seu aplicativo Streamlit faz chamadas de API, o armazenamento em cache pode ajudar a evitar limites de taxa de API e melhorar o desempenho do seu aplicativo, reduzindo o número de chamadas de API. Aqui está um exemplo:

@st.cache
def fetch_data(api_url):
    response = requests.get(api_url)
    return response.json()

Neste exemplo, a função fetch_data fará uma chamada de API somente se for chamada com uma nova api_url. Caso contrário, ela retornará a resposta em cache.

Armazenamento em cache de resultados de raspagem de web

A raspagem da web pode ser um processo lento e repetidamente raspar o mesmo site pode levar ao bloqueio do seu IP. Ao armazenar em cache os resultados de suas funções de raspagem da web, você pode evitar solicitações desnecessárias à rede. Aqui está um exemplo:

@st.cache
def scrape_website(url):
    data = perform_web_scraping_here(url)  # substitua pelo seu código de raspagem da web
   
    return data

Neste exemplo, a função scrape_website fará a raspagem do site somente se for chamada com um novo url. Caso contrário, ela retornará os dados em cache.

Melhores práticas de armazenamento em cache do Streamlit

Ao usar o armazenamento em cache do Streamlit, há várias melhores práticas a serem consideradas:

  • Use @st.cache com moderação: Embora o armazenamento em cache possa melhorar significativamente o desempenho do seu aplicativo, também pode consumir muita memória se não for usado com cuidado. Use @st.cache apenas para funções que realizam cálculos caros ou carregam conjuntos de dados grandes.

  • Evite efeitos colaterais em funções em cache: Funções marcadas com @st.cache não devem ter efeitos colaterais. Efeitos colaterais são alterações que uma função faz em seu ambiente, como modificar uma variável global ou escrever em um arquivo. Se uma função com efeitos colaterais for armazenada em cache, os efeitos colaterais ocorrerão apenas na primeira vez em que a função for chamada.

  • Esteja ciente de argumentos mutáveis: Se uma função em cache recebe argumentos mutáveis, como listas ou dicionários, esteja ciente de que o Streamlit usa os valores iniciais desses argumentos para identificar o resultado armazenado em cache. Se você modificar os argumentos após chamar a função, o Streamlit não reconhecerá as modificações e retornará o resultado em cache.

  • Considere usar allow_output_mutation=True para saídas não-hasháveis: Por padrão, o cache do Streamlit requer que as saídas da função sejam hasháveis. Se sua função retornar uma saída não-hashável, como um modelo de aprendizado de máquina, você pode usar a opção allow_output_mutation=True para contornar esse requisito.

Bônus: Widgets Interativos do Streamlit

Os widgets interativos do Streamlit são um recurso-chave que o diferencia de outras ferramentas de visualização de dados. Esses widgets permitem que os usuários interajam com seus aplicativos do Streamlit, permitindo que eles controlem o comportamento do aplicativo e interajam com os dados em tempo real.

Controle Deslizante

O widget de controle deslizante permite que os usuários selecionem um valor ou um intervalo de valores deslizando uma alça ao longo de uma escala horizontal. Isso é útil para permitir que os usuários controlem parâmetros numéricos em seu aplicativo.

idade = st.slider('Qual é a sua idade?', 0, 130, 25)
st.write("Eu tenho ", idade, 'anos')

Neste exemplo, o controle deslizante permite que os usuários selecionem uma idade entre 0 e 130, com o valor padrão definido como 25.

Caixa de Seleção

O widget de caixa de seleção permite que os usuários ativem ou desativem uma opção binária. Isso é útil para permitir que os usuários habilitem ou desabilitem certos recursos em seu aplicativo.

concordo = st.checkbox('Eu concordo')
if concordo:
    st.write('Ótimo!')

Neste exemplo, a caixa de seleção permite que os usuários concordem ou discordem de uma afirmação. Se o usuário marcar a caixa, o aplicativo exibirá a mensagem "Ótimo!".

Entrada de Texto

O widget de entrada de texto permite que os usuários insiram uma sequência de texto. Isso é útil para permitir que os usuários insiram dados de texto em seu aplicativo.

titulo = st.text_input('Título do Filme', 'A Vida de Brian')
st.write('O título do filme atual é', titulo)

Neste exemplo, a entrada de texto permite que os usuários insiram um título de filme.

Você já ouviu falar dessa incrível ferramenta de Análise de Dados e Visualização de Dados, que transforma seu aplicativo do Streamlit em um Tableau?

PyGWalker (opens in a new tab) é uma Biblioteca em Python que ajuda você a incorporar facilmente uma IU semelhante ao Tableau em seu próprio aplicativo do Streamlit sem esforço. Confira este vídeo incrível produzido por Sven do Coding Is Fun (opens in a new tab) demonstrando os passos detalhados para capacitar seu aplicativo do Streamlit com essa poderosa Biblioteca de Visualização de Dados em Python!


Agradecimentos especiais a Sven e sua grande contribuição (opens in a new tab) à comunidade PyGWalker!

Além disso, você também pode conferir a Página do GitHub do PyGWalker (opens in a new tab) para mais exemplos de PyGWalker.

Conclusão

O mecanismo de cache do Streamlit é uma ferramenta poderosa que pode acelerar significativamente seu aplicativo ao evitar cálculos desnecessários. Ao entender como o cache do Streamlit funciona e como usá-lo de forma eficaz, você pode criar aplicativos mais eficientes e responsivos. Seja fazendo cache de transformações de dados, modelos de aprendizado de máquina ou chamadas de API, o cache do Streamlit pode ajudá-lo a oferecer uma experiência do usuário mais suave e interativa.

Lembre-se de que, embora o cache possa melhorar o desempenho, nem sempre é a solução correta. Sempre leve em consideração as compensações e certifique-se de testar seu aplicativo minuciosamente para garantir que o cache esteja melhorando o desempenho do seu aplicativo sem introduzir comportamentos inesperados.

Os widgets interativos do Streamlit, como controles deslizantes, caixas de seleção e entradas de texto, fornecem uma maneira para os usuários interagirem com seu aplicativo e controlarem seu comportamento. Ao combinar esses widgets com o mecanismo de cache do Streamlit, você pode criar aplicativos de dados poderosos e responsivos.

No final, a simplicidade, flexibilidade e foco em dados e aprendizado de máquina do Streamlit o tornam uma ótima escolha para a construção de aplicativos de dados. Com seu mecanismo de cache e widgets interativos, você pode criar aplicativos que são poderosos e eficientes, além de interativos e envolventes.

Você já ouviu falar dessa incrível ferramenta de Análise de Dados e Visualização de Dados, que transforma seu aplicativo do Streamlit em um Tableau?

PyGWalker (opens in a new tab) é uma Biblioteca em Python que ajuda você a incorporar facilmente uma IU semelhante ao Tableau em seu próprio aplicativo do Streamlit sem esforço.

PyGWalker para visualização de dados no Streamlit (opens in a new tab)

Perguntas Frequentes

Como funciona o cache do Streamlit?

O mecanismo de cache do Streamlit armazena os resultados das chamadas de função em um cache. Quando uma função decorada com @st.cache é chamada, o Streamlit verifica se a função foi chamada anteriormente com as mesmas entradas. Se foi, o Streamlit pode pular a execução da função e usar o resultado em cache. Isso pode acelerar significativamente seu aplicativo ao evitar cálculos caros, como carregamento de dados ou execução de um modelo de aprendizado de máquina.

Quais são as limitações do cache do Streamlit?

Embora o mecanismo de cache do Streamlit seja poderoso, ele tem algumas limitações. Por exemplo, o valor de retorno de uma função em cache deve ser "pickleable", ou seja, pode ser serializado e desserializado usando o módulo pickle do Python. Isso significa que nem todos os objetos do Python podem ser retornados de uma função em cache. Além disso, as funções em cache não devem ter efeitos colaterais, pois esses serão executados apenas na primeira vez em que a função for chamada.

Como limpar o cache no Streamlit?

Você pode limpar o cache no Streamlit usando a função st.cache.clear(). Isso removerá todas as entradas do cache. Se você quiser limpar o cache para uma função específica, pode usar o método func.clear(), onde func é a função em cache.

Onde está o cache do Streamlit?

Isso significa que o cache é limpo toda vez que seu app do Streamlit é reiniciado. No entanto, você pode configurar o Streamlit para persistir o cache no disco, definindo o parâmetro persist do decorador @st.cache como True.