multimodalart HF Staff commited on
Commit
79b6afd
·
verified ·
1 Parent(s): 7e64b4e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -0
app.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Minimal reproduction of gr.HTML subclass bug with gr.Examples caching.
3
+
4
+ Bug: When subclassing gr.HTML and using the custom component as an output
5
+ in gr.Examples with cache_examples=True, Gradio throws:
6
+ AttributeError: 'CustomHTMLComponent' object has no attribute 'info'
7
+
8
+ The error occurs in gradio/components/base.py line 252 in get_config():
9
+ if self.info:
10
+
11
+ This happens during example caching when Gradio tries to serialize the
12
+ component's config.
13
+
14
+ Environment: Gradio 6.x (tested with latest)
15
+
16
+ To reproduce:
17
+ 1. Run this app: python app.py
18
+ 2. Click on any example
19
+ 3. Observe the error in the terminal
20
+
21
+ Workaround: Use gr.HTML directly via factory function instead of subclassing,
22
+ and don't include the custom component in Examples outputs.
23
+ """
24
+
25
+ import gradio as gr
26
+
27
+
28
+ # Custom component that subclasses gr.HTML - THIS CAUSES THE BUG
29
+ class CustomSlider(gr.HTML):
30
+ """A simple custom slider component using gr.HTML templates."""
31
+
32
+ def __init__(self, value=50, **kwargs):
33
+ html_template = """
34
+ <div style="padding: 20px; background: #f0f0f0; border-radius: 8px;">
35
+ <h3>Custom Slider: {{value}}</h3>
36
+ <input type="range" min="0" max="100" value="{{value}}"
37
+ style="width: 100%;" id="custom-slider">
38
+ </div>
39
+ """
40
+
41
+ js_on_load = """
42
+ (() => {
43
+ const slider = element.querySelector('#custom-slider');
44
+ slider.addEventListener('input', (e) => {
45
+ props.value = parseInt(e.target.value);
46
+ });
47
+ slider.addEventListener('change', (e) => {
48
+ trigger('change', parseInt(e.target.value));
49
+ });
50
+ })();
51
+ """
52
+
53
+ super().__init__(
54
+ value=value,
55
+ html_template=html_template,
56
+ js_on_load=js_on_load,
57
+ **kwargs
58
+ )
59
+
60
+ # Even adding api_info() doesn't fix the 'info' attribute error
61
+ def api_info(self):
62
+ return {"type": "integer", "minimum": 0, "maximum": 100}
63
+
64
+
65
+ def process(text_input, slider_value):
66
+ """Simple processing function that returns text and updates the custom slider."""
67
+ result_text = f"Processed: {text_input} with value {slider_value}"
68
+ new_slider_value = slider_value # Return the same value to update custom component
69
+ return result_text, new_slider_value
70
+
71
+
72
+ with gr.Blocks() as demo:
73
+ gr.Markdown("""
74
+ ## Bug Reproduction: gr.HTML Subclass with Examples Caching
75
+
76
+ Click any example below to trigger the error:
77
+ ```
78
+ AttributeError: 'CustomSlider' object has no attribute 'info'
79
+ ```
80
+ """)
81
+
82
+ with gr.Row():
83
+ with gr.Column():
84
+ text_input = gr.Textbox(label="Text Input", value="Hello")
85
+ slider_input = gr.Slider(label="Slider", minimum=0, maximum=100, value=50)
86
+ btn = gr.Button("Process")
87
+
88
+ with gr.Column():
89
+ text_output = gr.Textbox(label="Output")
90
+ # Custom component that causes the bug when used in Examples outputs
91
+ custom_slider = CustomSlider(value=50, label="Custom Slider Output")
92
+
93
+ btn.click(
94
+ fn=process,
95
+ inputs=[text_input, slider_input],
96
+ outputs=[text_output, custom_slider]
97
+ )
98
+
99
+ # THIS CAUSES THE BUG - including custom gr.HTML subclass in outputs with caching
100
+ gr.Examples(
101
+ examples=[
102
+ ["Example 1", 25],
103
+ ["Example 2", 50],
104
+ ["Example 3", 75],
105
+ ],
106
+ inputs=[text_input, slider_input],
107
+ outputs=[text_output, custom_slider], # Bug: custom_slider causes AttributeError
108
+ fn=process,
109
+ cache_examples=True, # Bug only occurs with caching enabled
110
+ )
111
+
112
+ if __name__ == "__main__":
113
+ demo.launch()