Web Development
🎛️

Gradio

A Python library for quickly creating customizable web interfaces for machine learning models and data workflows.

Beginner UI API ML Visualization Deployment

Alternative To

  • • Streamlit
  • • Dash
  • • Flask

Difficulty Level

Beginner

Suitable for users with basic technical knowledge. Easy to set up and use.

Overview

Gradio is an open-source Python library that enables developers to quickly create customizable web interfaces for machine learning models, data workflows, and general Python functions. With just a few lines of code, Gradio allows you to transform complex models and algorithms into interactive demos and applications that can be used by anyone through a web browser, without requiring any web development experience.

Designed with simplicity and flexibility in mind, Gradio bridges the gap between model development and user interaction, making it an essential tool for researchers, data scientists, and developers who want to showcase their work, gather feedback, or provide practical access to their models. The library supports a wide range of input and output types, from text and images to audio and video, making it suitable for virtually any machine learning application.

Key Features

FeatureDescription
Rapid DevelopmentCreate interactive UIs with just a few lines of Python code
Multiple Interface TypesSupport for Interface, Blocks, and ChatInterface to build various application types
Rich Component Library30+ pre-built components for inputs and outputs (text, images, audio, video, plots, etc.)
Customizable LayoutsFlexible layout options with the Blocks API for creating complex applications
Instant SharingGenerate temporary public URLs to share demos with collaborators
API GenerationAutomatic REST API creation for any Gradio app
Hugging Face IntegrationSeamless deployment to Hugging Face Spaces
Client LibrariesPython and JavaScript client libraries for programmatic access
Serverless CapabilityRun Python code entirely in the browser with Gradio Lite
Streaming SupportReal-time streaming for text, audio, and video applications
Queuing SystemBuilt-in queue for handling concurrent users
Flagging & FeedbackTools for collecting user feedback and example data

Technical Details

Architecture

Gradio follows a client-server architecture:

  1. Backend: Python server built on FastAPI that handles:

    • Processing inputs and outputs
    • Running the user-defined functions
    • Managing the queue system
    • Handling file uploads/downloads
    • Providing REST API endpoints
  2. Frontend: Modern web interface built with:

    • Svelte framework for reactive UI components
    • TailwindCSS for styling
    • Support for themes and custom CSS

Version Information

The current stable version of Gradio is 5.17.0 (as of February 2025), which requires Python 3.10 or higher. Gradio has evolved significantly since its initial release:

VersionRelease DateMajor Features
5.0January 2024Complete rewrite with Svelte, improved performance, new component system
4.0June 2023Blocks API improvements, better streaming support
3.0January 2023Introduction of the Blocks API for complex layouts
2.0May 2022Enhanced component library, improved sharing
1.0August 2021First stable release with core Interface functionality

Component System

Gradio’s component system is modular and extensible:

  • Input Components: Textbox, Image, Audio, Video, Slider, Checkbox, Radio, Dropdown, etc.
  • Output Components: Same as input components, plus specialized ones like Gallery, JSON, Label, etc.
  • Layout Components: Row, Column, Tab, Group, Accordion for organizing UI elements
  • Control Components: Button, Timer for triggering events

Each component handles:

  • Preprocessing (converting browser data to Python objects)
  • Postprocessing (converting Python objects to browser-displayable data)
  • Serialization/deserialization for API calls

Why Use Gradio

Compared to Streamlit

  • Faster Setup: Gradio requires less code to create a basic interface
  • ML-Focused: Optimized for machine learning model demos with specialized components
  • API Generation: Automatically creates APIs for any interface
  • In-Notebook Use: Seamlessly runs within Jupyter/Colab notebooks

Compared to Dash

  • Simpler Learning Curve: No need to learn React or complex callback patterns
  • Less Boilerplate: Requires significantly less code for basic applications
  • ML-Optimized Components: Built specifically for machine learning workflows
  • Instant Sharing: One-click temporary URL generation

Compared to Flask

  • No Web Development Knowledge Required: No HTML, CSS, or JavaScript needed
  • Built-in Components: Pre-built UI components for common ML inputs/outputs
  • Automatic API: No need to manually define routes and handlers
  • Queue Management: Built-in system for handling concurrent requests

Dependencies

Gradio has several key dependencies:

  • FastAPI (web server)
  • Pydantic (data validation)
  • Pillow (image processing)
  • ffmpeg (for audio/video processing)
  • NumPy (numerical operations)
  • Pandas (for dataframe components)
  • Matplotlib/Plotly (for plotting components)

Installation Guide

Basic Installation

The simplest way to install Gradio is via pip:

pip install gradio

For a more isolated environment, use a virtual environment:

# Create a virtual environment
python3.12 -m venv .venv # 3.13 is not ready for all ai projects yet, so I stick with 3.12 for now

# Activate the environment (macOS/Linux)
source .venv/bin/activate

# Install Gradio
pip install gradio

Installing with Extra Features

For additional functionality, you can install Gradio with extras:

# For plotting capabilities
pip install "gradio[plots]"

# For audio processing
pip install "gradio[audio]"

# For all optional dependencies
pip install "gradio[all]"

Client-Only Installation

If you only need to access Gradio apps programmatically:

pip install gradio-client

Practical Exercise: Creating a Simple Image Description Demo

python3.12 -m venv .venv
source .venv/bin/activate
pip install 'gradio[all]' torch

Moondream2 is the smallest vision model I could find at ollama. It is in general accurate, but far from perfect. Make sure you have the moondream model installed:

ollama pull moondream

Now let’s create the Gradio interface:

# main.py
import gradio as gr
import requests
import json
from PIL import Image
import io
import base64


# Function to encode the image to base64
def encode_image(image):
    buffered = io.BytesIO()
    image.save(buffered, format="PNG")
    return base64.b64encode(buffered.getvalue()).decode("utf-8")


# Define the classification function
def classify_image(image):
    # Encode the image to base64
    base64_image = encode_image(image)

    # Prepare the request to Ollama API
    api_url = "http://localhost:11434/api/generate"
    payload = {
        "model": "moondream",
        "prompt": "Describe this image in detail and identify what's in it.",
        "stream": False,
        "images": [base64_image],
    }

    # Make the API call
    try:
        response = requests.post(api_url, json=payload)
        response.raise_for_status()  # Raise an exception for HTTP errors

        # Parse the response
        result = response.json()
        description = result.get("response", "No description available")

        # Return the description
        return description
    except requests.exceptions.RequestException as e:
        return f"Error: {str(e)}"


# Create the Gradio interface
demo = gr.Interface(
    fn=classify_image,
    inputs=gr.Image(type="pil"),
    outputs=gr.Textbox(label="Image Description"),
    title="Image Analysis with Ollama moondream2",
    description="Upload an image to analyze it with the LLaVA model via Ollama.",
    examples=[
        [
            "https://ridermagazine.com/wp-content/uploads/2019/08/2020-Aprilia-RS-660-3qtr.jpg"
        ],
        [
            "https://upload.wikimedia.org/wikipedia/commons/thumb/1/15/Cat_August_2010-4.jpg/1200px-Cat_August_2010-4.jpg"
        ],
    ],
    article="This demo uses the LLaVA model through Ollama to analyze and describe images. Make sure you have Ollama running locally with the LLaVA model installed (`ollama pull llava`).",
)

# Launch the app
if __name__ == "__main__":
    demo.launch()

Advanced Example: Building a Chatbot with Blocks

Here’s how to create a more complex chatbot interface using Gradio’s Blocks API:

import gradio as gr
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# Load model and tokenizer
model_name = "NousResearch/Meta--Llama-3-8B"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16,
    device_map="auto"
)

# Define chat function
def chat(message, history):
    # Format the conversation history for the model
    messages = []
    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})

    # Convert to model input format
    prompt = tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=True
    )

    # Tokenize
    inputs = tokenizer(prompt, return_tensors="pt").to(model.device)

    # Generate response
    outputs = model.generate(
        inputs.input_ids,
        max_new_tokens=512,
        temperature=0.7,
        top_p=0.9,
        do_sample=True,
        eos_token_id=tokenizer.eos_token_id,
    )

    # Decode response
    response = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)

    return response

# Create the Gradio app with Blocks
with gr.Blocks(css="footer {visibility: hidden}") as demo:
    gr.Markdown("# 🤖 Llama 3 Chatbot")

    with gr.Row():
        with gr.Column(scale=4):
            chatbot = gr.Chatbot(height=600)
            msg = gr.Textbox(
                placeholder="Type your message here...",
                container=False,
                scale=7,
            )
            submit = gr.Button("Send", variant="primary", scale=1)

        with gr.Column(scale=1):
            gr.Markdown("### Settings")
            clear = gr.Button("Clear Conversation")

    # Set up event handlers
    msg_submit = msg.submit(
        chat,
        [msg, chatbot],
        [chatbot],
        queue=True
    ).then(
        lambda: "",
        None,
        [msg]
    )

    submit.click(
        chat,
        [msg, chatbot],
        [chatbot],
        queue=True
    ).then(
        lambda: "",
        None,
        [msg]
    )

    clear.click(lambda: None, None, chatbot, queue=False)

# Launch the app
if __name__ == "__main__":
    demo.launch()

Resources