---
title: "Gradio em Python: crie demos de machine learning em minutos"
url: "https://python.dev.br/blog/gradio-demos-machine-learning-python/"
markdown_url: "https://python.dev.br/blog/gradio-demos-machine-learning-python.MD"
description: "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."
date: "2026-09-10"
author: "Equipe Python Dev BR"
---

# 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](/blog/criando-dashboards-com-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](/blog/virtual-environments-python/) ou use [`uv`](/blog/uv-gerenciador-pacotes-python/)):

```bash
python -m venv .venv
source .venv/bin/activate
pip install gradio
```

Um exemplo mínimo, com uma função de saudação:

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

```python
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:

```python
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](/blog/introducao-ao-scikit-learn/).

```python
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:

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

```python
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:

```python
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:

```python
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`](/blog/python-secrets-tokens-senhas-seguros/).

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](/glossario/docker/), seguindo o mesmo fluxo do [guia de deploy de aplicações Python](/blog/deploy-aplicacao-python/).

## Gradio ou Streamlit?

As duas bibliotecas têm sobreposição, mas pontos fortes diferentes:

| Critério | Gradio | [Streamlit](/blog/criando-dashboards-com-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](/carreira/como-conseguir-vaga-python-ia/) — 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](/blog/apis-rest-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?
- [ ] Há `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.
