Update app.py
Browse files
app.py
CHANGED
@@ -34,6 +34,30 @@ def cached_list_items(username, kind):
|
|
34 |
return []
|
35 |
|
36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
# Rate limiting
|
38 |
class RateLimiter:
|
39 |
def __init__(self, calls_per_second=10):
|
@@ -180,37 +204,99 @@ def make_calendar_heatmap(df, title, year):
|
|
180 |
# Sidebar
|
181 |
with st.sidebar:
|
182 |
st.title("👤 Contributor")
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
year_options = list(range(datetime.now().year, 2017, -1))
|
193 |
-
selected_year = st.selectbox("
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
|
195 |
# Main Content
|
196 |
st.title("🤗 Hugging Face Contributions")
|
197 |
if username:
|
198 |
-
with st.spinner("Fetching commit data..."):
|
199 |
# Create a dictionary to store commits by type
|
200 |
commits_by_type = {}
|
201 |
commit_counts_by_type = {}
|
202 |
-
|
203 |
-
#
|
204 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
try:
|
206 |
items = cached_list_items(username, kind)
|
207 |
repo_ids = [item.id for item in items]
|
|
|
|
|
208 |
|
209 |
# Process repos in chunks
|
210 |
chunk_size = 5
|
211 |
total_commits = 0
|
212 |
all_commit_dates = []
|
213 |
|
|
|
214 |
for i in range(0, len(repo_ids), chunk_size):
|
215 |
chunk = repo_ids[i:i + chunk_size]
|
216 |
with ThreadPoolExecutor(max_workers=min(5, len(chunk))) as executor:
|
@@ -223,6 +309,13 @@ if username:
|
|
223 |
if repo_commits:
|
224 |
all_commit_dates.extend(repo_commits)
|
225 |
total_commits += repo_count
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
|
227 |
commits_by_type[kind] = all_commit_dates
|
228 |
commit_counts_by_type[kind] = total_commits
|
@@ -236,7 +329,20 @@ if username:
|
|
236 |
total_commits = sum(commit_counts_by_type.values())
|
237 |
|
238 |
st.subheader(f"{username}'s Activity in {selected_year}")
|
239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
|
241 |
# Create DataFrame for all commits
|
242 |
all_commits = []
|
@@ -248,26 +354,30 @@ if username:
|
|
248 |
|
249 |
make_calendar_heatmap(all_df, "All Commits", selected_year)
|
250 |
|
251 |
-
# Metrics and heatmaps for each type
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
(
|
256 |
-
(
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
df_kind =
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
|
|
|
|
|
|
|
|
|
34 |
return []
|
35 |
|
36 |
|
37 |
+
# Function to fetch trending model repositories
|
38 |
+
@lru_cache(maxsize=1)
|
39 |
+
def get_trending_accounts(limit=100):
|
40 |
+
try:
|
41 |
+
# Fetch trending models, datasets, and spaces
|
42 |
+
trending_models = list(api.list_models(sort="trending", limit=limit))
|
43 |
+
trending_datasets = list(api.list_datasets(sort="trending", limit=limit))
|
44 |
+
trending_spaces = list(api.list_spaces(sort="trending", limit=limit))
|
45 |
+
|
46 |
+
# Extract unique authors
|
47 |
+
authors = set()
|
48 |
+
for item in trending_models + trending_datasets + trending_spaces:
|
49 |
+
if hasattr(item, "author"):
|
50 |
+
authors.add(item.author)
|
51 |
+
elif hasattr(item, "id") and "/" in item.id:
|
52 |
+
authors.add(item.id.split("/")[0])
|
53 |
+
|
54 |
+
# Return sorted list of unique authors
|
55 |
+
return sorted(list(authors))[:limit]
|
56 |
+
except Exception as e:
|
57 |
+
st.error(f"Error fetching trending accounts: {str(e)}")
|
58 |
+
return ["ritvik77", "facebook", "google", "stabilityai", "Salesforce", "tiiuae", "bigscience"]
|
59 |
+
|
60 |
+
|
61 |
# Rate limiting
|
62 |
class RateLimiter:
|
63 |
def __init__(self, calls_per_second=10):
|
|
|
204 |
# Sidebar
|
205 |
with st.sidebar:
|
206 |
st.title("👤 Contributor")
|
207 |
+
|
208 |
+
# Fetch trending accounts with a loading spinner
|
209 |
+
with st.spinner("Loading top trending accounts..."):
|
210 |
+
trending_accounts = get_trending_accounts(limit=100)
|
211 |
+
|
212 |
+
# Create a tab interface for selection method
|
213 |
+
tab1, tab2 = st.tabs(["Top 100 Trending", "Custom User"])
|
214 |
+
|
215 |
+
with tab1:
|
216 |
+
# Show trending accounts list with search filter
|
217 |
+
st.subheader("🔥 Top Trending Accounts")
|
218 |
+
search_filter = st.text_input("Filter accounts", key="trending_filter")
|
219 |
+
|
220 |
+
# Filter accounts based on search
|
221 |
+
filtered_accounts = [acc for acc in trending_accounts if search_filter.lower() in acc.lower()] if search_filter else trending_accounts
|
222 |
+
|
223 |
+
# Show account count
|
224 |
+
st.caption(f"Showing {len(filtered_accounts)} accounts")
|
225 |
+
|
226 |
+
# Create a scrollable container for the accounts list
|
227 |
+
account_container = st.container()
|
228 |
+
with account_container:
|
229 |
+
selected_trending = st.selectbox(
|
230 |
+
"Select trending account",
|
231 |
+
options=filtered_accounts,
|
232 |
+
index=0 if filtered_accounts else None,
|
233 |
+
key="trending_selectbox"
|
234 |
+
)
|
235 |
+
|
236 |
+
if selected_trending:
|
237 |
+
username = selected_trending
|
238 |
+
|
239 |
+
with tab2:
|
240 |
+
st.subheader("🔎 Custom Account")
|
241 |
+
default_accounts = ["ritvik77", "facebook", "google", "stabilityai", "Salesforce", "tiiuae", "bigscience"]
|
242 |
+
custom_account = st.selectbox(
|
243 |
+
"Select or type a username",
|
244 |
+
options=default_accounts,
|
245 |
+
index=0
|
246 |
+
)
|
247 |
+
st.markdown("<div style='text-align: center; margin: 10px 0;'>OR</div>", unsafe_allow_html=True)
|
248 |
+
custom = st.text_input("", placeholder="Enter custom username/org")
|
249 |
+
if custom.strip():
|
250 |
+
username = custom.strip()
|
251 |
+
elif tab2._active and not tab1._active: # Only set if tab2 is active
|
252 |
+
username = custom_account
|
253 |
+
|
254 |
+
# Year selection (outside tabs to always be visible)
|
255 |
+
st.subheader("🗓️ Time Period")
|
256 |
year_options = list(range(datetime.now().year, 2017, -1))
|
257 |
+
selected_year = st.selectbox("Select Year", options=year_options)
|
258 |
+
|
259 |
+
# Additional options for customization
|
260 |
+
st.subheader("⚙️ Display Options")
|
261 |
+
show_models = st.checkbox("Show Models", value=True)
|
262 |
+
show_datasets = st.checkbox("Show Datasets", value=True)
|
263 |
+
show_spaces = st.checkbox("Show Spaces", value=True)
|
264 |
|
265 |
# Main Content
|
266 |
st.title("🤗 Hugging Face Contributions")
|
267 |
if username:
|
268 |
+
with st.spinner(f"Fetching commit data for {username}..."):
|
269 |
# Create a dictionary to store commits by type
|
270 |
commits_by_type = {}
|
271 |
commit_counts_by_type = {}
|
272 |
+
|
273 |
+
# Determine which types to fetch based on checkboxes
|
274 |
+
types_to_fetch = []
|
275 |
+
if show_models:
|
276 |
+
types_to_fetch.append("model")
|
277 |
+
if show_datasets:
|
278 |
+
types_to_fetch.append("dataset")
|
279 |
+
if show_spaces:
|
280 |
+
types_to_fetch.append("space")
|
281 |
+
|
282 |
+
if not types_to_fetch:
|
283 |
+
st.warning("Please select at least one content type to display (Models, Datasets, or Spaces)")
|
284 |
+
st.stop()
|
285 |
+
|
286 |
+
# Fetch commits for each selected type
|
287 |
+
for kind in types_to_fetch:
|
288 |
try:
|
289 |
items = cached_list_items(username, kind)
|
290 |
repo_ids = [item.id for item in items]
|
291 |
+
|
292 |
+
st.info(f"Found {len(repo_ids)} {kind}s for {username}")
|
293 |
|
294 |
# Process repos in chunks
|
295 |
chunk_size = 5
|
296 |
total_commits = 0
|
297 |
all_commit_dates = []
|
298 |
|
299 |
+
progress_bar = st.progress(0)
|
300 |
for i in range(0, len(repo_ids), chunk_size):
|
301 |
chunk = repo_ids[i:i + chunk_size]
|
302 |
with ThreadPoolExecutor(max_workers=min(5, len(chunk))) as executor:
|
|
|
309 |
if repo_commits:
|
310 |
all_commit_dates.extend(repo_commits)
|
311 |
total_commits += repo_count
|
312 |
+
|
313 |
+
# Update progress
|
314 |
+
progress = min(1.0, (i + len(chunk)) / max(1, len(repo_ids)))
|
315 |
+
progress_bar.progress(progress)
|
316 |
+
|
317 |
+
# Complete progress
|
318 |
+
progress_bar.progress(1.0)
|
319 |
|
320 |
commits_by_type[kind] = all_commit_dates
|
321 |
commit_counts_by_type[kind] = total_commits
|
|
|
329 |
total_commits = sum(commit_counts_by_type.values())
|
330 |
|
331 |
st.subheader(f"{username}'s Activity in {selected_year}")
|
332 |
+
|
333 |
+
# Profile information
|
334 |
+
profile_col1, profile_col2 = st.columns([1, 3])
|
335 |
+
with profile_col1:
|
336 |
+
# Try to get avatar
|
337 |
+
try:
|
338 |
+
avatar_url = f"https://huggingface.co/avatars/{username}"
|
339 |
+
st.image(avatar_url, width=150)
|
340 |
+
except:
|
341 |
+
st.info("No profile image available")
|
342 |
+
|
343 |
+
with profile_col2:
|
344 |
+
st.metric("Total Commits", total_commits)
|
345 |
+
st.markdown(f"[View Profile on Hugging Face](https://huggingface.co/{username})")
|
346 |
|
347 |
# Create DataFrame for all commits
|
348 |
all_commits = []
|
|
|
354 |
|
355 |
make_calendar_heatmap(all_df, "All Commits", selected_year)
|
356 |
|
357 |
+
# Metrics and heatmaps for each selected type
|
358 |
+
cols = st.columns(len(types_to_fetch)) if types_to_fetch else st.columns(1)
|
359 |
+
|
360 |
+
for i, (kind, emoji, label) in enumerate([
|
361 |
+
("model", "🧠", "Models"),
|
362 |
+
("dataset", "📦", "Datasets"),
|
363 |
+
("space", "🚀", "Spaces")
|
364 |
+
]):
|
365 |
+
if kind in types_to_fetch:
|
366 |
+
with cols[types_to_fetch.index(kind)]:
|
367 |
+
try:
|
368 |
+
total = len(cached_list_items(username, kind))
|
369 |
+
commits = commits_by_type.get(kind, [])
|
370 |
+
commit_count = commit_counts_by_type.get(kind, 0)
|
371 |
+
df_kind = pd.DataFrame(commits, columns=["date"])
|
372 |
+
if not df_kind.empty:
|
373 |
+
df_kind = df_kind.drop_duplicates() # Remove any duplicate dates
|
374 |
+
st.metric(f"{emoji} {label}", total)
|
375 |
+
st.metric(f"Commits in {selected_year}", commit_count)
|
376 |
+
make_calendar_heatmap(df_kind, f"{label} Commits", selected_year)
|
377 |
+
except Exception as e:
|
378 |
+
st.warning(f"Error processing {label}: {str(e)}")
|
379 |
+
st.metric(f"{emoji} {label}", 0)
|
380 |
+
st.metric(f"Commits in {selected_year}", 0)
|
381 |
+
make_calendar_heatmap(pd.DataFrame(), f"{label} Commits", selected_year)
|
382 |
+
else:
|
383 |
+
st.info("Please select an account from the sidebar to view contributions.")
|