Blocks is Gradio’s low-level API that gives you complete control over your application’s layout, events, and data flow. While Interface is great for simple demos, Blocks allows you to create sophisticated multi-page applications with custom interactions.
What is Blocks?
Blocks provides more flexibility than Interface by allowing you to:
- Control layout - Arrange components exactly how you want using rows, columns, tabs, and accordions
- Define custom events - Trigger functions based on any component interaction (clicks, changes, submissions)
- Create data flows - Chain events together so outputs from one function become inputs to another
- Build multi-page apps - Group related demos with tabs or separate pages
Basic structure
Blocks uses a context manager (the with statement) to define your application:
import gradio as gr
def welcome(name):
return f"Welcome to Gradio, {name}!"
with gr.Blocks() as demo:
gr.Markdown("# Hello World!")
inp = gr.Textbox(placeholder="What is your name?")
out = gr.Textbox()
inp.change(welcome, inp, out)
demo.launch()
Key points:
- Components defined inside the
with block are automatically added to the interface
- Events are set up using component methods like
.change(), .click(), etc.
- You define the function (
welcome), inputs (inp), and outputs (out) for each event
Layout components
Rows and Columns
Organize components horizontally and vertically:
import gradio as gr
with gr.Blocks() as demo:
with gr.Row():
inp = gr.Textbox(placeholder="Input")
out = gr.Textbox(placeholder="Output")
with gr.Row():
submit_btn = gr.Button("Submit")
clear_btn = gr.ClearButton([inp, out])
Tabs
Create tabbed interfaces for multiple workflows:
import gradio as gr
with gr.Blocks() as demo:
with gr.Tabs():
with gr.Tab("Text"):
text_input = gr.Textbox()
text_output = gr.Textbox()
with gr.Tab("Image"):
image_input = gr.Image()
image_output = gr.Image()
Accordions
Hide advanced options in collapsible sections:
import gradio as gr
with gr.Blocks() as demo:
prompt = gr.Textbox(label="Prompt")
with gr.Accordion("Advanced Settings", open=False):
temperature = gr.Slider(0, 2, label="Temperature")
max_tokens = gr.Slider(1, 2048, label="Max Tokens")
Event listeners
Blocks allows you to attach event listeners to components to trigger functions:
Click events
import gradio as gr
def process(text):
return text.upper()
with gr.Blocks() as demo:
inp = gr.Textbox()
out = gr.Textbox()
btn = gr.Button("Process")
btn.click(fn=process, inputs=inp, outputs=out)
Change events
Trigger when a component’s value changes:
with gr.Blocks() as demo:
inp = gr.Textbox()
out = gr.Textbox()
inp.change(fn=lambda x: x.upper(), inputs=inp, outputs=out)
Submit events
Trigger when the user presses Enter in a textbox:
with gr.Blocks() as demo:
inp = gr.Textbox()
out = gr.Textbox()
inp.submit(fn=process, inputs=inp, outputs=out)
Chaining events
One of Blocks’ most powerful features is event chaining with .then(), .success(), and .failure():
import gradio as gr
def step1(text):
return text.upper()
def step2(text):
return text + "!!!"
def cleanup():
return "Processing complete"
with gr.Blocks() as demo:
inp = gr.Textbox()
mid = gr.Textbox()
out = gr.Textbox()
status = gr.Textbox()
btn = gr.Button("Run")
btn.click(step1, inp, mid).then(
step2, mid, out
).success(
cleanup, None, status
)
.then() runs after the previous event completes (regardless of success/failure), .success() runs only on success, and .failure() runs only on errors.
Pass lists of components for functions that need multiple inputs or produce multiple outputs:
import gradio as gr
def calculate(x, y, operation):
if operation == "add":
return x + y, f"Added {x} and {y}"
elif operation == "multiply":
return x * y, f"Multiplied {x} and {y}"
with gr.Blocks() as demo:
with gr.Row():
num1 = gr.Number(label="First Number")
num2 = gr.Number(label="Second Number")
op = gr.Dropdown(["add", "multiply"], label="Operation")
result = gr.Number(label="Result")
description = gr.Textbox(label="Description")
btn = gr.Button("Calculate")
btn.click(
fn=calculate,
inputs=[num1, num2, op],
outputs=[result, description]
)
State management
Use the State component to maintain values between interactions:
import gradio as gr
def increment(count):
count = count + 1 if count else 1
return count, f"Count: {count}"
with gr.Blocks() as demo:
state = gr.State(value=0)
output = gr.Textbox(label="Counter")
btn = gr.Button("Increment")
btn.click(
fn=increment,
inputs=state,
outputs=[state, output]
)
State components are not visible in the UI but persist values across function calls for each user session.
Queue and concurrency
Enable queueing to handle multiple users and long-running functions:
import gradio as gr
import time
def slow_function(text):
time.sleep(3)
return text.upper()
with gr.Blocks() as demo:
inp = gr.Textbox()
out = gr.Textbox()
btn = gr.Button("Process")
btn.click(
fn=slow_function,
inputs=inp,
outputs=out,
concurrency_limit=3 # Allow up to 3 simultaneous requests
)
demo.queue() # Enable the queue
demo.launch()
Rendering dynamically
Components render as soon as they’re created within a Blocks context. Set render=False to prevent automatic rendering:
import gradio as gr
with gr.Blocks() as demo:
# This renders immediately
visible_box = gr.Textbox()
# This doesn't render yet
hidden_box = gr.Textbox(render=False)
# Render it later somewhere else
with gr.Column():
hidden_box.render()
Advanced features
Custom JavaScript
Run JavaScript code before or after Python functions:
with gr.Blocks() as demo:
inp = gr.Textbox()
out = gr.Textbox()
btn = gr.Button()
btn.click(
fn=lambda x: x.upper(),
inputs=inp,
outputs=out,
js="() => alert('Processing started!')"
)
Load events
Run functions when the page loads:
def initialize():
return "Welcome! App loaded at " + str(time.time())
with gr.Blocks() as demo:
output = gr.Textbox()
demo.load(fn=initialize, inputs=None, outputs=output)
Cancelling events
Cancel running events when a new event starts:
with gr.Blocks() as demo:
inp = gr.Textbox()
out = gr.Textbox()
start_btn = gr.Button("Start")
stop_btn = gr.Button("Stop")
click_event = start_btn.click(slow_function, inp, out)
stop_btn.click(None, None, None, cancels=[click_event])
Configuration
Blocks supports various configuration options:
with gr.Blocks(
title="My App",
analytics_enabled=True,
fill_height=True,
fill_width=False,
delete_cache=(86400, 86400) # Delete temp files daily
) as demo:
# Your components here
pass
When to use Blocks
Use Blocks when you need:
- Custom layouts beyond simple input/output
- Multiple related functions in one interface
- Complex event chains and data flows
- Multi-page or tabbed applications
- Advanced state management
For simple function wrapping, consider using Interface instead.
See also