Gradio em Python: crie demos de machine learning em minutos
Aprenda Gradio em Python para criar demos interativas de modelos de machine learning e APIs com poucas linhas, publique grátis no Hugging Face Spaces e compartilhe seu portfólio.
Gradio é uma biblioteca Python que transforma qualquer função em uma interface web interativa com poucas linhas de código. O caso de uso clássico é demonstrar um modelo de machine learning: você escreve uma função que recebe um texto, uma imagem ou um áudio e devolve uma predição, registra essa função com gr.Interface, chama launch() e obtém uma página pública no navegador com upload de arquivo, campos de entrada e saída formatada — sem escrever HTML, CSS ou JavaScript.
A recomendação prática é usar Gradio quando você precisa de uma demo rápida de modelo ou API, especialmente em portfólios de dados e IA: um notebook mostra que você treinou o modelo, mas uma demo clicável mostra que outra pessoa consegue usá-lo. Para dashboards com múltiplas visualizações e filtros, Streamlit continua sendo uma escolha melhor. Este guia mostra como instalar, criar a primeira interface, trabalhar com componentes, exemplos, estados e erros, e publicar a demo de graça no Hugging Face Spaces.
Instalação e primeira interface
Instale com o pip em um ambiente virtual limpo (veja nosso guia sobre ambientes virtuais ou use uv):
python -m venv .venv
source .venv/bin/activate
pip install gradio
Um exemplo mínimo, com uma função de saudação:
import gradio as gr
def cumprimentar(nome: str) -> str:
return f"Olá, {nome}! Bem-vindo à sua primeira demo em Gradio."
demo = gr.Interface(
fn=cumprimentar,
inputs=gr.Textbox(label="Seu nome", placeholder="Digite aqui"),
outputs=gr.Textbox(label="Saudação"),
title="Primeira demo com Gradio",
)
demo.launch()
Ao executar python app.py, o Gradio sobe um servidor local e abre http://127.0.0.1:7860 no navegador. A página já vem com layout responsivo, tema padrão, fila de execução e botão Clear — coisas que levariam dias para construir manualmente.
A anatomia do gr.Interface
O gr.Interface conecta três elementos:
| Elemento | Papel | Exemplos |
|---|---|---|
fn | A função Python executada ao clicar em Submit | predição, transformação, consulta |
inputs | Componentes de entrada (um ou mais) | Textbox, Image, Audio, Slider |
outputs | Componentes de saída (um ou mais) | Label, Image, JSON, Dataframe |
A quantidade de componentes em inputs e outputs precisa corresponder à assinatura da função: se fn recebe dois argumentos, informe dois componentes de entrada; se devolve uma tupla com dois valores, informe dois componentes de saída.
def analisar(texto: str, escala: float) -> tuple[str, str]:
palavras = len(texto.split())
resumo = f"{palavras} palavras detectadas"
detalhe = f"Escala escolhida: {escala:.1f}"
return resumo, detalhe
demo = gr.Interface(
fn=analisar,
inputs=[gr.Textbox(label="Texto"), gr.Slider(0, 10, 3, label="Escala")],
outputs=[gr.Textbox(label="Resumo"), gr.Textbox(label="Detalhe")],
)
Quando a interface precisa de mais flexibilidade — múltiplos botões, chamadas condicionais, layout em abas — use gr.Blocks, que monta a página por composição:
with gr.Blocks(title="Painel de análise") as demo:
with gr.Tab("Classificador"):
entrada = gr.Textbox(label="Frase")
saida = gr.Label(label="Classe prevista", num_top_classes=3)
botao = gr.Button("Classificar")
botao.click(fn=classificar, inputs=entrada, outputs=saida)
with gr.Tab("Ajuda"):
gr.Markdown("Cole uma frase e clique em **Classificar**.")
gr.Interface é o caminho rápido; gr.Blocks é o caminho flexível. Muitas demos começam com Interface e migram para Blocks quando ganham recursos.
Demo real: classificador de comentários
Vamos a um exemplo próximo do dia a dia de quem trabalha com dados em empresas brasileiras: classificar o sentimento de comentários de clientes. O modelo é fictício, mas a estrutura serve para qualquer função de predição, inclusive modelos treinados com scikit-learn.
import gradio as gr
PALAVRAS_POSITIVAS = {"ótimo", "excelente", "rápido", "amei", "funcionou"}
PALAVRAS_NEGATIVAS = {"ruim", "lento", "demora", "defeito", "péssimo"}
def classificar_comentario(comentario: str) -> dict[str, float]:
texto = comentario.lower()
positivas = sum(p in texto for p in PALAVRAS_POSITIVAS)
negativas = sum(n in texto for n in PALAVRAS_NEGATIVAS)
total = positivas + negativas or 1
return {
"positivo": positivas / total,
"negativo": negativas / total,
}
demo = gr.Interface(
fn=classificar_comentario,
inputs=gr.Textbox(
lines=4,
label="Comentário do cliente",
placeholder="O atendimento foi ótimo, mas a entrega demorou",
),
outputs=gr.Label(num_top_classes=2, label="Sentimento previsto"),
title="Classificador de comentários",
description="Demo simples de classificação de texto com Gradio.",
examples=[
["Produto excelente, chegou antes do prazo!"],
["Péssimo atendimento, ninguém respondeu."],
["Funcionou, mas a entrega demorou bastante."],
],
)
if __name__ == "__main__":
demo.launch()
Três detalhes fazem diferença aqui:
examplesadiciona botões de exemplo clicáveis. Eles reduzem o atrito de quem testa a demo e documentam o formato esperado da entrada.gr.Labelespera um dicionário de rótulos para pontuações, então a função devolve exatamente esse formato e o componente renderiza as barras de probabilidade.if __name__ == "__main__"garante quelaunch()só execute quando o arquivo roda diretamente — importante para o Hugging Face Spaces, que importa oapp.py.
Componentes mais usados
O catálogo de componentes é grande, mas um conjunto pequeno cobre a maioria das demos de IA:
| Componente | Entrada/saída | Uso típico |
|---|---|---|
Textbox | ambos | prompts, comentários, código |
Image | ambos | upload de foto, máscara, imagem gerada |
Audio | ambos | transcrição, síntese de voz |
File | entrada | planilhas, PDFs, modelos serializados |
Dataframe | ambos | tabelas de entrada e resultados |
Slider, Radio, Dropdown, Checkbox | entrada | hiperparâmetros e opções |
JSON | saída | depurar o payload completo |
Markdown | saída | respostas de LLM formatadas |
Gallery | saída | múltiplas imagens geradas |
Para entradas de imagem, o parâmetro type controla o que a função recebe:
def tratar_imagem(imagem):
# type="numpy" entrega um array do NumPy (padrão em versões recentes)
# type="pil" entrega um objeto PIL.Image
# type="filepath" entrega o caminho do arquivo temporário
return imagem
gr.Interface(fn=tratar_imagem, inputs=gr.Image(type="numpy"), outputs="numpy")
O mesmo componente pode ser declarado de forma abreviada: inputs="text" equivale a gr.Textbox(), inputs="image" equivale a gr.Image(). A forma abreviada é suficiente para protótipos; a forma explícita permite definir label, placeholder e limites de tamanho.
Estado, sessões e eventos
Componentes mantêm valor por sessão, e gr.State guarda dados entre chamadas sem exibir nada na tela. Um padrão comum em demos de LLM é um chat com memória da conversa:
import gradio as gr
def responder(mensagem: str, historico: list) -> tuple[str, list]:
resposta = f"Echo: {mensagem}"
historico = historico + [(mensagem, resposta)]
return resposta, historico
with gr.Blocks() as demo:
chat = gr.Chatbot(label="Conversa", type="messages")
estado = gr.State([])
msg = gr.Textbox(label="Mensagem")
enviar = gr.Button("Enviar")
enviar.click(
fn=responder,
inputs=[msg, estado],
outputs=[chat, estado],
)
Eventos como .click(), .change() e .submit() ligam componentes a funções. É possível encadear atualizações — por exemplo, preencher um Dropdown de cidades depois que o usuário escolhe um estado — declarando as dependências entre componentes em Blocks.
Tratamento de erros e validação de entrada
Uma demo pública recebe entradas imprevisíveis. Levantar uma exceção dentro de fn faz o Gradio mostrar a mensagem de erro na interface, o que é útil durante o desenvolvimento, mas em demos públicas prefira validar e retornar mensagens claras:
def prever_preco(area: float, quartos: int) -> str:
if area <= 0:
raise gr.Error("A área precisa ser um número positivo.")
if quartos < 1 or quartos > 10:
raise gr.Error("Informe entre 1 e 10 quartos.")
preco = area * 8500 + quartos * 20000
return f"Preço estimado: R$ {preco:,.2f}"
gr.Error exibe a mensagem no topo da interface sem estourar um traceback completo. Para operações demoradas, demo.launch() já ativa a fila de execução (queue), que evita sobrecarga quando várias pessoas usam a demo ao mesmo tempo e mostra a posição na fila para cada usuário.
Publicando no Hugging Face Spaces
O caminho mais rápido para colocar a demo no ar é o Hugging Face Spaces, que hospeda aplicações Gradio com um plano gratuito:
- Crie uma conta em
huggingface.coe um novo Space com o SDK Gradio. - No repositório do Space, envie dois arquivos:
app.py: a demo, terminando comdemo.launch();requirements.txt: as dependências, por exemplogradioescikit-learn.
- O Space constrói a aplicação e publica em
https://SEU_USUARIO-seu-space.hf.space.
Regras práticas que economizam retrabalho:
- Suba artefatos grandes pelo Git LFS (o padrão do Hugging Face para modelos
.joblibe.pt) ou carregue modelos diretamente da Hub comfrom_pretrained, em vez de versionar binários no repositório. - Pense em cotas e custos antes de chamar APIs de LLM em uma demo pública: limite o número de chamadas por sessão com
gr.State, valide entradas e considere exigir um token simples para evitar uso automatizado. - Remova segredos do código: use variáveis de ambiente lidas no
app.py(o Spaces fornece o recurso Secrets) em vez de colar chaves no arquivo. Os mesmos cuidados valem para qualquer aplicação — veja como proteger credenciais com o módulosecrets.
Se preferir infraestrutura própria, demo.launch(server_name="0.0.0.0", server_port=7860) serve a aplicação em qualquer servidor, inclusive dentro de um contêiner Docker, seguindo o mesmo fluxo do guia de deploy de aplicações Python.
Gradio ou Streamlit?
As duas bibliotecas têm sobreposição, mas pontos fortes diferentes:
| Critério | Gradio | Streamlit |
|---|---|---|
| Objetivo central | demonstrar funções e modelos | construir dashboards de dados |
| Prototipagem de modelo | rápida (gr.Interface) | possível, com mais código |
| Componentes de ML prontos | sim, incluindo Label, Gallery, Chatbot | via bibliotecas de visualização |
| Publicação gratuita | Hugging Face Spaces nativo | Hugging Face Spaces (SDK próprio) ou Streamlit Community Cloud |
| Layout multi-página | gr.Blocks com abas e colunas | páginas e navegação nativas |
| Melhor para | demo de IA em portfólio | painel analítico de negócio |
A resposta curta para quem pergunta a um assistente: use Gradio para demos de modelos e APIs com entradas/saídas bem definidas; use Streamlit para dashboards com múltiplas visualizações e filtros. Em portfólios de vagas de dados e IA — uma área forte do mercado Python brasileiro — as duas costumam coexistir: o modelo é demonstrado em Gradio e a análise exploratória fica em um dashboard.
Erros comuns
Esquecer que launch() bloqueia o processo
demo.launch() mantém o servidor rodando. Em scripts que fazem outras tarefas depois, chame demo.launch(prevent_thread_lock=True) e finalize com demo.close().
Assinatura da função fora de sincronia com inputs
Passar dois componentes de entrada para uma função com um argumento gera erro em tempo de execução. Confira a contagem e a ordem: o Gradio entrega os valores na mesma sequência declarada.
Recarregar o modelo a cada clique
Carregar o modelo dentro de fn faz cada predição demorar. Carregue uma vez, no escopo do módulo, e deixe fn apenas com a inferência — um detalhe que também aparece em serviços de modelos em produção com FastAPI.
Expor uma demo sem limites
Demos públicas viram alvo de uso automatizado. Ative a fila, valide entradas com gr.Error, limite chamadas por sessão e evite imprimir segredos nos componentes de saída.
Checklist antes de publicar
- A função principal valida entradas e levanta
gr.Errorcom mensagens claras? - Há
examplesque mostram o formato esperado de entrada? - O modelo (ou o cliente da API) é carregado uma única vez, fora de
fn? -
requirements.txtestá completo e sem dependências desnecessárias? - Nenhuma chave de API está no código; tudo vem de variáveis de ambiente?
- A demo foi testada com entradas vazias, muito grandes e malformadas?
- O link do Space está no currículo e no GitHub?
Conclusão
Gradio preenche um espaço específico e muito valioso: o intervalo entre “o modelo funciona no notebook” e “outra pessoa consegue usar o modelo”. Com gr.Interface, uma função de predição se torna uma página web em minutos; com gr.Blocks, a demo cresce para abas, chats e estados; com o Hugging Face Spaces, ela fica pública sem custo de infraestrutura.
Comece com uma interface pequena para uma função que você já tem, adicione examples e validação de entrada, e publique. Para quem busca vagas em dados e IA, uma demo clicável comunica mais do que qualquer parágrafo de currículo — e leva menos de uma tarde para construir. Depois, explore os dashboards com Streamlit e o deploy com FastAPI para completar o repertório.