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
- 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
1. Share with Public Link
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:
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