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.

10 Sep 2026 9 min de leitura Equipe Python Dev BR

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:

ElementoPapelExemplos
fnA função Python executada ao clicar em Submitpredição, transformação, consulta
inputsComponentes de entrada (um ou mais)Textbox, Image, Audio, Slider
outputsComponentes 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:

  1. examples adiciona botões de exemplo clicáveis. Eles reduzem o atrito de quem testa a demo e documentam o formato esperado da entrada.
  2. gr.Label espera 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.
  3. if __name__ == "__main__" garante que launch() só execute quando o arquivo roda diretamente — importante para o Hugging Face Spaces, que importa o app.py.

Componentes mais usados

O catálogo de componentes é grande, mas um conjunto pequeno cobre a maioria das demos de IA:

ComponenteEntrada/saídaUso típico
Textboxambosprompts, comentários, código
Imageambosupload de foto, máscara, imagem gerada
Audioambostranscrição, síntese de voz
Fileentradaplanilhas, PDFs, modelos serializados
Dataframeambostabelas de entrada e resultados
Slider, Radio, Dropdown, Checkboxentradahiperparâmetros e opções
JSONsaídadepurar o payload completo
Markdownsaídarespostas de LLM formatadas
Gallerysaídamú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:

  1. Crie uma conta em huggingface.co e um novo Space com o SDK Gradio.
  2. No repositório do Space, envie dois arquivos:
    • app.py: a demo, terminando com demo.launch();
    • requirements.txt: as dependências, por exemplo gradio e scikit-learn.
  3. 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 .joblib e .pt) ou carregue modelos diretamente da Hub com from_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ódulo secrets.

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érioGradioStreamlit
Objetivo centraldemonstrar funções e modelosconstruir dashboards de dados
Prototipagem de modelorápida (gr.Interface)possível, com mais código
Componentes de ML prontossim, incluindo Label, Gallery, Chatbotvia bibliotecas de visualização
Publicação gratuitaHugging Face Spaces nativoHugging Face Spaces (SDK próprio) ou Streamlit Community Cloud
Layout multi-páginagr.Blocks com abas e colunaspáginas e navegação nativas
Melhor parademo de IA em portfóliopainel 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.Error com mensagens claras?
  • examples que mostram o formato esperado de entrada?
  • O modelo (ou o cliente da API) é carregado uma única vez, fora de fn?
  • requirements.txt está 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.

E
Equipe Python Dev BR

Contribuidor do Python Dev BR

Artigos relacionados