Skip to main content
The Blocks class gives you fine-grained control over your Gradio application. Unlike Interface, which automatically creates a simple layout, Blocks lets you customize the layout, define multiple data flows, and create complex interactions between components.

Understanding Blocks structure

Here’s a simple example that shows the basic structure of a Blocks app:
Let’s break down what’s happening:
1

Create the Blocks context

The with gr.Blocks() as demo: clause creates a context where you define your app. All components created inside this context are automatically added to the app.
2

Add components

Components like Textbox and Button are created inside the context. These are the same components used in Interface, but here you have full control over their placement and configuration.
3

Define event listeners

The click() method attaches an event listener to the button. This defines the data flow: when the button is clicked, the greet function runs with name as input and updates output with the result.

Using decorator syntax

You can also attach event listeners using decorators. Skip the fn argument and assign inputs and outputs directly:

Event listeners and interactivity

Gradio automatically determines which components should be interactive based on how they’re used:
  • Input components: Any component that serves as an input to an event listener is made interactive
  • Output-only components: Components that only serve as outputs are non-interactive
  • Override behavior: You can explicitly control interactivity with the interactive parameter
If a component is neither an input nor an output:
  • With a default value: rendered non-interactive (displaying content)
  • Without a default value: rendered interactive
You can always override this with interactive=True or interactive=False.

Types of event listeners

Different components support different event listeners. Here’s an example using the change() event:
Instead of requiring a button click, this function triggers whenever you type in the textbox. The change() event listener fires when the component’s value changes.

Common event listeners

  • .click(): Triggered when a button or clickable component is clicked
  • .change(): Triggered when a component’s value changes
  • .submit(): Triggered when Enter is pressed in an input component
  • .input(): Triggered on every keystroke in a text input
  • .select(): Triggered when text or an item is selected
  • .upload(): Triggered when a file is uploaded
  • .play(): Triggered when media playback starts
Check the component documentation to see which event listeners are available for each component.

Multiple data flows

Unlike Interface, Blocks apps can have multiple data flows connecting various components. Components can serve as both inputs and outputs:
In this example, num1 can act as input to num2, and vice versa.

Function inputs: list vs set

When you have multiple input components, you can pass their values to your function in two ways:

Option 1: List of arguments

The values are passed as separate arguments in the order they appear in the inputs list.

Option 2: Dictionary (using a set)

When you pass inputs as a set (using curly brackets {}), your function receives a single dictionary where keys are the input components and values are their current values.
Option 2 is particularly useful for functions with many input components, as it makes the function signature cleaner and easier to manage.

Function returns: list vs dict

Similarly, you can return values for multiple outputs in two ways:

Option 1: Return a list

Return values in the same order as the outputs list.
For a single output component, return the value directly, not as a single-item list. Gradio cannot distinguish whether the outer list is part of your return value or a container.

Option 2: Return a dictionary

With dictionary returns, you can:
  • Update only specific outputs (notice how we skip food_box when food is 0)
  • Update outputs in any order
  • Conditionally update different sets of outputs
Even with dictionary returns, you must still specify all possible outputs in the event listener’s outputs parameter.

Updating component configurations

You can update not just a component’s value, but also its configuration (like visibility, label, or interactivity):
Return a new component instance with the properties you want to change. Any properties you don’t set will preserve their previous values.

Not changing a component’s value

Sometimes you want to leave a component’s value unchanged. Use gr.skip() for this:
Returning None typically resets a component to its empty state, while gr.skip() preserves the current value. If you have multiple outputs and want to leave all unchanged, return a single gr.skip() instead of a tuple of skips.

Running events consecutively

Use the .then() method to run events in sequence:
The .then() method executes regardless of whether the previous event raised errors.

Conditional chaining

  • .success(): Only runs if the previous event completed without errors
  • .failure(): Only runs if the previous event raised an error
These are useful for error handling workflows:

Binding multiple triggers to a function

Use gr.on() to bind multiple triggers to the same function:

Decorator syntax with gr.on

Creating “live” events

Omit the triggers parameter to automatically bind to all change events of input components:

Binding component values directly

For simple cases where a component’s value should always be a function of other components, use this shorthand:
This is equivalent to:

Next steps

Now that you understand how to create Blocks and attach event listeners, you can: