Navigation

Introduction to AI

Machine Learning

Deep Learning

Generative AI

Tools & Frameworks

General

Introduction to Gradio

Gradio is a Python library that lets you build interactive web demos for machine learning models in minutes, with no JavaScript required. A researcher can wrap any Python function — a model inference call, a data processing pipeline, a generative AI endpoint — in a Gradio interface and share it as a public URL or embed it in a web page.

Gradio is particularly well-integrated with the Hugging Face ecosystem: every Hugging Face Space runs Gradio or Streamlit, and the Hub hosts tens of thousands of Gradio demos for everything from image generation to code completion to medical diagnosis. Its combination of rapid prototyping, rich component library, and zero-friction sharing makes it the dominant tool for ML demo development.

Quick Start: The Interface API

The simplest Gradio usage wraps a Python function with typed inputs and outputs:

import gradio as gr
import numpy as np
from PIL import Image

def classify_image(img: np.ndarray) -> dict[str, float]:
    """
    Placeholder image classifier — replace with your actual model.
    Returns a dict mapping class name → confidence score (0–1).
    """
    # Simulate model predictions
    classes = ["cat", "dog", "bird", "car", "person"]
    scores = np.random.dirichlet(np.ones(len(classes)))
    return dict(zip(classes, scores.tolist()))


# Single-line demo: inputs and outputs inferred from type hints
demo = gr.Interface(
    fn=classify_image,
    inputs=gr.Image(),           # webcam or file upload → numpy array
    outputs=gr.Label(num_top_classes=3),  # bar chart of top predictions
    title="Image Classifier",
    description="Upload an image to classify it.",
    examples=["cat.jpg", "dog.jpg"],   # pre-loaded example inputs
    theme=gr.themes.Soft()
)

demo.launch(
    share=True,       # generates a public gradio.live URL
    server_port=7860
)

Core Input/Output Components

Gradio provides over 30 built-in components covering all common ML modalities:

import gradio as gr

# Text
text_input = gr.Textbox(label="Input text", lines=3, placeholder="Type here...")
text_output = gr.Textbox(label="Output", interactive=False)

# Numbers and sliders
temperature = gr.Slider(minimum=0.0, maximum=2.0, value=0.7,
                         step=0.1, label="Temperature")
max_tokens = gr.Number(value=256, minimum=1, maximum=4096,
                        label="Max tokens", precision=0)

# Dropdowns and checkboxes
model_choice = gr.Dropdown(
    choices=["gpt-4o", "gpt-4o-mini", "claude-3-5-sonnet"],
    value="gpt-4o",
    label="Model"
)
streaming = gr.Checkbox(value=True, label="Stream output")

# Media
image_input = gr.Image(type="pil", label="Upload image")
audio_input = gr.Audio(type="numpy", label="Record or upload audio",
                        sources=["microphone", "upload"])
video_input = gr.Video(label="Upload video")

# File I/O
file_upload = gr.File(file_types=[".pdf", ".txt", ".csv"],
                       label="Upload document")
file_download = gr.DownloadButton(label="Download result")

# Structured data
dataframe_output = gr.Dataframe(
    headers=["Name", "Score", "Label"],
    datatype=["str", "number", "str"],
    interactive=False
)

# Rich display
json_output = gr.JSON(label="Model response")
markdown_output = gr.Markdown()
html_output = gr.HTML()
plot_output = gr.Plot()   # matplotlib, plotly, altair figures

The Blocks API: Complex Layouts

gr.Blocks gives full control over layout, event handling, and multi-step interactions:

import gradio as gr
import openai
from typing import Iterator

client = openai.OpenAI()

def stream_chat_response(
    message: str,
    history: list[list[str]],
    system_prompt: str,
    temperature: float,
    max_tokens: int
) -> Iterator[str]:
    """Stream a chat response token by token."""
    messages = [{"role": "system", "content": system_prompt}]
    for user_msg, assistant_msg in history:
        messages.append({"role": "user", "content": user_msg})
        messages.append({"role": "assistant", "content": assistant_msg})
    messages.append({"role": "user", "content": message})

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
        temperature=temperature,
        max_tokens=max_tokens,
        stream=True
    )
    partial = ""
    for chunk in response:
        delta = chunk.choices[0].delta.content or ""
        partial += delta
        yield partial


with gr.Blocks(title="Chat Interface", theme=gr.themes.Ocean()) as demo:
    gr.Markdown("# AI Chat Assistant")

    with gr.Row():
        with gr.Column(scale=3):
            chatbot = gr.Chatbot(
                label="Conversation",
                height=500,
                bubble_full_width=False,
                show_copy_button=True
            )
            with gr.Row():
                msg = gr.Textbox(
                    label="Message",
                    placeholder="Type a message...",
                    scale=4,
                    container=False
                )
                send_btn = gr.Button("Send", variant="primary", scale=1)

        with gr.Column(scale=1):
            gr.Markdown("### Settings")
            system_prompt = gr.Textbox(
                label="System prompt",
                value="You are a helpful assistant.",
                lines=4
            )
            temperature = gr.Slider(0.0, 2.0, value=0.7,
                                     step=0.05, label="Temperature")
            max_tokens = gr.Slider(64, 4096, value=512,
                                    step=64, label="Max tokens")
            clear_btn = gr.Button("Clear conversation", variant="secondary")

    def respond(message, chat_history, sys_prompt, temp, max_tok):
        # Generator function enables token-by-token streaming in UI
        bot_message = ""
        for partial in stream_chat_response(message, chat_history,
                                             sys_prompt, temp, max_tok):
            bot_message = partial
            yield chat_history + [[message, bot_message]], ""
        # Final yield with complete message
        yield chat_history + [[message, bot_message]], ""

    send_btn.click(
        respond,
        inputs=[msg, chatbot, system_prompt, temperature, max_tokens],
        outputs=[chatbot, msg]
    )
    msg.submit(   # also trigger on Enter key
        respond,
        inputs=[msg, chatbot, system_prompt, temperature, max_tokens],
        outputs=[chatbot, msg]
    )
    clear_btn.click(lambda: [], outputs=chatbot)

demo.launch()

Multi-Tab Interfaces

import gradio as gr

with gr.Blocks() as demo:
    gr.Markdown("# Multi-Modal AI Demo")

    with gr.Tab("Text Generation"):
        with gr.Row():
            prompt = gr.Textbox(label="Prompt", lines=3)
            output = gr.Textbox(label="Generated text", lines=8, interactive=False)
        gen_btn = gr.Button("Generate", variant="primary")
        gen_btn.click(fn=generate_text, inputs=prompt, outputs=output)

    with gr.Tab("Image Generation"):
        with gr.Row():
            img_prompt = gr.Textbox(label="Image prompt")
            img_style = gr.Dropdown(
                choices=["realistic", "anime", "oil painting", "sketch"],
                value="realistic", label="Style"
            )
        gen_img_btn = gr.Button("Generate image", variant="primary")
        image_out = gr.Image(label="Generated image", width=512, height=512)
        gen_img_btn.click(fn=generate_image,
                           inputs=[img_prompt, img_style], outputs=image_out)

    with gr.Tab("Document Q&A"):
        file_in = gr.File(file_types=[".pdf", ".txt"], label="Upload document")
        question = gr.Textbox(label="Question about the document")
        answer = gr.Textbox(label="Answer", interactive=False)
        qa_btn = gr.Button("Ask", variant="primary")
        qa_btn.click(fn=answer_question, inputs=[file_in, question], outputs=answer)

demo.launch()

State Management

import gradio as gr

def add_to_history(new_item: str, history: list) -> tuple[list, list, str]:
    """Add item to session-specific history."""
    updated_history = history + [new_item]
    display = "\n".join(f"{i+1}. {item}" for i, item in enumerate(updated_history))
    return updated_history, updated_history, display


with gr.Blocks() as demo:
    # gr.State: persists across interactions within a session (server-side)
    history_state = gr.State(default_value=[])

    item_input = gr.Textbox(label="Add item")
    add_btn = gr.Button("Add")
    history_display = gr.Textbox(label="History", interactive=False)

    add_btn.click(
        add_to_history,
        inputs=[item_input, history_state],
        outputs=[history_state, history_state, history_display]
    )

Deploying on Hugging Face Spaces

Every Hugging Face Space is a Gradio (or Streamlit) app. Deployment is a single git push:

# app.py — entry point for HF Spaces
import gradio as gr
import torch
from transformers import pipeline

# Load model (cached by HF infrastructure)
classifier = pipeline("text-classification", model="distilbert-base-uncased-finetuned-sst-2-english")

def classify_sentiment(text: str) -> dict:
    result = classifier(text)[0]
    return {result["label"]: result["score"],
            ("POSITIVE" if result["label"] == "NEGATIVE" else "NEGATIVE"): 1 - result["score"]}

demo = gr.Interface(
    fn=classify_sentiment,
    inputs=gr.Textbox(label="Review text", placeholder="Enter text to analyze..."),
    outputs=gr.Label(num_top_classes=2),
    title="Sentiment Classifier",
    description="Classify text as POSITIVE or NEGATIVE sentiment.",
    examples=["I loved this movie!", "The service was terrible.", "It was okay."],
    cache_examples=True   # pre-compute example outputs to speed up cold start
)

# HF Spaces reads launch() parameters from README.md hardware config
demo.launch()

The requirements.txt in the Space repo lists dependencies; hardware (CPU/T4/A10G) is configured in the Space settings UI or README.md metadata block.

Gradio vs. Alternatives

ToolBest forRequiresSharing
GradioML demos, rapid prototypingPython onlyHF Spaces, gradio.live
StreamlitData dashboards, app-like UIsPython onlyStreamlit Cloud
PanelComplex dashboards, notebooksPython onlySelf-host
DashProduction analytics appsPython + configSelf-host
FastAPI + ReactFull custom web appPython + JSSelf-host

Gradio’s combination of near-zero setup, deep HuggingFace integration, and growing component library makes it the fastest path from a trained model to a shareable interactive demo — a capability that has fundamentally changed how ML researchers communicate results and gather feedback from users.