Gradio
Gradio is a Python library for building interactive web UIs and ML demos. This skill covers the core API, patterns, and examples.
Guides
Detailed guides on specific topics (read these when relevant):
Core Patterns
Interface (high-level): wraps a function with input/output components.
import gradio as gr
def greet(name):
return f"Hello {name}!"
gr.Interface(fn=greet, inputs="text", outputs="text").launch()
Blocks (low-level): flexible layout with explicit event wiring.
import gradio as gr
with gr.Blocks() as demo:
name = gr.Textbox(label="Name")
output = gr.Textbox(label="Greeting")
btn = gr.Button("Greet")
btn.click(fn=lambda n: f"Hello {n}!", inputs=name, outputs=output)
demo.launch()
ChatInterface: high-level wrapper for chatbot UIs.
import gradio as gr
def respond(message, history):
return f"You said: {message}"
gr.ChatInterface(fn=respond).launch()
Component Signatures
Do not rely on memorized/pasted signatures for Textbox, Number, Slider, Checkbox, Dropdown, Radio, Image, Audio, Video, File, Chatbot, Button, Markdown, HTML, or any other component — they change across Gradio versions. Use gradio info (see "Prediction CLI" below) against a running app, or python -c "import gradio as gr; help(gr.Textbox)", to get the exact current signature before using unfamiliar parameters.
Custom HTML Components
If a task requires significant customization of an existing component or a component that doesn't exist in Gradio, you can create one with gr.HTML. It supports html_template (with ${} JS expressions and {{}} Handlebars syntax), css_template for scoped styles, and js_on_load for interactivity — where props.value updates the component value and trigger('event_name') fires Gradio events. For reuse, subclass gr.HTML and define api_info() for API/MCP support. See the full guide.
Here's an example that shows how to create and use these kinds of components:
import gradio as gr
class StarRating(gr.HTML):
def __init__(self, label, value=0, **kwargs):
html_template = """
<h2>${label} rating:</h2>
${Array.from({length: 5}, (_, i) => `<img class='${i < value ? '' : 'faded'}' src='https://upload.wikimedia.org/wikipedia/commons/d/df/Award-star-gold-3d.svg'>`).join('')}
"""
css_template = """
img { height: 50px; display: inline-block; cursor: pointer; }
.faded { filter: grayscale(100%); opacity: 0.3; }
"""
js_on_load = """
const imgs = element.querySelectorAll('img');
imgs.forEach((img, index) => {
img.addEventListener('click', () => {
props.value = index + 1;
});
});
"""
super().__init__(value=value, label=label, html_template=html_template, css_template=css_template, js_on_load=js_on_load, **kwargs)
def api_info(self):
return {"type": "integer", "minimum": 0, "maximum": 5}
with gr.Blocks() as demo:
gr.Markdown("# Restaurant Review")
food_rating = StarRating(label="Food", value=3)
service_rating = StarRating(label="Service", value=3)
ambience_rating = StarRating(label="Ambience", value=3)
average_btn = gr.Button("Calculate Average Rating")
rating_output = StarRating(label="Average", value=3)
def calculate_average(food, service, ambience):
return round((food + service + ambience) / 3)
average_btn.click(
fn=calculate_average,
inputs=[food_rating, service_rating, ambience_rating],
outputs=rating_output
)
demo.launch()
Event Listeners
All event listeners share the same signature:
component.event_name(
fn: Callable | None | Literal["decorator"] = "decorator",
inputs: Component | Sequence[Component] | set[Component] | None = None,
outputs: Component | Sequence[Component] | set[Component] | None = None,
api_name: str | None = None,
api_description: str | None | Literal[False] = None,
scroll_to_output: bool = False,
show_progress: Literal["full", "minimal", "hidden"] = "full",
show_progress_on: Component | Sequence[Component] | None = None,
queue: bool = True,
batch: bool = False,
max_batch_size: int = 4,
preprocess: bool = True,
postprocess: bool = True,
cancels: dict[str, Any] | list[dict[str, Any]] | None = None,
trigger_mode: Literal["once", "multiple", "always_last"] | None = None,
js: str | Literal[True] | None = None,
concurrency_limit: int | None | Literal["default"] = "default",
concurrency_id: str | None = None,
api_visibility: Literal["public", "private", "undocumented"] = "public",
time_limit: int | None = None,
stream_every: float = 0.5,
key: int | str | tuple[int | str, ...] | None = None,
validator: Callable | None = None,
) -> Dependency
Supported events per component:
- AnnotatedImage: select
- Audio: stream, change, clear, play, pause, stop, pause, start_recording, pause_recording, stop_recording, upload, input
- BarPlot: select, double_click
- BrowserState: change
- Button: click
- Chatbot: change, select, like, retry, undo, example_select, option_select, clear, copy, edit
- Checkbox: change, input, select
- CheckboxGroup: change, input, select
- ClearButton: click
- Code: change, input, focus, blur
- ColorPicker: change, input, submit, focus, blur
- Dataframe: change, input, select, edit
- Dataset: click, select
- DateTime: change, submit
- DeepLinkButton: click
- Dialogue: change, input, submit
- DownloadButton: click
- Dropdown: change, input, select, focus, blur, key_up
- DuplicateButton: click
- File: change, select, clear, upload, delete, download
- FileExplorer: change, input, select
- Gallery: select, upload, change, delete, preview_close, preview_open
- HTML: change, input, click, double_click, submit, stop, edit, clear, play, pause, end, start_recording, pause_recording, stop_recording, focus, blur, upload, release, select, stream, like, example_select, option_select, load, key_up, apply, delete, tick, undo, retry, expand, collapse, download, copy
- HighlightedText: change, select
- Image: clear, change, stream, select, upload, input
- ImageEditor: clear, change, input, select, upload, apply
- ImageSlider: clear, change, stream, select, upload, input
- JSON: change
- Label: change, select
- LinePlot: select, double_click
- LoginButton: click
- Markdown: change, copy
- Model3D: change, upload, edit, clear
- MultimodalTextbox: change, input, select, submit, focus, blur, stop
- Navbar: change
- Number: change, input, submit, focus, blur
- ParamViewer: change, upload
- Plot: change
- Radio: select, change, input
- ScatterPlot: select, double_click
- SimpleImage: clear, change, upload
- Slider: change, input, release
- State: change
- Textbox: change, input, select, submit, focus, blur, stop, copy
- Timer: tick
- UploadButton: click, upload
- Video: change, clear, start_recording, stop_recording, stop, play, pause, end, upload, input
Prediction CLI
The gradio CLI includes info and predict commands for interacting with Gradio apps programmatically. These are especially useful for coding agents that need to use Spaces in their workflows.
gradio info — Discover endpoints and parameters
gradio info <space_id_or_url>
Returns a JSON payload describing all endpoints, their parameters (with types and defaults), and return values.
gradio info gradio/calculator
# {
# "/predict": {
# "parameters": [
# {"name": "num1", "required": true, "default": null, "type": {"type": "number"}},
# {"name": "operation", "required": true, "default": null, "type": {"enum": ["add", "subtract", "multiply", "divide"], "type": "string"}},
# {"name": "num2", "required": true, "default": null, "type": {"type": "number"}}
# ],
# "returns": [{"name": "output", "type": {"type": "number"}}],
# "description": ""
# }
# }
File-type parameters show "type": "filepath" with instructions to include "meta": {"_type": "gradio.FileData"} — this signals the file will be uploaded to the remote server.
gradio predict — Send predictions
gradio predict <space_id_or_url> <endpoint> <json_payload>
Returns a JSON object with named output keys.
# Simple numeric prediction
gradio predict gradio/calculator /predict '{"num1": 5, "operation": "multiply", "num2": 3}'
# {"output": 15}
# Image generation
gradio predict black-forest-labs/FLUX.2-dev /infer '{"prompt": "A majestic dragon"}'
# {"Result": "/tmp/gradio/.../image.webp", "Seed": 1117868604}
# File upload (must include meta key)
gradio predict gradio/image_mod /predict '{"image": {"path": "/path/to/image.png", "meta": {"_type": "gradio.FileData"}}}'
# {"output": "/tmp/gradio/.../output.png"}
Both commands accept --token for accessing private Spaces.
Additional Reference
- End-to-End Examples — complete working apps
1---2name: huggingface-gradio3description: Build Gradio web UIs and demos in Python. Use when creating or editing Gradio apps, components, event listeners, layouts, or chatbots.4---5# Gradio67Gradio is a Python library for building interactive web UIs and ML demos. This skill covers the core API, patterns, and examples.89## Guides1011Detailed guides on specific topics (read these when relevant):1213- [Quickstart](https://www.gradio.app/guides/quickstart)14- [The Interface Class](https://www.gradio.app/guides/the-interface-class)15- [Blocks and Event Listeners](https://www.gradio.app/guides/blocks-and-event-listeners)16- [Controlling Layout](https://www.gradio.app/guides/controlling-layout)17- [More Blocks Features](https://www.gradio.app/guides/more-blocks-features)18- [Custom CSS and JS](https://www.gradio.app/guides/custom-CSS-and-JS)19- [Streaming Outputs](https://www.gradio.app/guides/streaming-outputs)20- [Streaming Inputs](https://www.gradio.app/guides/streaming-inputs)21- [Sharing Your App](https://www.gradio.app/guides/sharing-your-app)22- [Custom HTML Components](https://www.gradio.app/guides/custom-HTML-components)23- [Getting Started with the Python Client](https://www.gradio.app/guides/getting-started-with-the-python-client)24- [Getting Started with the JS Client](https://www.gradio.app/guides/getting-started-with-the-js-client)2526## Core Patterns2728**Interface** (high-level): wraps a function with input/output components.2930```python31import gradio as gr3233def greet(name):34 return f"Hello {name}!"3536gr.Interface(fn=greet, inputs="text", outputs="text").launch()37```3839**Blocks** (low-level): flexible layout with explicit event wiring.4041```python42import gradio as gr4344with gr.Blocks() as demo:45 name = gr.Textbox(label="Name")46 output = gr.Textbox(label="Greeting")47 btn = gr.Button("Greet")48 btn.click(fn=lambda n: f"Hello {n}!", inputs=name, outputs=output)4950demo.launch()51```5253**ChatInterface**: high-level wrapper for chatbot UIs.5455```python56import gradio as gr5758def respond(message, history):59 return f"You said: {message}"6061gr.ChatInterface(fn=respond).launch()62```6364## Component Signatures6566Do not rely on memorized/pasted signatures for `Textbox`, `Number`, `Slider`, `Checkbox`, `Dropdown`, `Radio`, `Image`, `Audio`, `Video`, `File`, `Chatbot`, `Button`, `Markdown`, `HTML`, or any other component — they change across Gradio versions. Use `gradio info` (see "Prediction CLI" below) against a running app, or `python -c "import gradio as gr; help(gr.Textbox)"`, to get the exact current signature before using unfamiliar parameters.6768## Custom HTML Components6970If a task requires significant customization of an existing component or a component that doesn't exist in Gradio, you can create one with `gr.HTML`. It supports `html_template` (with `${}` JS expressions and `{{}}` Handlebars syntax), `css_template` for scoped styles, and `js_on_load` for interactivity — where `props.value` updates the component value and `trigger('event_name')` fires Gradio events. For reuse, subclass `gr.HTML` and define `api_info()` for API/MCP support. See the [full guide](https://www.gradio.app/guides/custom-HTML-components).7172Here's an example that shows how to create and use these kinds of components:7374```python75import gradio as gr7677class StarRating(gr.HTML):78 def __init__(self, label, value=0, **kwargs):79 html_template = """80 <h2>${label} rating:</h2>81 ${Array.from({length: 5}, (_, i) => `<img class='${i < value ? '' : 'faded'}' src='https://upload.wikimedia.org/wikipedia/commons/d/df/Award-star-gold-3d.svg'>`).join('')}82 """83 css_template = """84 img { height: 50px; display: inline-block; cursor: pointer; }85 .faded { filter: grayscale(100%); opacity: 0.3; }86 """87 js_on_load = """88 const imgs = element.querySelectorAll('img');89 imgs.forEach((img, index) => {90 img.addEventListener('click', () => {91 props.value = index + 1;92 });93 });94 """95 super().__init__(value=value, label=label, html_template=html_template, css_template=css_template, js_on_load=js_on_load, **kwargs)9697 def api_info(self):98 return {"type": "integer", "minimum": 0, "maximum": 5}99100101with gr.Blocks() as demo:102 gr.Markdown("# Restaurant Review")103 food_rating = StarRating(label="Food", value=3)104 service_rating = StarRating(label="Service", value=3)105 ambience_rating = StarRating(label="Ambience", value=3)106 average_btn = gr.Button("Calculate Average Rating")107 rating_output = StarRating(label="Average", value=3)108 def calculate_average(food, service, ambience):109 return round((food + service + ambience) / 3)110 average_btn.click(111 fn=calculate_average,112 inputs=[food_rating, service_rating, ambience_rating],113 outputs=rating_output114 )115116demo.launch()117```118119## Event Listeners120121All event listeners share the same signature:122123```python124component.event_name(125 fn: Callable | None | Literal["decorator"] = "decorator",126 inputs: Component | Sequence[Component] | set[Component] | None = None,127 outputs: Component | Sequence[Component] | set[Component] | None = None,128 api_name: str | None = None,129 api_description: str | None | Literal[False] = None,130 scroll_to_output: bool = False,131 show_progress: Literal["full", "minimal", "hidden"] = "full",132 show_progress_on: Component | Sequence[Component] | None = None,133 queue: bool = True,134 batch: bool = False,135 max_batch_size: int = 4,136 preprocess: bool = True,137 postprocess: bool = True,138 cancels: dict[str, Any] | list[dict[str, Any]] | None = None,139 trigger_mode: Literal["once", "multiple", "always_last"] | None = None,140 js: str | Literal[True] | None = None,141 concurrency_limit: int | None | Literal["default"] = "default",142 concurrency_id: str | None = None,143 api_visibility: Literal["public", "private", "undocumented"] = "public",144 time_limit: int | None = None,145 stream_every: float = 0.5,146 key: int | str | tuple[int | str, ...] | None = None,147 validator: Callable | None = None,148) -> Dependency149```150151Supported events per component:152153- **AnnotatedImage**: select154- **Audio**: stream, change, clear, play, pause, stop, pause, start_recording, pause_recording, stop_recording, upload, input155- **BarPlot**: select, double_click156- **BrowserState**: change157- **Button**: click158- **Chatbot**: change, select, like, retry, undo, example_select, option_select, clear, copy, edit159- **Checkbox**: change, input, select160- **CheckboxGroup**: change, input, select161- **ClearButton**: click162- **Code**: change, input, focus, blur163- **ColorPicker**: change, input, submit, focus, blur164- **Dataframe**: change, input, select, edit165- **Dataset**: click, select166- **DateTime**: change, submit167- **DeepLinkButton**: click168- **Dialogue**: change, input, submit169- **DownloadButton**: click170- **Dropdown**: change, input, select, focus, blur, key_up171- **DuplicateButton**: click172- **File**: change, select, clear, upload, delete, download173- **FileExplorer**: change, input, select174- **Gallery**: select, upload, change, delete, preview_close, preview_open175- **HTML**: change, input, click, double_click, submit, stop, edit, clear, play, pause, end, start_recording, pause_recording, stop_recording, focus, blur, upload, release, select, stream, like, example_select, option_select, load, key_up, apply, delete, tick, undo, retry, expand, collapse, download, copy176- **HighlightedText**: change, select177- **Image**: clear, change, stream, select, upload, input178- **ImageEditor**: clear, change, input, select, upload, apply179- **ImageSlider**: clear, change, stream, select, upload, input180- **JSON**: change181- **Label**: change, select182- **LinePlot**: select, double_click183- **LoginButton**: click184- **Markdown**: change, copy185- **Model3D**: change, upload, edit, clear186- **MultimodalTextbox**: change, input, select, submit, focus, blur, stop187- **Navbar**: change188- **Number**: change, input, submit, focus, blur189- **ParamViewer**: change, upload190- **Plot**: change191- **Radio**: select, change, input192- **ScatterPlot**: select, double_click193- **SimpleImage**: clear, change, upload194- **Slider**: change, input, release195- **State**: change196- **Textbox**: change, input, select, submit, focus, blur, stop, copy197- **Timer**: tick198- **UploadButton**: click, upload199- **Video**: change, clear, start_recording, stop_recording, stop, play, pause, end, upload, input200201## Prediction CLI202203The `gradio` CLI includes `info` and `predict` commands for interacting with Gradio apps programmatically. These are especially useful for coding agents that need to use Spaces in their workflows.204205### `gradio info` — Discover endpoints and parameters206207```bash208gradio info <space_id_or_url>209```210211Returns a JSON payload describing all endpoints, their parameters (with types and defaults), and return values.212213```bash214gradio info gradio/calculator215# {216# "/predict": {217# "parameters": [218# {"name": "num1", "required": true, "default": null, "type": {"type": "number"}},219# {"name": "operation", "required": true, "default": null, "type": {"enum": ["add", "subtract", "multiply", "divide"], "type": "string"}},220# {"name": "num2", "required": true, "default": null, "type": {"type": "number"}}221# ],222# "returns": [{"name": "output", "type": {"type": "number"}}],223# "description": ""224# }225# }226```227228File-type parameters show `"type": "filepath"` with instructions to include `"meta": {"_type": "gradio.FileData"}` — this signals the file will be uploaded to the remote server.229230### `gradio predict` — Send predictions231232```bash233gradio predict <space_id_or_url> <endpoint> <json_payload>234```235236Returns a JSON object with named output keys.237238```bash239# Simple numeric prediction240gradio predict gradio/calculator /predict '{"num1": 5, "operation": "multiply", "num2": 3}'241# {"output": 15}242243# Image generation244gradio predict black-forest-labs/FLUX.2-dev /infer '{"prompt": "A majestic dragon"}'245# {"Result": "/tmp/gradio/.../image.webp", "Seed": 1117868604}246247# File upload (must include meta key)248gradio predict gradio/image_mod /predict '{"image": {"path": "/path/to/image.png", "meta": {"_type": "gradio.FileData"}}}'249# {"output": "/tmp/gradio/.../output.png"}250```251252Both commands accept `--token` for accessing private Spaces.253254## Additional Reference255256- [End-to-End Examples](examples.md) — complete working apps