Complete Gradio Tutorial: Build ML Demos in Minutes

# Tutorial Lengkap Gradio: Buat Demo ML dalam Hitungan Menit Gradio adalah library Python yang memungkinkan Anda membuat web interface untuk model machine learning dengan cepat. Dengan beberapa baris...

By Ruby Abdullah · · tutorial
GradioML DemoWeb InterfacePythonMachine LearningHugging Face

Complete Gradio Tutorial: Build ML Demos in Minutes

Gradio is a Python library that allows you to quickly create web interfaces for machine learning models. With just a few lines of code, you can build interactive demos, share them with others, and even deploy to Hugging Face Spaces.

Why Gradio?

Gradio Advantages:
  • Simple API: Build UIs with minimal code
  • No frontend knowledge: Python-only development
  • Shareable links: Instant public URLs
  • Hugging Face integration: Easy deployment to Spaces
  • Multiple input/output types: Text, images, audio, video

Use Cases:
  • ML model demos
  • Data science prototypes
  • Internal tools
  • Educational applications
  • API testing interfaces

Installation

pip install gradio

With additional features

pip install gradio[oauth] # For authentication

Verify installation

python -c "import gradio; print(gradio.version)"

Quick Start

1. Hello World

import gradio as gr

def greet(name):

return f"Hello, {name}!"

demo = gr.Interface(fn=greet, inputs="text", outputs="text")

demo.launch()

2. Multiple Inputs/Outputs

import gradio as gr

def process(name, age, isstudent):

status = "student" if isstudent else "professional"

return f"{name} is a {age}-year-old {status}.", age 12

demo = gr.Interface(

fn=process,

inputs=[

gr.Textbox(label="Name"),

gr.Number(label="Age"),

gr.Checkbox(label="Is Student?")

],

outputs=[

gr.Textbox(label="Description"),

gr.Number(label="Age in Months")

],

title="User Info Processor",

description="Enter your information"

)

demo.launch()

Input Components

1. Text Inputs

import gradio as gr

def textdemo(text, textarea, password):

return f"Text: {text}, Area: {textarea[:20]}..., Pass length: {len(password)}"

demo = gr.Interface(

fn=textdemo,

inputs=[

gr.Textbox(label="Short Text", placeholder="Enter text..."),

gr.Textbox(label="Long Text", lines=5, maxlines=10),

gr.Textbox(label="Password", type="password")

],

outputs="text"

)

demo.launch()

2. Numeric Inputs

import gradio as gr

def numericdemo(number, slider, rangeval):

return f"Number: {number}, Slider: {slider}, Range: {rangeval}"

demo = gr.Interface(

fn=numericdemo,

inputs=[

gr.Number(label="Number", value=10),

gr.Slider(minimum=0, maximum=100, value=50, step=1, label="Slider"),

gr.Slider(minimum=0, maximum=100, value=[20, 80], label="Range")

],

outputs="text"

)

demo.launch()

3. Selection Inputs

import gradio as gr

def selectiondemo(dropdown, radio, checkboxes):

return f"Dropdown: {dropdown}, Radio: {radio}, Checks: {checkboxes}"

demo = gr.Interface(

fn=selectiondemo,

inputs=[

gr.Dropdown(choices=["Option A", "Option B", "Option C"], label="Dropdown"),

gr.Radio(choices=["Choice 1", "Choice 2", "Choice 3"], label="Radio"),

gr.CheckboxGroup(choices=["Item 1", "Item 2", "Item 3"], label="Checkboxes")

],

outputs="text"

)

demo.launch()

4. Media Inputs

import gradio as gr

from PIL import Image

import numpy as np

def mediademo(image, audio, video):

result = []

if image is not None:

result.append(f"Image shape: {np.array(image).shape}")

if audio is not None:

sr, data = audio

result.append(f"Audio: {sr}Hz, {len(data)} samples")

if video is not None:

result.append(f"Video received")

return "\n".join(result) if result else "No media provided"

demo = gr.Interface(

fn=mediademo,

inputs=[

gr.Image(label="Upload Image", type="pil"),

gr.Audio(label="Upload Audio"),

gr.Video(label="Upload Video")

],

outputs="text"

)

demo.launch()

5. File Inputs

import gradio as gr

def filedemo(file, files):

result = []

if file:

result.append(f"Single file: {file.name}")

if files:

result.append(f"Multiple files: {[f.name for f in files]}")

return "\n".join(result)

demo = gr.Interface(

fn=filedemo,

inputs=[

gr.File(label="Single File"),

gr.File(label="Multiple Files", filecount="multiple")

],

outputs="text"

)

demo.launch()

Output Components

1. Text and Data Outputs

import gradio as gr

import pandas as pd

import json

def outputdemo(text):

df = pd.DataFrame({

"Name": ["Alice", "Bob", "Charlie"],

"Score": [85, 92, 78]

})

jsondata = {"input": text, "length": len(text)}

return (

f"Processed: {text.upper()}",

df,

jsondata,

"# Markdown Output\nBold and italic"

)

demo = gr.Interface(

fn=outputdemo,

inputs="text",

outputs=[

gr.Textbox(label="Text Output"),

gr.Dataframe(label="Table Output"),

gr.JSON(label="JSON Output"),

gr.Markdown(label="Markdown Output")

]

)

demo.launch()

2. Media Outputs

import gradio as gr

import numpy as np

from PIL import Image

def mediaoutputdemo(text):

# Generate random image

imgarray = np.random.randint(0, 255, (256, 256, 3), dtype=np.uint8)

image = Image.fromarray(imgarray)

# Generate audio (sine wave)

sr = 22050

t = np.linspace(0, 1, sr)

audio = (np.sin(2 np.pi 440 t) 32767).astype(np.int16)

return image, (sr, audio)

demo = gr.Interface(

fn=mediaoutputdemo,

inputs="text",

outputs=[

gr.Image(label="Generated Image"),

gr.Audio(label="Generated Audio")

]

)

demo.launch()

3. Plot Outputs

import gradio as gr

import matplotlib.pyplot as plt

import numpy as np

def plotdemo(numpoints):

# Matplotlib plot

fig, ax = plt.subplots()

x = np.linspace(0, 10, int(numpoints))

ax.plot(x, np.sin(x), label='sin(x)')

ax.plot(x, np.cos(x), label='cos(x)')

ax.legend()

ax.settitle("Trigonometric Functions")

return fig

demo = gr.Interface(

fn=plotdemo,

inputs=gr.Slider(10, 100, value=50, label="Number of Points"),

outputs=gr.Plot(label="Plot")

)

demo.launch()

Blocks API (Advanced Layouts)

1. Basic Blocks

import gradio as gr

with gr.Blocks() as demo:

gr.Markdown("# My Application")

with gr.Row():

with gr.Column():

inputtext = gr.Textbox(label="Input")

submitbtn = gr.Button("Submit")

with gr.Column():

outputtext = gr.Textbox(label="Output")

def process(text):

return text.upper()

submitbtn.click(fn=process, inputs=inputtext, outputs=outputtext)

demo.launch()

2. Tabs and Accordions

import gradio as gr

with gr.Blocks() as demo:

gr.Markdown("# Multi-Tab Application")

with gr.Tabs():

with gr.TabItem("Text Processing"):

textinput = gr.Textbox(label="Enter Text")

textoutput = gr.Textbox(label="Result")

textbtn = gr.Button("Process")

textbtn.click(

fn=lambda x: x.upper(),

inputs=textinput,

outputs=textoutput

)

with gr.TabItem("Image Processing"):

imginput = gr.Image(label="Upload Image")

imgoutput = gr.Image(label="Result")

imgbtn = gr.Button("Process")

imgbtn.click(

fn=lambda x: x, # Identity for demo

inputs=imginput,

outputs=imgoutput

)

with gr.Accordion("Advanced Settings", open=False):

gr.Slider(label="Parameter 1")

gr.Slider(label="Parameter 2")

demo.launch()

3. State Management

import gradio as gr

with gr.Blocks() as demo:

# State to persist across interactions

history = gr.State([])

chatbot = gr.Chatbot(label="Chat History")

msg = gr.Textbox(label="Message")

clear = gr.Button("Clear")

def respond(message, chathistory):

response = f"You said: {message}"

chathistory.append((message, response))

return "", chathistory

def clearhistory():

return [], []

msg.submit(respond, [msg, chatbot], [msg, chatbot])

clear.click(clearhistory, outputs=[chatbot, history])

demo.launch()

4. Event Handling

import gradio as gr

with gr.Blocks() as demo:

inputtext = gr.Textbox(label="Type something")

outputtext = gr.Textbox(label="Output")

charcount = gr.Number(label="Character Count")

# Multiple event types

inputtext.change(

fn=lambda x: (x.upper(), len(x)),

inputs=inputtext,

outputs=[outputtext, charcount]

)

# Button events

btn = gr.Button("Click Me")

clickcount = gr.Number(value=0, label="Click Count")

btn.click(

fn=lambda x: x + 1,

inputs=clickcount,

outputs=clickcount

)

demo.launch()

ML Model Integration

1. Image Classification

import gradio as gr

from transformers import pipeline

Load model

classifier = pipeline("image-classification", model="google/vit-base-patch16-224")

def classifyimage(image):

if image is None:

return {}

results = classifier(image)

return {r["label"]: r["score"] for r in results}

demo = gr.Interface(

fn=classifyimage,

inputs=gr.Image(type="pil"),

outputs=gr.Label(numtopclasses=5),

title="Image Classifier",

examples=["cat.jpg", "dog.jpg"] # Add example images

)

demo.launch()

2. Text Generation

import gradio as gr

from transformers import pipeline

generator = pipeline("text-generation", model="gpt2")

def generatetext(prompt, maxlength, temperature):

result = generator(

prompt,

maxlength=maxlength,

temperature=temperature,

numreturnsequences=1

)

return result[0]["generatedtext"]

demo = gr.Interface(

fn=generatetext,

inputs=[

gr.Textbox(label="Prompt", lines=3),

gr.Slider(50, 200, value=100, label="Max Length"),

gr.Slider(0.1, 2.0, value=0.7, label="Temperature")

],

outputs=gr.Textbox(label="Generated Text", lines=10),

title="Text Generator"

)

demo.launch()

3. Chatbot with LLM

import gradio as gr

from openai import OpenAI

client = OpenAI()

def chat(message, history):

messages = [{"role": "system", "content": "You are a helpful assistant."}]

for h in history:

messages.append({"role": "user", "content": h[0]})

messages.append({"role": "assistant", "content": h[1]})

messages.append({"role": "user", "content": message})

response = client.chat.completions.create(

model="gpt-4o-mini",

messages=messages

)

return response.choices[0].message.content

demo = gr.ChatInterface(

fn=chat,

title="AI Chatbot",

description="Chat with GPT-4o-mini"

)

demo.launch()

4. Object Detection

import gradio as gr

from transformers import pipeline

from PIL import Image, ImageDraw

detector = pipeline("object-detection", model="facebook/detr-resnet-50")

def detectobjects(image):

if image is None:

return None, []

results = detector(image)

# Draw bounding boxes

draw = ImageDraw.Draw(image)

detections = []

for result in results:

box = result["box"]

label = f"{result['label']}: {result['score']:.2f}"

draw.rectangle(

[box["xmin"], box["ymin"], box["xmax"], box["ymax"]],

outline="red",

width=2

)

draw.text((box["xmin"], box["ymin"]), label, fill="red")

detections.append(label)

return image, detections

demo = gr.Interface(

fn=detectobjects,

inputs=gr.Image(type="pil"),

outputs=[

gr.Image(label="Detected Objects"),

gr.JSON(label="Detections")

],

title="Object Detector"

)

demo.launch()

Sharing and Deployment

import gradio as gr

demo = gr.Interface(fn=lambda x: x, inputs="text", outputs="text")

Creates a public link (valid for 72 hours)

demo.launch(share=True)

2. Deploy to Hugging Face Spaces

# app.py

import gradio as gr

def greet(name):

return f"Hello, {name}!"

demo = gr.Interface(fn=greet, inputs="text", outputs="text")

demo.launch()

# Create requirements.txt

echo "gradio" > requirements.txt

Upload to Hugging Face Spaces via web interface or CLI

huggingface-cli login

huggingface-cli repo create my-gradio-app --type space --space-sdk gradio

git push

3. Custom Server Configuration

import gradio as gr

demo = gr.Interface(fn=lambda x: x, inputs="text", outputs="text")

demo.launch(

servername="0.0.0.0", # Listen on all interfaces

serverport=7860,

auth=("admin", "password"), # Basic auth

sslkeyfile="key.pem", # HTTPS

sslcertfile="cert.pem",

maxthreads=10

)

4. FastAPI Integration

from fastapi import FastAPI

import gradio as gr

app = FastAPI()

@app.get("/")

def readroot():

return {"message": "Hello World"}

def greet(name):

return f"Hello, {name}!"

demo = gr.Interface(fn=greet, inputs="text", outputs="text")

app = gr.mountgradioapp(app, demo, path="/gradio")

Run: uvicorn app:app --reload

Advanced Features

1. Flagging

import gradio as gr

def process(text):

return text.upper()

demo = gr.Interface(

fn=process,

inputs="text",

outputs="text",

flaggingmode="manual", # or "auto", "never"

flaggingdir="flaggeddata",

flaggingoptions=["Incorrect", "Offensive", "Other"]

)

demo.launch()

2. Progress Bars

import gradio as gr

import time

def longtask(progress=gr.Progress()):

progress(0, desc="Starting...")

for i in progress.tqdm(range(100)):

time.sleep(0.05)

return "Done!"

demo = gr.Interface(fn=longtask, inputs=[], outputs="text")

demo.launch()

3. Queuing

import gradio as gr

import time

def slowfunction(x):

time.sleep(5)

return x

with gr.Blocks() as demo:

inputtext = gr.Textbox()

outputtext = gr.Textbox()

btn = gr.Button("Submit")

btn.click(slowfunction, inputtext, outputtext)

demo.queue(maxsize=10) # Enable queue with max 10 pending requests

demo.launch()

4. API Mode

import gradio as gr

def greet(name):

return f"Hello, {name}!"

demo = gr.Interface(fn=greet, inputs="text", outputs="text")

demo.launch()

Access API at /api/predict

curl -X POST http://localhost:7860/api/predict -H "Content-Type: application/json" -d '{"data":["World"]}'

# Client usage

from gradioclient import Client

client = Client("http://localhost:7860/")

result = client.predict("World", apiname="/predict")

print(result) # "Hello, World!"

Best Practices

1. Error Handling

import gradio as gr

def safeprocess(text):

try:

if not text:

raise gr.Error("Please enter some text!")

if len(text) > 1000:

gr.Warning("Text is very long, processing may be slow")

return text.upper()

except Exception as e:

raise gr.Error(f"Processing failed: {str(e)}")

demo = gr.Interface(fn=safeprocess, inputs="text", outputs="text")

demo.launch()

2. Caching

import gradio as gr

@gr.cache() # Cache results

def expensiveoperation(x):

# Expensive computation

import time

time.sleep(2)

return x 2

demo = gr.Interface(fn=expensiveoperation, inputs="number", outputs="number")

demo.launch()

3. Examples

import gradio as gr

def process(text, number):

return f"{text} x {number} = {text * number}"

demo = gr.Interface(

fn=process,

inputs=["text", "number"],

outputs="text",

examples=[

["Hello", 3],

["World", 2],

["Gradio", 5]

],

cacheexamples=True # Pre-compute examples

)

demo.launch()

Conclusion

Gradio is the fastest way to create ML demos with:

  • Simple API: Build interfaces with minimal code
  • Rich Components: Text, image, audio, video support
  • Blocks API: Create complex custom layouts
  • Easy Sharing: Public URLs and Hugging Face Spaces
  • ML Integration: Works with any Python ML framework
  • Key takeaways:

    • Use Interface for simple demos
    • Use Blocks for complex layouts
    • Enable queuing for slow operations
    • Deploy to Hugging Face Spaces for free hosting

    Related Articles

    Complete Comet ML Tutorial: MLOps Platform for Experiment Tracking and Model Management

    Tutorial Lengkap Comet ML: Platform MLOps untuk Experiment Tracking dan Model Management Dalam dunia machine learning mo...

    MLX Tutorial: Apple's Machine Learning Framework for Apple Silicon

    Tutorial MLX: Framework Machine Learning Apple untuk Apple Silicon MLX adalah framework machine learning open-source dar...

    SHAP Tutorial: Explainable AI and Model Interpretability

    SHAP - Panduan Praktis Explainable AI dan Interpretabilitas Model Model machine learning makin sering dipakai untuk meng...

    PyOD Tutorial: Anomaly and Outlier Detection in Python

    Deteksi Anomali di Python dengan PyOD: Panduan Praktis Sebagian besar dataset di dunia nyata mengandung sebagian kecil d...