Building demos with Gradio
- Source
- From the RAG & Agents Engineering course
- By
- Sourav Banerjee
- Last updated
- 9 Nov 2026
Gradio Blocks
Gradio turns a Python function into a web page. The function stays ordinary Python; Gradio draws an input component for each argument, an output component for each return value, and calls the function when the user acts. launch() serves the page at http://localhost:7860, or the next free port above it.
Gradio has two ways to build that page:
gr.Interface(fn, inputs, outputs)builds a form around one function: the input components, a Submit button and the outputs. Notebook05awraps an adder, a text reverser, a greyscale filter and a classifier this way, and05dsetslive=Trueso the function reruns on every change instead of on Submit. Interface also adds a Flag button; in Gradio 6.31 flagged examples go to.gradio/flagged, not theflaggedfolder05anames.gr.Blocks()is a context manager in which you place components yourself, insidegr.Row(),gr.Column(scale=…),gr.Tab(),gr.Accordion()andgr.Group()(05b). Blocks adds no button and calls nothing by itself. You connect each event to a function (05c):button.click(fn, inputs, outputs)runs on a click,slider.change(...)on every change of value. One page can hold many components and many events, each with its own function.
The event names its inputs and outputs by component, and Gradio passes values between the browser and the function. This is the Larkspur ticket tagger as a Blocks app, with the ticket box and button in a wide column and the result beside them:
import gradio as gr
from transformers import pipeline
clf = pipeline("sentiment-analysis",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
revision="714eb0f") # loaded once, when the app starts
def tag(ticket):
if not ticket.strip():
raise gr.Error("Paste a ticket first.") # stops here and shows the message
r = clf(ticket)[0]
return {r["label"]: r["score"]} # gr.Label shows a label with its confidence
with gr.Blocks() as demo:
with gr.Row():
with gr.Column(scale=2):
ticket = gr.Textbox(label="Ticket", lines=4)
go = gr.Button("Tag")
with gr.Column(scale=1):
label = gr.Label(label="Sentiment")
go.click(fn=tag, inputs=ticket, outputs=label)
demo.launch()
Three habits from the notebooks carry over to every demo:
- Load the model once, outside the function.
05ebuilds its sentiment pipeline at the top of the notebook and only calls it insidepredict_sentiment. A pipeline built inside the event function would reload the weights on every click. - Fail with a message.
raise gr.Error("…")stops the function and shows the message in the page;gr.Warning("…")shows a notice and lets the function finish (05f). - Style through
launch()in Gradio 6.05gpassestheme=togr.Interfaceandcss=togr.Blocks. Gradio 6.31, the version this course locks, still accepts both but warns "The parameters have been moved from the Blocks constructor to the launch() method in Gradio 6.0"; pass them asdemo.launch(theme=…, css=…).
Notebook 05e's last cell, gr.load("distilbert-base-uncased-finetuned-sst-2-english", src=…), runs the model on Hugging Face's servers instead of locally. In the course copy its src points at a GitHub folder URL, which gr.load does not accept; the source notebook has src="models", which loads the model by its Hub name.
A demo is a tool for trying a model with people who do not run notebooks, such as the Larkspur support lead. It has no login, rate limit or monitoring unless you add them, so in production the model runs behind a service with those controls, and the demo stays a way to try it.
Run the notebooks
The code for this lesson is in these notebooks. Colab runs one in your browser: install the packages its first cell imports and set the API keys it reads. To run every notebook as written, clone the repository and use its uv environment.
| Notebook | GitHub | Colab |
|---|---|---|
| Gradio introduction | Open on GitHub | Open in Colab |
| Gradio layout (optional) | Open on GitHub | Open in Colab |
| Gradio interactions (optional) | Open on GitHub | Open in Colab |
| Gradio image ml integration (optional) | Open on GitHub | Open in Colab |
| Gradio text ml integration (optional) | Open on GitHub | Open in Colab |
| Gradio modals errors (optional) | Open on GitHub | Open in Colab |
| Gradio styling and themes (optional) | Open on GitHub | Open in Colab |
Key Takeaways
- Use
gr.Interfacefor a quick form around one function, andgr.Blockswhen you need your own layout and many events, each wired to a function with calls such asbutton.click(fn, inputs, outputs). - Load the model once when the app starts, raise
gr.Errorto stop with a message, and passtheme=andcss=tolaunch()in Gradio 6. - A demo has no login, rate limit or monitoring. Use it to let people try a model, and serve production traffic from a service with those controls.
Check yourself
1. What does gr.Blocks leave you to do that gr.Interface does for you?
gr.Interface builds a form around one function: input components, a Submit button, the outputs and a Flag button. gr.Blocks adds no button and calls nothing by itself: you place the components in rows, columns and tabs, and connect each event to a function, such as button.click(fn, inputs, outputs). In return one page can hold many components and events.
2. In the Larkspur ticket tagger, the support lead clicks Tag with an empty ticket box. What does the page show, and does the classifier run?
The page shows "Paste a ticket first." and the classifier does not run. tag checks for an empty ticket first, and raise gr.Error(...) stops the function there and shows the message. gr.Warning would show a notice and let the function finish.
3. Every click in a colleague's Gradio demo reloads the model weights. Where did they build the pipeline, and where should it go?
Inside the event function, so each call builds the pipeline again. Build it once outside the function, when the app starts, as 05e and the ticket tagger do, and only call it inside the function.