CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-gradio

Python library for easily interacting with trained machine learning models

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

events.mddocs/

Event Handling

Reactive event system for connecting user interactions to Python functions with comprehensive event data, dependency management, and support for complex interaction patterns.

Capabilities

Event Data Classes

Structured data objects that provide information about user interactions and system events, enabling detailed event handling logic.

class EventData:
    def __init__(self, target, data):
        """
        Base event information with metadata.

        Attributes:
        - target: Component that triggered the event
        - data: Event-specific data payload
        """

class SelectData(EventData):
    def __init__(self, index, value, selected):
        """
        Selection event data with index/value information.

        Attributes:
        - index: Selected item index (int or tuple for 2D selections)
        - value: Selected item value
        - selected: Whether item is selected (bool)
        """

class KeyUpData(EventData):
    def __init__(self, key, input_value):
        """
        Keyboard input event data with key information.

        Attributes:
        - key: Key that was pressed (string)
        - input_value: Current input value after key press
        """

class LikeData(EventData):
    def __init__(self, index, value, liked):
        """
        Like/dislike event data for feedback systems.

        Attributes:
        - index: Index of liked/disliked item
        - value: Value of liked/disliked item  
        - liked: Whether item was liked (True) or disliked (False)
        """

class RetryData(EventData):
    def __init__(self, index, value):
        """
        Retry action event data for error handling.

        Attributes:
        - index: Index of item being retried
        - value: Value of item being retried
        """

class UndoData(EventData):
    def __init__(self, index, value):
        """
        Undo action event data for edit operations.

        Attributes:
        - index: Index of item being undone
        - value: Previous value before undo
        """

class EditData(EventData):
    def __init__(self, index, value):
        """
        Edit operation event data with change information.

        Attributes:
        - index: Index of edited item
        - value: New value after edit
        """

class DownloadData(EventData):
    def __init__(self, value):
        """
        Download event data with file information.

        Attributes:
        - value: File path or data being downloaded
        """

class CopyData(EventData):
    def __init__(self, value):
        """
        Copy operation event data for clipboard actions.

        Attributes:
        - value: Data being copied to clipboard
        """

class DeletedFileData(EventData):
    def __init__(self, file):
        """
        File deletion event data with file metadata.

        Attributes:
        - file: FileData object of deleted file
        """

Event Listeners and Handlers

Functions and methods for registering event handlers and managing event dependencies between components.

def on(
    triggers,
    fn,
    inputs=None,
    outputs=None,
    api_name=None,
    status_tracker=None,
    preprocess=True,
    postprocess=True,
    scroll_to_output=False,
    show_progress="full",
    queue=None,
    batch=False,
    max_batch_size=4,
    concurrency_limit=None,
    concurrency_id=None,
    **kwargs
):
    """
    Generic event listener for custom events.

    Parameters:
    - triggers: List of component.event_name pairs to listen to
    - fn: Function to call when event occurs
    - inputs: Input components to pass to function
    - outputs: Output components to update with results
    - api_name: Name for API endpoint (None for no API)
    - status_tracker: Status indicator component
    - preprocess: Whether to preprocess inputs
    - postprocess: Whether to postprocess outputs
    - scroll_to_output: Whether to scroll to outputs
    - show_progress: Progress indicator ("full", "minimal", "hidden")
    - queue: Whether to queue the event
    - batch: Whether to batch process multiple inputs
    - max_batch_size: Maximum batch size
    - concurrency_limit: Maximum concurrent executions
    - concurrency_id: Identifier for concurrency limiting
    """

class Dependency:
    def __init__(
        self,
        trigger,
        fn,
        inputs,
        outputs,
        **kwargs
    ):
        """
        Event dependency configuration and chaining.

        Parameters:
        - trigger: Component event that triggers this dependency
        - fn: Function to execute
        - inputs: Input components
        - outputs: Output components
        """

    def then(self, fn, inputs=None, outputs=None, **kwargs):
        """Chain another function to execute after this one."""

    def success(self, fn, inputs=None, outputs=None, **kwargs):
        """Execute function only on successful completion."""

    def error(self, fn, inputs=None, outputs=None, **kwargs):
        """Execute function only on error."""

def api(name):
    """
    API endpoint decorator for HTTP exposure.

    Parameters:
    - name: Name for the API endpoint

    Returns:
    - Decorator function for marking functions as API endpoints
    """

Component Event Methods

Event handling methods available on all interactive components for connecting user interactions to Python functions.

# Standard event methods available on most components
def change(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when component value changes."""

def click(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when component is clicked (buttons, clickable elements)."""

def select(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when item is selected (galleries, dataframes, lists)."""

def submit(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when form is submitted (textboxes, forms)."""

def input(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered on input changes (textboxes, sliders)."""

def focus(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when component gains focus."""

def blur(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when component loses focus."""

def upload(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when file is uploaded (file components)."""

def play(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when media starts playing (audio, video)."""

def pause(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when media is paused."""

def like(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when item is liked/disliked (chatbot)."""

def retry(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when retry is requested."""

def undo(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when undo is requested."""

def edit(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when item is edited."""

def delete(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when item is deleted."""

def copy(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when item is copied."""

def key_up(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered when key is released."""

def stream(self, fn, inputs=None, outputs=None, **kwargs):
    """Triggered for streaming data updates."""

Event Handling Patterns

Basic Event Handling

Simple event handlers connecting component interactions to functions:

import gradio as gr

def process_text(text):
    return text.upper()

def button_clicked():
    return "Button was clicked!"

with gr.Blocks() as demo:
    input_text = gr.Textbox(label="Input")
    output_text = gr.Textbox(label="Output")
    submit_btn = gr.Button("Submit")
    status_text = gr.Textbox(label="Status")
    
    # Button click event
    submit_btn.click(
        fn=process_text,
        inputs=input_text,
        outputs=output_text
    )
    
    # Input change event
    input_text.change(
        fn=lambda x: f"Typing: {x}",
        inputs=input_text,
        outputs=status_text
    )

Advanced Event Data Usage

Using event data objects to access detailed interaction information:

import gradio as gr

def handle_selection(evt: gr.SelectData):
    return f"Selected item {evt.index} with value: {evt.value}"

def handle_like(evt: gr.LikeData):
    action = "liked" if evt.liked else "disliked"
    return f"You {action} message {evt.index}: {evt.value}"

def handle_keypress(evt: gr.KeyUpData):
    return f"Key pressed: {evt.key}, Current text: {evt.input_value}"

with gr.Blocks() as demo:
    # Gallery with selection handling
    gallery = gr.Gallery(["image1.jpg", "image2.jpg"])
    selection_output = gr.Textbox(label="Selection")
    
    gallery.select(
        fn=handle_selection,
        outputs=selection_output
    )
    
    # Chatbot with like/dislike
    chatbot = gr.Chatbot(likeable=True)
    like_output = gr.Textbox(label="Feedback")
    
    chatbot.like(
        fn=handle_like,
        outputs=like_output
    )
    
    # Text input with key handling
    text_input = gr.Textbox(label="Type here")
    key_output = gr.Textbox(label="Key presses")
    
    text_input.key_up(
        fn=handle_keypress,
        outputs=key_output
    )

Event Chaining and Dependencies

Chaining multiple functions and handling success/error cases:

import gradio as gr

def process_step1(text):
    if not text:
        raise ValueError("Empty input")
    return text.upper()

def process_step2(text):
    return f"Processed: {text}"

def handle_success():
    return "Processing completed successfully!"

def handle_error(error):
    return f"Error occurred: {str(error)}"

with gr.Blocks() as demo:
    input_text = gr.Textbox(label="Input")
    output_text = gr.Textbox(label="Output")
    status_text = gr.Textbox(label="Status")
    submit_btn = gr.Button("Process")
    
    # Chain multiple processing steps
    submit_btn.click(
        fn=process_step1,
        inputs=input_text,
        outputs=output_text
    ).then(
        fn=process_step2,
        inputs=output_text,
        outputs=output_text
    ).success(
        fn=handle_success,
        outputs=status_text
    ).error(
        fn=handle_error,
        outputs=status_text
    )

Generic Event Handling

Using the on function for complex event combinations:

import gradio as gr

def multi_trigger_handler(text1, text2):
    return f"Combined: {text1} + {text2}"

with gr.Blocks() as demo:
    text1 = gr.Textbox(label="Text 1")
    text2 = gr.Textbox(label="Text 2") 
    button = gr.Button("Submit")
    output = gr.Textbox(label="Output")
    
    # Listen to multiple triggers
    gr.on(
        triggers=[text1.change, text2.change, button.click],
        fn=multi_trigger_handler,
        inputs=[text1, text2],
        outputs=output
    )

State Management with Events

Managing persistent state across event handlers:

import gradio as gr

def increment_counter(current_count):
    return current_count + 1

def reset_counter():
    return 0

def update_display(count):
    return f"Count: {count}"

with gr.Blocks() as demo:
    counter_state = gr.State(0)
    display = gr.Textbox(label="Counter", interactive=False)
    increment_btn = gr.Button("Increment")
    reset_btn = gr.Button("Reset")
    
    # Increment counter and update display
    increment_btn.click(
        fn=increment_counter,
        inputs=counter_state,
        outputs=counter_state
    ).then(
        fn=update_display,
        inputs=counter_state,
        outputs=display
    )
    
    # Reset counter and update display
    reset_btn.click(
        fn=reset_counter,
        outputs=counter_state
    ).then(
        fn=update_display,
        inputs=counter_state,
        outputs=display
    )

Event Configuration Options

Performance and Queuing

Control event execution performance and queuing behavior:

# Queue events for better performance
submit_btn.click(
    fn=heavy_processing_function,
    inputs=input_data,
    outputs=output_data,
    queue=True,
    concurrency_limit=2  # Limit concurrent executions
)

# Batch processing for efficiency
process_btn.click(
    fn=batch_processor,
    inputs=batch_input,
    outputs=batch_output,
    batch=True,
    max_batch_size=10
)

Progress and Status Tracking

Show progress indicators and status updates during event processing:

def long_running_task(progress=gr.Progress()):
    progress(0, desc="Starting...")
    for i in progress.tqdm(range(100)):
        time.sleep(0.1)  # Simulate work
    return "Task completed!"

submit_btn.click(
    fn=long_running_task,
    outputs=result_output,
    show_progress="full"  # "full", "minimal", or "hidden"
)

API Endpoint Creation

Expose event handlers as HTTP API endpoints:

def api_function(input_data):
    return {"processed": input_data.upper()}

submit_btn.click(
    fn=api_function,
    inputs=api_input,
    outputs=api_output,
    api_name="process_text"  # Creates /api/process_text endpoint
)

Error Handling and Validation

Input Validation

Validate inputs before processing and provide user feedback:

def validate_and_process(text):
    if not text or len(text) < 3:
        gr.Warning("Please enter at least 3 characters")
        return gr.update()  # No change to output
    
    try:
        result = complex_processing(text)
        gr.Success("Processing completed successfully!")
        return result
    except Exception as e:
        gr.Error(f"Processing failed: {str(e)}")
        return gr.update()

Exception Handling

Handle exceptions gracefully in event handlers:

def safe_processing(input_data):
    try:
        return risky_operation(input_data)
    except ValueError as e:
        gr.Warning(f"Invalid input: {e}")
        return None
    except Exception as e:
        gr.Error(f"Unexpected error: {e}")
        return None

# Use error handler for cleanup
submit_btn.click(
    fn=safe_processing,
    inputs=user_input,
    outputs=result_output
).error(
    fn=lambda: "Processing failed, please try again",
    outputs=status_output
)

Install with Tessl CLI

npx tessl i tessl/pypi-gradio

docs

components.md

core-applications.md

events.md

external-integration.md

index.md

layouts.md

themes.md

utilities.md

tile.json