Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
# --- START OF FINAL
|
2 |
|
3 |
import gradio as gr
|
4 |
import pandas as pd
|
@@ -17,48 +17,49 @@ TAG_FILTER_CHOICES = [ "Audio & Speech", "Time series", "Robotics", "Music", "Vi
|
|
17 |
PIPELINE_TAGS = [ 'text-generation', 'text-to-image', 'text-classification', 'text2text-generation', 'audio-to-audio', 'feature-extraction', 'image-classification', 'translation', 'reinforcement-learning', 'fill-mask', 'text-to-speech', 'automatic-speech-recognition', 'image-text-to-text', 'token-classification', 'sentence-similarity', 'question-answering', 'image-feature-extraction', 'summarization', 'zero-shot-image-classification', 'object-detection', 'image-segmentation', 'image-to-image', 'image-to-text', 'audio-classification', 'visual-question-answering', 'text-to-video', 'zero-shot-classification', 'depth-estimation', 'text-ranking', 'image-to-video', 'multiple-choice', 'unconditional-image-generation', 'video-classification', 'text-to-audio', 'time-series-forecasting', 'any-to-any', 'video-text-to-text', 'table-question-answering' ]
|
18 |
|
19 |
# --- Custom HTML, CSS, and JavaScript for the Slider ---
|
|
|
20 |
custom_slider_js = """
|
21 |
-
function createCustomSlider() {
|
22 |
-
const paramChoices =
|
23 |
const slider = document.getElementById('noui-slider-container');
|
24 |
-
if (slider.noUiSlider) {
|
25 |
slider.noUiSlider.destroy();
|
26 |
-
}
|
27 |
-
noUiSlider.create(slider, {
|
28 |
start: [0, paramChoices.length - 1],
|
29 |
connect: true,
|
30 |
step: 1,
|
31 |
-
range: { 'min': 0, 'max': paramChoices.length - 1 },
|
32 |
-
pips: {
|
33 |
mode: 'values',
|
34 |
values: Array.from(Array(paramChoices.length).keys()),
|
35 |
density: 100 / (paramChoices.length - 1),
|
36 |
-
format: { to: function(value) { return paramChoices[value]; } }
|
37 |
-
}
|
38 |
-
});
|
39 |
|
40 |
const paramRangeStateInput = document.querySelector('#param-range-state-js textarea');
|
41 |
-
slider.noUiSlider.on('update', function (values) {
|
42 |
const intValues = values.map(v => parseInt(v, 10));
|
43 |
const newValue = JSON.stringify(intValues);
|
44 |
-
if (paramRangeStateInput.value !== newValue) {
|
45 |
paramRangeStateInput.value = newValue;
|
46 |
-
const event = new Event('input', { bubbles: true });
|
47 |
paramRangeStateInput.dispatchEvent(event);
|
48 |
-
}
|
49 |
-
});
|
50 |
|
51 |
-
function highlightPips(values) {
|
52 |
const intValues = values.map(v => parseInt(v, 10));
|
53 |
-
document.querySelectorAll('.noUi-value').forEach((pip, index) => {
|
54 |
const pipIsSelected = index >= intValues[0] && index <= intValues[1];
|
55 |
pip.style.fontWeight = pipIsSelected ? 'bold' : 'normal';
|
56 |
pip.style.color = pipIsSelected ? '#000' : '#777';
|
57 |
-
});
|
58 |
-
}
|
59 |
slider.noUiSlider.on('update', highlightPips);
|
60 |
highlightPips([0, paramChoices.length - 1]);
|
61 |
-
}
|
62 |
"""
|
63 |
|
64 |
def load_models_data():
|
@@ -103,7 +104,7 @@ def make_treemap_data(df, count_by, top_k=25, tag_filter=None, pipeline_filter=N
|
|
103 |
filtered_df = filtered_df[~filtered_df["organization"].isin(skip_orgs)]
|
104 |
if filtered_df.empty: return pd.DataFrame()
|
105 |
if count_by not in filtered_df.columns: filtered_df[count_by] = 0.0
|
106 |
-
filtered_df[count_by] = pd.to_numeric(filtered_df[count_by], errors=
|
107 |
org_totals = filtered_df.groupby("organization")[count_by].sum().nlargest(top_k, keep='first')
|
108 |
top_orgs_list = org_totals.index.tolist()
|
109 |
treemap_data = filtered_df[filtered_df["organization"].isin(top_orgs_list)][["id", "organization", count_by]].copy()
|
@@ -125,12 +126,9 @@ custom_head = """
|
|
125 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/15.7.1/nouislider.min.js"></script>
|
126 |
"""
|
127 |
|
128 |
-
# --- MODIFIED: Added emoji to the browser tab title ---
|
129 |
with gr.Blocks(title="🤗 ModelVerse Explorer", fill_width=True, head=custom_head) as demo:
|
130 |
models_data_state = gr.State(pd.DataFrame())
|
131 |
loading_complete_state = gr.State(False)
|
132 |
-
|
133 |
-
# --- MODIFIED: Removed the main title from the page body for a cleaner look ---
|
134 |
|
135 |
with gr.Row():
|
136 |
with gr.Column(scale=1):
|
@@ -221,8 +219,15 @@ with gr.Blocks(title="🤗 ModelVerse Explorer", fill_width=True, head=custom_he
|
|
221 |
plot_stats_md = f"## Plot Statistics\n- **Models shown**: {total_items_in_plot:,}\n- **Total {metric_choice}**: {int(total_value_in_plot):,}"
|
222 |
return plotly_fig, plot_stats_md
|
223 |
|
224 |
-
demo.load(
|
225 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
|
227 |
generate_plot_button.click(
|
228 |
fn=ui_generate_plot_controller,
|
@@ -235,4 +240,4 @@ if __name__ == "__main__":
|
|
235 |
print(f"Application starting...")
|
236 |
demo.queue().launch()
|
237 |
|
238 |
-
# --- END OF FINAL
|
|
|
1 |
+
# --- START OF FINAL, CORRECTED FILE app.py ---
|
2 |
|
3 |
import gradio as gr
|
4 |
import pandas as pd
|
|
|
17 |
PIPELINE_TAGS = [ 'text-generation', 'text-to-image', 'text-classification', 'text2text-generation', 'audio-to-audio', 'feature-extraction', 'image-classification', 'translation', 'reinforcement-learning', 'fill-mask', 'text-to-speech', 'automatic-speech-recognition', 'image-text-to-text', 'token-classification', 'sentence-similarity', 'question-answering', 'image-feature-extraction', 'summarization', 'zero-shot-image-classification', 'object-detection', 'image-segmentation', 'image-to-image', 'image-to-text', 'audio-classification', 'visual-question-answering', 'text-to-video', 'zero-shot-classification', 'depth-estimation', 'text-ranking', 'image-to-video', 'multiple-choice', 'unconditional-image-generation', 'video-classification', 'text-to-audio', 'time-series-forecasting', 'any-to-any', 'video-text-to-text', 'table-question-answering' ]
|
18 |
|
19 |
# --- Custom HTML, CSS, and JavaScript for the Slider ---
|
20 |
+
# Using a placeholder for the choices to be safely injected from Python
|
21 |
custom_slider_js = """
|
22 |
+
function createCustomSlider() {{
|
23 |
+
const paramChoices = {js_param_choices}; // This will be replaced by Python
|
24 |
const slider = document.getElementById('noui-slider-container');
|
25 |
+
if (slider.noUiSlider) {{
|
26 |
slider.noUiSlider.destroy();
|
27 |
+
}}
|
28 |
+
noUiSlider.create(slider, {{
|
29 |
start: [0, paramChoices.length - 1],
|
30 |
connect: true,
|
31 |
step: 1,
|
32 |
+
range: {{ 'min': 0, 'max': paramChoices.length - 1 }},
|
33 |
+
pips: {{
|
34 |
mode: 'values',
|
35 |
values: Array.from(Array(paramChoices.length).keys()),
|
36 |
density: 100 / (paramChoices.length - 1),
|
37 |
+
format: {{ to: function(value) {{ return paramChoices[value]; }} }}
|
38 |
+
}}
|
39 |
+
}});
|
40 |
|
41 |
const paramRangeStateInput = document.querySelector('#param-range-state-js textarea');
|
42 |
+
slider.noUiSlider.on('update', function (values) {{
|
43 |
const intValues = values.map(v => parseInt(v, 10));
|
44 |
const newValue = JSON.stringify(intValues);
|
45 |
+
if (paramRangeStateInput.value !== newValue) {{
|
46 |
paramRangeStateInput.value = newValue;
|
47 |
+
const event = new Event('input', {{ bubbles: true }});
|
48 |
paramRangeStateInput.dispatchEvent(event);
|
49 |
+
}}
|
50 |
+
}});
|
51 |
|
52 |
+
function highlightPips(values) {{
|
53 |
const intValues = values.map(v => parseInt(v, 10));
|
54 |
+
document.querySelectorAll('.noUi-value').forEach((pip, index) => {{
|
55 |
const pipIsSelected = index >= intValues[0] && index <= intValues[1];
|
56 |
pip.style.fontWeight = pipIsSelected ? 'bold' : 'normal';
|
57 |
pip.style.color = pipIsSelected ? '#000' : '#777';
|
58 |
+
}});
|
59 |
+
}}
|
60 |
slider.noUiSlider.on('update', highlightPips);
|
61 |
highlightPips([0, paramChoices.length - 1]);
|
62 |
+
}}
|
63 |
"""
|
64 |
|
65 |
def load_models_data():
|
|
|
104 |
filtered_df = filtered_df[~filtered_df["organization"].isin(skip_orgs)]
|
105 |
if filtered_df.empty: return pd.DataFrame()
|
106 |
if count_by not in filtered_df.columns: filtered_df[count_by] = 0.0
|
107 |
+
filtered_df[count_by] = pd.to_numeric(filtered_df[count_by], errors='coerce').fillna(0.0)
|
108 |
org_totals = filtered_df.groupby("organization")[count_by].sum().nlargest(top_k, keep='first')
|
109 |
top_orgs_list = org_totals.index.tolist()
|
110 |
treemap_data = filtered_df[filtered_df["organization"].isin(top_orgs_list)][["id", "organization", count_by]].copy()
|
|
|
126 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/15.7.1/nouislider.min.js"></script>
|
127 |
"""
|
128 |
|
|
|
129 |
with gr.Blocks(title="🤗 ModelVerse Explorer", fill_width=True, head=custom_head) as demo:
|
130 |
models_data_state = gr.State(pd.DataFrame())
|
131 |
loading_complete_state = gr.State(False)
|
|
|
|
|
132 |
|
133 |
with gr.Row():
|
134 |
with gr.Column(scale=1):
|
|
|
219 |
plot_stats_md = f"## Plot Statistics\n- **Models shown**: {total_items_in_plot:,}\n- **Total {metric_choice}**: {int(total_value_in_plot):,}"
|
220 |
return plotly_fig, plot_stats_md
|
221 |
|
222 |
+
# --- FINAL FIX: Use the `js` parameter in demo.load() instead of the deprecated `_js` in .then() ---
|
223 |
+
# We also safely format the Python list into a JS array using json.dumps
|
224 |
+
final_js = custom_slider_js.format(js_param_choices=json.dumps(PARAM_CHOICES))
|
225 |
+
demo.load(
|
226 |
+
fn=ui_load_data_controller,
|
227 |
+
inputs=[],
|
228 |
+
outputs=[models_data_state, loading_complete_state, data_info_md, status_message_md],
|
229 |
+
js=f"() => {{ {final_js} }}" # Wrap the JS in a function to be executed on load
|
230 |
+
)
|
231 |
|
232 |
generate_plot_button.click(
|
233 |
fn=ui_generate_plot_controller,
|
|
|
240 |
print(f"Application starting...")
|
241 |
demo.queue().launch()
|
242 |
|
243 |
+
# --- END OF FINAL, CORRECTED FILE app.py ---
|