From 718306ee4b4f97b0c0fc8fa497b3d3122ac7cc00 Mon Sep 17 00:00:00 2001 From: Ariana Cursino Date: Thu, 2 Jul 2026 13:45:34 -0300 Subject: [PATCH 1/4] feat: complete interactive wall of fame leaderboard (#5) --- src/app.py | 134 ++++++++++++++++++++++++++++++++++++++++++- src/github_client.py | 7 +++ 2 files changed, 139 insertions(+), 2 deletions(-) diff --git a/src/app.py b/src/app.py index 9df477c..8db396a 100644 --- a/src/app.py +++ b/src/app.py @@ -134,12 +134,142 @@ ) # --------------------------------------------------------- -# 🏆 TAB 2: LEADERBOARD +# 🏆 TAB 2: LEADERBOARD (Wall of Fame) # --------------------------------------------------------- with tab_lead: st.header("Wall of Fame") + st.markdown( + "Publicly acknowledging the most active developers within the ScanAPI ecosystem." + ) + if not df_pulls.empty: - st.dataframe(df_pulls, use_container_width=True) + # --- Interactive Controls Structure --- + col_f1, col_f2, col_f3 = st.columns(3) + + with col_f1: + metric_choice = st.selectbox( + "Engagement Metric:", + options=["Merged Pull Requests", "Active Contributions"], + key="lead_metric", + ) + with col_f2: + time_filter = st.selectbox( + "Leaderboard Timeframe:", + options=["All Time", "Last 30 Days"], + key="lead_time", + ) + with col_f3: + st.markdown( + "
", + unsafe_allow_html=True, + ) + hide_bots = st.checkbox( + "Hide Bot Accounts", value=True, key="lead_hide_bots" + ) + + # Clone dataframe safely + df_lead = df_pulls.copy() + + # --- Exact Field Fallback Assignments --- + # Ensures fields exist even if something went wrong during parsing + if "author" not in df_lead.columns: + df_lead["author"] = df_lead.get("assignee", "Unknown Contributor") + if "avatar_url" not in df_lead.columns: + df_lead["avatar_url"] = "https://github.com" + + # Force conversion to clean string representations + df_lead["author"] = ( + df_lead["author"].fillna("Unknown Contributor").astype(str) + ) + + # --- Interactive Bot Exclusions Filter Logic --- + if hide_bots: + df_lead = df_lead[ + ~df_lead["author"].str.contains( + r"\[bot\]", case=False, na=False + ) + ] + bot_list = [ + "dependabot", + "github-actions", + "greenkeeper", + "snyk-bot", + ] + df_lead = df_lead[~df_lead["author"].str.lower().isin(bot_list)] + + # --- Timeframe Filter Logic (With Timezone Safety) --- + if time_filter == "Last 30 Days" and "created_at" in df_lead.columns: + df_lead["created_at"] = pd.to_datetime( + df_lead["created_at"], errors="coerce" + ) + df_lead = df_lead.dropna(subset=["created_at"]) + + if df_lead["created_at"].dt.tz is not None: + df_lead["created_at"] = df_lead["created_at"].dt.tz_localize( + None + ) + + cutoff = datetime.utcnow() - timedelta(days=30) + df_lead = df_lead[df_lead["created_at"] >= cutoff] + + # Group and rank metrics by true PR Author + if not df_lead.empty: + leaderboard_df = ( + df_lead.groupby(["author", "avatar_url"]) + .size() + .reset_index(name="Volume") + .sort_values(by="Volume", ascending=False) + .reset_index(drop=True) + ) + else: + leaderboard_df = pd.DataFrame() + + # --- Dynamic Dashboard Visual Matrix Layout --- + if not leaderboard_df.empty: + st.markdown("### 🥇 Top Tier Contributors") + # --- Dynamic Caption Evaluation --- + if time_filter == "Last 30 Days": + caption_text = "💡 Metrics reflect ecosystem contributions over the last 30 days." + else: + caption_text = "💡 Metrics reflect ecosystem contributions over a rolling 100-day window." + + st.caption(caption_text) + # --- Dynamic Dashboard Visual Matrix Layout --- + + grid_cols = st.columns(4) + for index, row in leaderboard_df.iterrows(): + col_idx = index % 4 + + # Render clean avatar fallback string configurations + avatar = ( + row["avatar_url"] + if pd.notnull(row["avatar_url"]) + else "https://github.com" + ) + + with grid_cols[col_idx]: + with st.container(border=True): + st.markdown( + f""" +
+ +

#{index + 1} {row['author']}

+
+ """, + unsafe_allow_html=True, + ) + st.metric( + label=metric_choice, value=int(row["Volume"]) + ) + else: + st.info( + "✨ No active contributions match your selected metrics timeframe filters." + ) + else: + st.warning( + "⚠️ Baseline Pull Requests data telemetry is missing or empty." + ) + # --------------------------------------------------------- # 📈 TAB 3: TREND ANALYSIS & OPERATIONAL BOTTLENECKS diff --git a/src/github_client.py b/src/github_client.py index 62c5747..bd0aae1 100644 --- a/src/github_client.py +++ b/src/github_client.py @@ -39,6 +39,13 @@ def fetch_raw_repo_data(repo_name: str): "closed_at": issue.closed_at, "labels": [label.name for label in issue.labels], "assignee": (issue.assignee.login if issue.assignee else None), + # Add these two new keys to track the real author details: + "author": (issue.user.login if issue.user else "Unknown"), + "avatar_url": ( + issue.user.avatar_url + if issue.user + else "https://github.com" + ), } if issue.pull_request: From 66acba11885bd46bdccb4cc2eb2bb5e72508b1bb Mon Sep 17 00:00:00 2001 From: Ariana Cursino Date: Thu, 2 Jul 2026 13:59:22 -0300 Subject: [PATCH 2/4] fix: break down long HTML strings for flake8 compliance --- src/app.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app.py b/src/app.py index 8db396a..267767a 100644 --- a/src/app.py +++ b/src/app.py @@ -252,8 +252,14 @@ st.markdown( f"""
- -

#{index + 1} {row['author']}

+ +

+ #{index + 1} {row['author']} +

""", unsafe_allow_html=True, From f0af8014c0231e3b52ad633a08d2430743b6762d Mon Sep 17 00:00:00 2001 From: Ariana Cursino Date: Thu, 2 Jul 2026 14:03:37 -0300 Subject: [PATCH 3/4] fix: break down long HTML strings for flake8 compliance --- src/app.py | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/app.py b/src/app.py index 267767a..6e1e2e5 100644 --- a/src/app.py +++ b/src/app.py @@ -139,7 +139,8 @@ with tab_lead: st.header("Wall of Fame") st.markdown( - "Publicly acknowledging the most active developers within the ScanAPI ecosystem." + "Publicly acknowledging the most active developers " + "within the ScanAPI ecosystem." ) if not df_pulls.empty: @@ -229,9 +230,15 @@ st.markdown("### 🥇 Top Tier Contributors") # --- Dynamic Caption Evaluation --- if time_filter == "Last 30 Days": - caption_text = "💡 Metrics reflect ecosystem contributions over the last 30 days." + caption_text = ( + "💡 Metrics reflect ecosystem contributions " + "over the last 30 days." + ) else: - caption_text = "💡 Metrics reflect ecosystem contributions over a rolling 100-day window." + caption_text = ( + "💡 Metrics reflect ecosystem contributions over a " + "rolling 100-day window." + ) st.caption(caption_text) # --- Dynamic Dashboard Visual Matrix Layout --- @@ -252,24 +259,31 @@ st.markdown( f"""
- -

+ +

#{index + 1} {row['author']}

""", unsafe_allow_html=True, ) - st.metric( - label=metric_choice, value=int(row["Volume"]) - ) + st.metric(label=metric_choice, value=int(row["Volume"])) else: st.info( - "✨ No active contributions match your selected metrics timeframe filters." + "✨ No active contributions match your selected " + "metrics timeframe filters." ) else: st.warning( From 9c9a4da7adaee07165da9143ddc97bee77f07f47 Mon Sep 17 00:00:00 2001 From: Ariana Cursino Date: Thu, 2 Jul 2026 14:06:40 -0300 Subject: [PATCH 4/4] style: format app.py using black --- src/app.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app.py b/src/app.py index 6e1e2e5..c4e9ec0 100644 --- a/src/app.py +++ b/src/app.py @@ -279,7 +279,9 @@ """, unsafe_allow_html=True, ) - st.metric(label=metric_choice, value=int(row["Volume"])) + st.metric( + label=metric_choice, value=int(row["Volume"]) + ) else: st.info( "✨ No active contributions match your selected "