0
# Event Handling
1
2
Reactive event system for connecting user interactions to Python functions with comprehensive event data, dependency management, and support for complex interaction patterns.
3
4
## Capabilities
5
6
### Event Data Classes
7
8
Structured data objects that provide information about user interactions and system events, enabling detailed event handling logic.
9
10
```python { .api }
11
class EventData:
12
def __init__(self, target, data):
13
"""
14
Base event information with metadata.
15
16
Attributes:
17
- target: Component that triggered the event
18
- data: Event-specific data payload
19
"""
20
21
class SelectData(EventData):
22
def __init__(self, index, value, selected):
23
"""
24
Selection event data with index/value information.
25
26
Attributes:
27
- index: Selected item index (int or tuple for 2D selections)
28
- value: Selected item value
29
- selected: Whether item is selected (bool)
30
"""
31
32
class KeyUpData(EventData):
33
def __init__(self, key, input_value):
34
"""
35
Keyboard input event data with key information.
36
37
Attributes:
38
- key: Key that was pressed (string)
39
- input_value: Current input value after key press
40
"""
41
42
class LikeData(EventData):
43
def __init__(self, index, value, liked):
44
"""
45
Like/dislike event data for feedback systems.
46
47
Attributes:
48
- index: Index of liked/disliked item
49
- value: Value of liked/disliked item
50
- liked: Whether item was liked (True) or disliked (False)
51
"""
52
53
class RetryData(EventData):
54
def __init__(self, index, value):
55
"""
56
Retry action event data for error handling.
57
58
Attributes:
59
- index: Index of item being retried
60
- value: Value of item being retried
61
"""
62
63
class UndoData(EventData):
64
def __init__(self, index, value):
65
"""
66
Undo action event data for edit operations.
67
68
Attributes:
69
- index: Index of item being undone
70
- value: Previous value before undo
71
"""
72
73
class EditData(EventData):
74
def __init__(self, index, value):
75
"""
76
Edit operation event data with change information.
77
78
Attributes:
79
- index: Index of edited item
80
- value: New value after edit
81
"""
82
83
class DownloadData(EventData):
84
def __init__(self, value):
85
"""
86
Download event data with file information.
87
88
Attributes:
89
- value: File path or data being downloaded
90
"""
91
92
class CopyData(EventData):
93
def __init__(self, value):
94
"""
95
Copy operation event data for clipboard actions.
96
97
Attributes:
98
- value: Data being copied to clipboard
99
"""
100
101
class DeletedFileData(EventData):
102
def __init__(self, file):
103
"""
104
File deletion event data with file metadata.
105
106
Attributes:
107
- file: FileData object of deleted file
108
"""
109
```
110
111
### Event Listeners and Handlers
112
113
Functions and methods for registering event handlers and managing event dependencies between components.
114
115
```python { .api }
116
def on(
117
triggers,
118
fn,
119
inputs=None,
120
outputs=None,
121
api_name=None,
122
status_tracker=None,
123
preprocess=True,
124
postprocess=True,
125
scroll_to_output=False,
126
show_progress="full",
127
queue=None,
128
batch=False,
129
max_batch_size=4,
130
concurrency_limit=None,
131
concurrency_id=None,
132
**kwargs
133
):
134
"""
135
Generic event listener for custom events.
136
137
Parameters:
138
- triggers: List of component.event_name pairs to listen to
139
- fn: Function to call when event occurs
140
- inputs: Input components to pass to function
141
- outputs: Output components to update with results
142
- api_name: Name for API endpoint (None for no API)
143
- status_tracker: Status indicator component
144
- preprocess: Whether to preprocess inputs
145
- postprocess: Whether to postprocess outputs
146
- scroll_to_output: Whether to scroll to outputs
147
- show_progress: Progress indicator ("full", "minimal", "hidden")
148
- queue: Whether to queue the event
149
- batch: Whether to batch process multiple inputs
150
- max_batch_size: Maximum batch size
151
- concurrency_limit: Maximum concurrent executions
152
- concurrency_id: Identifier for concurrency limiting
153
"""
154
155
class Dependency:
156
def __init__(
157
self,
158
trigger,
159
fn,
160
inputs,
161
outputs,
162
**kwargs
163
):
164
"""
165
Event dependency configuration and chaining.
166
167
Parameters:
168
- trigger: Component event that triggers this dependency
169
- fn: Function to execute
170
- inputs: Input components
171
- outputs: Output components
172
"""
173
174
def then(self, fn, inputs=None, outputs=None, **kwargs):
175
"""Chain another function to execute after this one."""
176
177
def success(self, fn, inputs=None, outputs=None, **kwargs):
178
"""Execute function only on successful completion."""
179
180
def error(self, fn, inputs=None, outputs=None, **kwargs):
181
"""Execute function only on error."""
182
183
def api(name):
184
"""
185
API endpoint decorator for HTTP exposure.
186
187
Parameters:
188
- name: Name for the API endpoint
189
190
Returns:
191
- Decorator function for marking functions as API endpoints
192
"""
193
```
194
195
### Component Event Methods
196
197
Event handling methods available on all interactive components for connecting user interactions to Python functions.
198
199
```python { .api }
200
# Standard event methods available on most components
201
def change(self, fn, inputs=None, outputs=None, **kwargs):
202
"""Triggered when component value changes."""
203
204
def click(self, fn, inputs=None, outputs=None, **kwargs):
205
"""Triggered when component is clicked (buttons, clickable elements)."""
206
207
def select(self, fn, inputs=None, outputs=None, **kwargs):
208
"""Triggered when item is selected (galleries, dataframes, lists)."""
209
210
def submit(self, fn, inputs=None, outputs=None, **kwargs):
211
"""Triggered when form is submitted (textboxes, forms)."""
212
213
def input(self, fn, inputs=None, outputs=None, **kwargs):
214
"""Triggered on input changes (textboxes, sliders)."""
215
216
def focus(self, fn, inputs=None, outputs=None, **kwargs):
217
"""Triggered when component gains focus."""
218
219
def blur(self, fn, inputs=None, outputs=None, **kwargs):
220
"""Triggered when component loses focus."""
221
222
def upload(self, fn, inputs=None, outputs=None, **kwargs):
223
"""Triggered when file is uploaded (file components)."""
224
225
def play(self, fn, inputs=None, outputs=None, **kwargs):
226
"""Triggered when media starts playing (audio, video)."""
227
228
def pause(self, fn, inputs=None, outputs=None, **kwargs):
229
"""Triggered when media is paused."""
230
231
def like(self, fn, inputs=None, outputs=None, **kwargs):
232
"""Triggered when item is liked/disliked (chatbot)."""
233
234
def retry(self, fn, inputs=None, outputs=None, **kwargs):
235
"""Triggered when retry is requested."""
236
237
def undo(self, fn, inputs=None, outputs=None, **kwargs):
238
"""Triggered when undo is requested."""
239
240
def edit(self, fn, inputs=None, outputs=None, **kwargs):
241
"""Triggered when item is edited."""
242
243
def delete(self, fn, inputs=None, outputs=None, **kwargs):
244
"""Triggered when item is deleted."""
245
246
def copy(self, fn, inputs=None, outputs=None, **kwargs):
247
"""Triggered when item is copied."""
248
249
def key_up(self, fn, inputs=None, outputs=None, **kwargs):
250
"""Triggered when key is released."""
251
252
def stream(self, fn, inputs=None, outputs=None, **kwargs):
253
"""Triggered for streaming data updates."""
254
```
255
256
## Event Handling Patterns
257
258
### Basic Event Handling
259
260
Simple event handlers connecting component interactions to functions:
261
262
```python
263
import gradio as gr
264
265
def process_text(text):
266
return text.upper()
267
268
def button_clicked():
269
return "Button was clicked!"
270
271
with gr.Blocks() as demo:
272
input_text = gr.Textbox(label="Input")
273
output_text = gr.Textbox(label="Output")
274
submit_btn = gr.Button("Submit")
275
status_text = gr.Textbox(label="Status")
276
277
# Button click event
278
submit_btn.click(
279
fn=process_text,
280
inputs=input_text,
281
outputs=output_text
282
)
283
284
# Input change event
285
input_text.change(
286
fn=lambda x: f"Typing: {x}",
287
inputs=input_text,
288
outputs=status_text
289
)
290
```
291
292
### Advanced Event Data Usage
293
294
Using event data objects to access detailed interaction information:
295
296
```python
297
import gradio as gr
298
299
def handle_selection(evt: gr.SelectData):
300
return f"Selected item {evt.index} with value: {evt.value}"
301
302
def handle_like(evt: gr.LikeData):
303
action = "liked" if evt.liked else "disliked"
304
return f"You {action} message {evt.index}: {evt.value}"
305
306
def handle_keypress(evt: gr.KeyUpData):
307
return f"Key pressed: {evt.key}, Current text: {evt.input_value}"
308
309
with gr.Blocks() as demo:
310
# Gallery with selection handling
311
gallery = gr.Gallery(["image1.jpg", "image2.jpg"])
312
selection_output = gr.Textbox(label="Selection")
313
314
gallery.select(
315
fn=handle_selection,
316
outputs=selection_output
317
)
318
319
# Chatbot with like/dislike
320
chatbot = gr.Chatbot(likeable=True)
321
like_output = gr.Textbox(label="Feedback")
322
323
chatbot.like(
324
fn=handle_like,
325
outputs=like_output
326
)
327
328
# Text input with key handling
329
text_input = gr.Textbox(label="Type here")
330
key_output = gr.Textbox(label="Key presses")
331
332
text_input.key_up(
333
fn=handle_keypress,
334
outputs=key_output
335
)
336
```
337
338
### Event Chaining and Dependencies
339
340
Chaining multiple functions and handling success/error cases:
341
342
```python
343
import gradio as gr
344
345
def process_step1(text):
346
if not text:
347
raise ValueError("Empty input")
348
return text.upper()
349
350
def process_step2(text):
351
return f"Processed: {text}"
352
353
def handle_success():
354
return "Processing completed successfully!"
355
356
def handle_error(error):
357
return f"Error occurred: {str(error)}"
358
359
with gr.Blocks() as demo:
360
input_text = gr.Textbox(label="Input")
361
output_text = gr.Textbox(label="Output")
362
status_text = gr.Textbox(label="Status")
363
submit_btn = gr.Button("Process")
364
365
# Chain multiple processing steps
366
submit_btn.click(
367
fn=process_step1,
368
inputs=input_text,
369
outputs=output_text
370
).then(
371
fn=process_step2,
372
inputs=output_text,
373
outputs=output_text
374
).success(
375
fn=handle_success,
376
outputs=status_text
377
).error(
378
fn=handle_error,
379
outputs=status_text
380
)
381
```
382
383
### Generic Event Handling
384
385
Using the `on` function for complex event combinations:
386
387
```python
388
import gradio as gr
389
390
def multi_trigger_handler(text1, text2):
391
return f"Combined: {text1} + {text2}"
392
393
with gr.Blocks() as demo:
394
text1 = gr.Textbox(label="Text 1")
395
text2 = gr.Textbox(label="Text 2")
396
button = gr.Button("Submit")
397
output = gr.Textbox(label="Output")
398
399
# Listen to multiple triggers
400
gr.on(
401
triggers=[text1.change, text2.change, button.click],
402
fn=multi_trigger_handler,
403
inputs=[text1, text2],
404
outputs=output
405
)
406
```
407
408
### State Management with Events
409
410
Managing persistent state across event handlers:
411
412
```python
413
import gradio as gr
414
415
def increment_counter(current_count):
416
return current_count + 1
417
418
def reset_counter():
419
return 0
420
421
def update_display(count):
422
return f"Count: {count}"
423
424
with gr.Blocks() as demo:
425
counter_state = gr.State(0)
426
display = gr.Textbox(label="Counter", interactive=False)
427
increment_btn = gr.Button("Increment")
428
reset_btn = gr.Button("Reset")
429
430
# Increment counter and update display
431
increment_btn.click(
432
fn=increment_counter,
433
inputs=counter_state,
434
outputs=counter_state
435
).then(
436
fn=update_display,
437
inputs=counter_state,
438
outputs=display
439
)
440
441
# Reset counter and update display
442
reset_btn.click(
443
fn=reset_counter,
444
outputs=counter_state
445
).then(
446
fn=update_display,
447
inputs=counter_state,
448
outputs=display
449
)
450
```
451
452
## Event Configuration Options
453
454
### Performance and Queuing
455
456
Control event execution performance and queuing behavior:
457
458
```python
459
# Queue events for better performance
460
submit_btn.click(
461
fn=heavy_processing_function,
462
inputs=input_data,
463
outputs=output_data,
464
queue=True,
465
concurrency_limit=2 # Limit concurrent executions
466
)
467
468
# Batch processing for efficiency
469
process_btn.click(
470
fn=batch_processor,
471
inputs=batch_input,
472
outputs=batch_output,
473
batch=True,
474
max_batch_size=10
475
)
476
```
477
478
### Progress and Status Tracking
479
480
Show progress indicators and status updates during event processing:
481
482
```python
483
def long_running_task(progress=gr.Progress()):
484
progress(0, desc="Starting...")
485
for i in progress.tqdm(range(100)):
486
time.sleep(0.1) # Simulate work
487
return "Task completed!"
488
489
submit_btn.click(
490
fn=long_running_task,
491
outputs=result_output,
492
show_progress="full" # "full", "minimal", or "hidden"
493
)
494
```
495
496
### API Endpoint Creation
497
498
Expose event handlers as HTTP API endpoints:
499
500
```python
501
def api_function(input_data):
502
return {"processed": input_data.upper()}
503
504
submit_btn.click(
505
fn=api_function,
506
inputs=api_input,
507
outputs=api_output,
508
api_name="process_text" # Creates /api/process_text endpoint
509
)
510
```
511
512
## Error Handling and Validation
513
514
### Input Validation
515
516
Validate inputs before processing and provide user feedback:
517
518
```python
519
def validate_and_process(text):
520
if not text or len(text) < 3:
521
gr.Warning("Please enter at least 3 characters")
522
return gr.update() # No change to output
523
524
try:
525
result = complex_processing(text)
526
gr.Success("Processing completed successfully!")
527
return result
528
except Exception as e:
529
gr.Error(f"Processing failed: {str(e)}")
530
return gr.update()
531
```
532
533
### Exception Handling
534
535
Handle exceptions gracefully in event handlers:
536
537
```python
538
def safe_processing(input_data):
539
try:
540
return risky_operation(input_data)
541
except ValueError as e:
542
gr.Warning(f"Invalid input: {e}")
543
return None
544
except Exception as e:
545
gr.Error(f"Unexpected error: {e}")
546
return None
547
548
# Use error handler for cleanup
549
submit_btn.click(
550
fn=safe_processing,
551
inputs=user_input,
552
outputs=result_output
553
).error(
554
fn=lambda: "Processing failed, please try again",
555
outputs=status_output
556
)
557
```