Upload 5 files
Browse files- app.py +32 -56
- hfsearch.py +173 -0
app.py
CHANGED
@@ -1,60 +1,36 @@
|
|
1 |
-
import
|
2 |
-
if os.environ.get("SPACES_ZERO_GPU") is not None:
|
3 |
-
import spaces
|
4 |
-
else:
|
5 |
-
class spaces:
|
6 |
-
@staticmethod
|
7 |
-
def GPU(func):
|
8 |
-
def wrapper(*args, **kwargs):
|
9 |
-
return func(*args, **kwargs)
|
10 |
-
return wrapper
|
11 |
import gradio as gr
|
12 |
-
import
|
13 |
-
from huggingface_hub import HfApi
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
if model.downloads_all_time: md += f" AllDLs:'{model.downloads_all_time}'"
|
40 |
-
md += "\n"
|
41 |
-
return md
|
42 |
-
except Exception as e:
|
43 |
-
raise gr.Error(e)
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
sort = gr.Radio(label="Sort", choices=["last_modified", "likes", "downloads"], value="likes")
|
51 |
-
sort_dir = gr.Checkbox(label="Sort by descending order", value=False)
|
52 |
-
appr_status = gr.CheckboxGroup(label="Approval method", choices=["auto", "manual"], value=["auto", "manual"], visible=False)
|
53 |
-
|
54 |
-
run_button = gr.Button("Search", variant="primary")
|
55 |
|
56 |
-
|
57 |
-
|
58 |
-
run_button.click(infer, [filter, sort, sort_dir, infer_status, gated_status, appr_status], [output_md])
|
59 |
-
|
60 |
-
demo.launch()
|
|
|
1 |
+
import spaces
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import gradio as gr
|
3 |
+
from hfsearch import HFSearchResult, search, update_filter, update_df
|
|
|
4 |
|
5 |
+
with gr.Blocks(fill_width=True) as demo:
|
6 |
+
with gr.Column():
|
7 |
+
search_result = gr.State(value=HFSearchResult())
|
8 |
+
with gr.Group():
|
9 |
+
with gr.Row(equal_height=True):
|
10 |
+
infer_status = gr.Radio(label="Inference status", choices=["warm", "cold", "frozen", "all"], value="warm")
|
11 |
+
gated_status = gr.Radio(label="Gated status", choices=["gated", "non-gated", "all"], value="non-gated")
|
12 |
+
appr_status = gr.CheckboxGroup(label="Approval method", choices=["auto", "manual"], value=["auto", "manual"])
|
13 |
+
with gr.Accordion("Advanced", open=False):
|
14 |
+
with gr.Row(equal_height=True):
|
15 |
+
filter = gr.Textbox(label="Query", value="")
|
16 |
+
author = gr.Textbox(label="Author", value="")
|
17 |
+
sort = gr.Radio(label="Sort", choices=["last_modified", "likes", "downloads"], value="likes")
|
18 |
+
sort_method = gr.Radio(label="Sort method", choices=["ascending order", "descending order"], value="ascending order")
|
19 |
+
limit = gr.Number(label="Limit", info="If 0, fetches all models", value=1000, step=1, minimum=0, maximum=10000000)
|
20 |
+
run_button = gr.Button("Search", variant="primary")
|
21 |
+
with gr.Group():
|
22 |
+
with gr.Accordion("Filter", open=False):
|
23 |
+
hide_item = gr.CheckboxGroup(label="Hide items", choices=[], value=[], visible=False)
|
24 |
+
with gr.Row(equal_height=True):
|
25 |
+
filter_item1 = gr.Dropdown(label="Filter item", choices=[""], value="", visible=False)
|
26 |
+
filter1 = gr.Dropdown(label="Filter", choices=[""], value="", allow_custom_value=True, visible=False)
|
27 |
+
filter_btn = gr.Button("Apply filter", variant="secondary", visible=False)
|
28 |
+
result_df = gr.DataFrame(label="Results", type="array", value=[[]], interactive=False)
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
+
run_button.click(search, [sort, sort_method, filter, author, infer_status, gated_status, appr_status, limit, search_result], [result_df, hide_item, search_result])\
|
31 |
+
.success(update_filter, [filter_item1, search_result], [filter_item1, filter1, filter_btn, search_result], queue=False)
|
32 |
+
gr.on(triggers=[hide_item.change, filter_btn.click], fn=update_df, inputs=[hide_item, filter_item1, filter1, search_result],
|
33 |
+
outputs=[result_df, search_result], trigger_mode="once", queue=False, show_api=False)
|
34 |
+
filter_item1.change(update_filter, [filter_item1, search_result], [filter_item1, filter1, filter_btn, search_result], queue=False, show_api=False)
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
+
demo.queue().launch()
|
|
|
|
|
|
|
|
hfsearch.py
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import spaces
|
2 |
+
import gradio as gr
|
3 |
+
from huggingface_hub import HfApi
|
4 |
+
import gc
|
5 |
+
|
6 |
+
class Labels():
|
7 |
+
VALID_DTYPE = ["str", "number", "bool", "date", "markdown"]
|
8 |
+
|
9 |
+
def __init__(self):
|
10 |
+
self.types = {}
|
11 |
+
self.orders = {}
|
12 |
+
|
13 |
+
def set(self, label: str, type: str="str", order: int=255):
|
14 |
+
if type not in self.VALID_DTYPE: raise Exception(f"Invalid data type: {type}")
|
15 |
+
self.types[label] = type
|
16 |
+
self.orders[label] = order
|
17 |
+
|
18 |
+
def get(self):
|
19 |
+
labels = list(self.types.keys())
|
20 |
+
labels.sort(key=lambda x: self.orders[x])
|
21 |
+
label_types = [self.types[s] for s in labels]
|
22 |
+
return labels, label_types
|
23 |
+
|
24 |
+
def get_null_value(self, type: str):
|
25 |
+
if type == "bool": return False
|
26 |
+
elif type == "number" or type == "date": return 0
|
27 |
+
else: return "None"
|
28 |
+
|
29 |
+
class HFSearchResult():
|
30 |
+
def __init__(self):
|
31 |
+
self.labels = Labels()
|
32 |
+
self.current_item = {}
|
33 |
+
self.current_show_item = {}
|
34 |
+
self.item_list = []
|
35 |
+
self.show_item_list = []
|
36 |
+
self.item_hide_flags = []
|
37 |
+
self.hide_item = []
|
38 |
+
self.filter_items = None
|
39 |
+
self.filters = None
|
40 |
+
gc.collect()
|
41 |
+
|
42 |
+
def reset(self):
|
43 |
+
self.__init__()
|
44 |
+
|
45 |
+
def set(self, data, label: str, type: str="str", order: int=255, show_data=None):
|
46 |
+
self.labels.set(label, type, order)
|
47 |
+
self.current_item[label] = data
|
48 |
+
if show_data is not None: self.current_show_item[label] = show_data
|
49 |
+
|
50 |
+
def next(self):
|
51 |
+
self.item_list.append(self.current_item.copy())
|
52 |
+
self.current_item = {}
|
53 |
+
self.show_item_list.append(self.current_show_item.copy())
|
54 |
+
self.current_show_item = {}
|
55 |
+
|
56 |
+
def get(self):
|
57 |
+
labels, label_types = self.labels.get()
|
58 |
+
df = [[item.get(l, self.labels.get_null_value(t)) for l, t in zip(labels, label_types)] for item in self.item_list]
|
59 |
+
return df, labels, label_types
|
60 |
+
|
61 |
+
def get_show(self):
|
62 |
+
labels, label_types = self.labels.get()
|
63 |
+
self._do_filter()
|
64 |
+
df = [[show_item.get(l, self.labels.get_null_value(t)) if l in show_item.keys() else item.get(l, self.labels.get_null_value(t)) for l, t in zip(labels, label_types) if l not in set(self.hide_item)] for item, show_item, is_hide in zip(self.item_list, self.show_item_list, self.item_hide_flags) if not is_hide]
|
65 |
+
show_label_types = [t for l, t in zip(labels, label_types) if l not in self.hide_item]
|
66 |
+
show_labels = [l for l in labels if l not in self.hide_item]
|
67 |
+
return df, show_labels, show_label_types
|
68 |
+
|
69 |
+
def set_hide(self, hide_item: list):
|
70 |
+
self.hide_item = hide_item
|
71 |
+
|
72 |
+
def set_filter(self, filter_item1: str, filter1: str):
|
73 |
+
if not filter_item1 and not filter1:
|
74 |
+
self.filter_items = None
|
75 |
+
self.filters = None
|
76 |
+
else:
|
77 |
+
self.filter_items = [filter_item1]
|
78 |
+
self.filters = [filter1]
|
79 |
+
|
80 |
+
def _do_filter(self):
|
81 |
+
if self.filters is None or self.filter_items is None:
|
82 |
+
self.item_hide_flags = [False] * len(self.item_list)
|
83 |
+
return
|
84 |
+
labels, label_types = self.labels.get()
|
85 |
+
types = dict(zip(labels, label_types))
|
86 |
+
flags = []
|
87 |
+
for item in self.item_list:
|
88 |
+
flag = False
|
89 |
+
for i, f in zip(self.filter_items, self.filters):
|
90 |
+
if i not in item.keys(): continue
|
91 |
+
t = types[i]
|
92 |
+
if item[i] == self.labels.get_null_value(t):
|
93 |
+
flag = True
|
94 |
+
break
|
95 |
+
if t in set(["str", "markdown"]):
|
96 |
+
if f in item[i]: flag = False
|
97 |
+
else:
|
98 |
+
flag = True
|
99 |
+
break
|
100 |
+
flags.append(flag)
|
101 |
+
self.item_hide_flags = flags
|
102 |
+
|
103 |
+
def get_gr_df(self):
|
104 |
+
df, labels, label_types = self.get_show()
|
105 |
+
return gr.update(type="array", value=df, headers=labels, datatype=label_types)
|
106 |
+
|
107 |
+
def get_gr_hide_item(self):
|
108 |
+
return gr.update(choices=self.labels.get()[0], value=[], visible=True)
|
109 |
+
|
110 |
+
def get_gr_filter_item(self, filter_item: str=""):
|
111 |
+
labels, label_types = self.labels.get()
|
112 |
+
choices = [s for s, t in zip(labels, label_types) if t in set(["str", "markdown"])]
|
113 |
+
if len(choices) == 0: choices = [""]
|
114 |
+
return gr.update(choices=choices, value=filter_item if filter_item else choices[0], visible=True)
|
115 |
+
|
116 |
+
def get_gr_filter(self, filter_item: str=""):
|
117 |
+
labels = self.labels.get()[0]
|
118 |
+
if not filter_item or filter_item not in set(labels): return gr.update(choices=[""], value="", visible=True)
|
119 |
+
d = {}
|
120 |
+
for item in self.item_list:
|
121 |
+
if filter_item not in item.keys(): continue
|
122 |
+
v = item[filter_item]
|
123 |
+
if v in d.keys(): d[v] += 1
|
124 |
+
else: d[v] = 1
|
125 |
+
return gr.update(choices=[""] + [t[0] for t in sorted(d.items(), key=lambda x : x[1])][:100], value="", visible=True)
|
126 |
+
|
127 |
+
def md_lb(s: str, count: int):
|
128 |
+
return "<br>".join([s[i:i+count] for i in range(0, len(s), count)])
|
129 |
+
|
130 |
+
# https://huggingface.co/docs/huggingface_hub/package_reference/hf_api
|
131 |
+
# https://huggingface.co/docs/huggingface_hub/package_reference/hf_api#huggingface_hub.ModelInfo
|
132 |
+
@spaces.GPU
|
133 |
+
def search(sort: str, sort_method: str, filter: str, author: str, infer: str, gated: str, appr: list[str], limit: int, r: HFSearchResult):
|
134 |
+
try:
|
135 |
+
api = HfApi()
|
136 |
+
kwargs = {}
|
137 |
+
if filter: kwargs["filter"] = filter
|
138 |
+
if author: kwargs["author"] = author
|
139 |
+
if gated == "gated": kwargs["gated"] = True
|
140 |
+
elif gated == "non-gated": kwargs["gated"] = False
|
141 |
+
if infer != "all": kwargs["inference"] = infer
|
142 |
+
if sort_method == "descending order": kwargs["direction"] = -1
|
143 |
+
if limit > 0: kwargs["limit"] = limit
|
144 |
+
models = api.list_models(sort=sort, cardData=True, full=True, **kwargs)
|
145 |
+
r.reset()
|
146 |
+
i = 1
|
147 |
+
for model in models:
|
148 |
+
if model.gated is not None and model.gated and model.gated not in appr: continue
|
149 |
+
r.set(i, "No.", "number", 0)
|
150 |
+
r.set(model.id, "Model", "markdown", 2, f"[{md_lb(model.id, 48)}](https://hf.co/{model.id})")
|
151 |
+
if model.inference is not None: r.set(model.inference, "Status", "markdown", 4, md_lb(model.inference, 8))
|
152 |
+
#if infer != "all": r.set(infer, "Status", "markdown", 4)
|
153 |
+
if model.gated is not None: r.set(model.gated if model.gated else "off", "Gated", "str", 6)
|
154 |
+
#if gated != "all": r.set("on" if gated == "gated" else "off", "Gated", "str", 6)
|
155 |
+
if model.library_name is not None: r.set(model.library_name, "Library", "markdown", 10, md_lb(model.library_name, 12))
|
156 |
+
if model.pipeline_tag is not None: r.set(model.pipeline_tag, "Pipeline", "markdown", 11, md_lb(model.pipeline_tag, 15))
|
157 |
+
if model.last_modified is not None: r.set(model.last_modified, "LastMod.", "date", 12)
|
158 |
+
if model.likes is not None: r.set(model.likes, "Likes", "number", 13)
|
159 |
+
if model.downloads is not None: r.set(model.downloads, "DLs", "number", 14)
|
160 |
+
if model.downloads_all_time is not None: r.set(model.downloads_all_time, "AllDLs", "number", 15)
|
161 |
+
r.next()
|
162 |
+
i += 1
|
163 |
+
return r.get_gr_df(), r.get_gr_hide_item(), r
|
164 |
+
except Exception as e:
|
165 |
+
raise gr.Error(e)
|
166 |
+
|
167 |
+
def update_df(hide_item: list, filter_item1: str, filter1: str, r: HFSearchResult):
|
168 |
+
r.set_hide(hide_item)
|
169 |
+
r.set_filter(filter_item1, filter1)
|
170 |
+
return r.get_gr_df(), r
|
171 |
+
|
172 |
+
def update_filter(filter_item1: str, r: HFSearchResult):
|
173 |
+
return r.get_gr_filter_item(filter_item1), r.get_gr_filter(filter_item1), gr.update(visible=True), r
|