ginipick commited on
Commit
ee4c075
·
verified ·
1 Parent(s): 0d08829

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -37
app.py CHANGED
@@ -25,9 +25,8 @@ def create_trend_chart(space_id, daily_ranks_df):
25
  markers=True
26
  )
27
 
28
- # 차트를 더 크게 설정
29
  fig.update_layout(
30
- height=500, # 높이 증가
31
  xaxis_title="Date",
32
  yaxis_title="Rank",
33
  yaxis=dict(
@@ -40,7 +39,7 @@ def create_trend_chart(space_id, daily_ranks_df):
40
  plot_bgcolor='white',
41
  paper_bgcolor='white',
42
  showlegend=False,
43
- margin=dict(t=50, r=20, b=40, l=40) # 여백 조정
44
  )
45
 
46
  fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='lightgray')
@@ -59,7 +58,9 @@ def create_trend_chart(space_id, daily_ranks_df):
59
 
60
  def create_space_card(space_info):
61
  return f"""
62
- <div style="
 
 
63
  border: 1px solid #e5e7eb;
64
  border-radius: 8px;
65
  padding: 16px;
@@ -69,14 +70,20 @@ def create_space_card(space_info):
69
  display: inline-block;
70
  width: 250px;
71
  vertical-align: top;
72
- ">
 
 
 
 
 
73
  <div style="font-size: 1.2em; font-weight: bold; margin-bottom: 8px;">
74
  #{int(space_info['rank'])}
75
  </div>
76
  <div style="margin-bottom: 8px;">
77
  <a href="https://huggingface.co/spaces/{space_info['id']}"
78
  target="_blank"
79
- style="color: #2563eb; text-decoration: none;">
 
80
  {space_info['id']}
81
  <span style="font-size: 0.8em;">↗</span>
82
  </a>
@@ -91,7 +98,7 @@ def update_display(selection):
91
  global daily_ranks_df
92
 
93
  if not selection:
94
- return None, "Please select a space"
95
 
96
  try:
97
  space_id = selection
@@ -100,7 +107,6 @@ def update_display(selection):
100
  daily_ranks_df['id'] == space_id
101
  ].sort_values('date').iloc[-1]
102
 
103
- # HTML로 포맷팅된 정보 텍스트
104
  info_text = f"""
105
  <div style="padding: 16px; background-color: white; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
106
  <h3 style="margin: 0 0 12px 0;">Space Details</h3>
@@ -124,47 +130,119 @@ def update_display(selection):
124
 
125
  except Exception as e:
126
  print(f"Error in update_display: {e}")
127
- return None, f"Error processing data: {str(e)}"
128
 
129
  def load_and_process_data():
130
- # ... (기존 데이터 로딩 함수는 동일하게 유지)
131
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
 
133
  # 데이터 로드
134
  print("Loading initial data...")
135
  daily_ranks_df, top_100_spaces = load_and_process_data()
136
- print("Data loaded.")
137
 
138
  # Gradio 인터페이스 생성
139
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
140
- gr.Markdown("# Trending Spaces Dashboard")
 
141
 
142
- with gr.Row():
143
- trend_plot = gr.Plot(
144
- label="Daily Rank Trend",
145
- container=True
146
- )
147
 
148
- with gr.Row():
149
- info_box = gr.HTML(
150
- label="Space Details",
151
- value="Select a space to view details"
152
- )
153
 
154
- # 그리드 형태의 스페이스 카드들
155
- with gr.Row():
156
- space_grid = gr.HTML(
157
- value="<div style='display: flex; flex-wrap: wrap; gap: 16px; justify-content: center;'>" +
158
- "".join([create_space_card(row) for _, row in top_100_spaces.iterrows()]) +
159
- "</div>"
160
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
- # 숨겨진 라디오 버튼 (상태 관리용)
163
- space_selection = gr.Radio(
164
- choices=[row['id'] for _, row in top_100_spaces.iterrows()],
165
- value=None,
166
- visible=False
167
- )
 
 
 
 
 
 
 
168
 
169
  # JavaScript를 통한 카드 클릭 이벤트 처리
170
  space_grid.click(
@@ -176,7 +254,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
176
  document.addEventListener('click', function(e) {
177
  if (e.target.closest('.space-card')) {
178
  const spaceId = e.target.closest('.space-card').dataset.spaceId;
179
- // 라디오 버튼 값 업데이트
180
  document.querySelector(`input[type="radio"][value="${spaceId}"]`).click();
181
  }
182
  });
 
25
  markers=True
26
  )
27
 
 
28
  fig.update_layout(
29
+ height=500,
30
  xaxis_title="Date",
31
  yaxis_title="Rank",
32
  yaxis=dict(
 
39
  plot_bgcolor='white',
40
  paper_bgcolor='white',
41
  showlegend=False,
42
+ margin=dict(t=50, r=20, b=40, l=40)
43
  )
44
 
45
  fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='lightgray')
 
58
 
59
  def create_space_card(space_info):
60
  return f"""
61
+ <div class="space-card"
62
+ data-space-id="{space_info['id']}"
63
+ style="
64
  border: 1px solid #e5e7eb;
65
  border-radius: 8px;
66
  padding: 16px;
 
70
  display: inline-block;
71
  width: 250px;
72
  vertical-align: top;
73
+ cursor: pointer;
74
+ transition: all 0.2s;
75
+ "
76
+ onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 4px 6px rgba(0,0,0,0.1)';"
77
+ onmouseout="this.style.transform='none';this.style.boxShadow='0 1px 3px rgba(0,0,0,0.1)';"
78
+ >
79
  <div style="font-size: 1.2em; font-weight: bold; margin-bottom: 8px;">
80
  #{int(space_info['rank'])}
81
  </div>
82
  <div style="margin-bottom: 8px;">
83
  <a href="https://huggingface.co/spaces/{space_info['id']}"
84
  target="_blank"
85
+ style="color: #2563eb; text-decoration: none;"
86
+ onclick="event.stopPropagation();">
87
  {space_info['id']}
88
  <span style="font-size: 0.8em;">↗</span>
89
  </a>
 
98
  global daily_ranks_df
99
 
100
  if not selection:
101
+ return None, gr.HTML(value="<div style='text-align: center; padding: 20px; color: #666;'>Select a space to view details</div>")
102
 
103
  try:
104
  space_id = selection
 
107
  daily_ranks_df['id'] == space_id
108
  ].sort_values('date').iloc[-1]
109
 
 
110
  info_text = f"""
111
  <div style="padding: 16px; background-color: white; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
112
  <h3 style="margin: 0 0 12px 0;">Space Details</h3>
 
130
 
131
  except Exception as e:
132
  print(f"Error in update_display: {e}")
133
+ return None, gr.HTML(value=f"<div style='color: red;'>Error processing data: {str(e)}</div>")
134
 
135
  def load_and_process_data():
136
+ try:
137
+ url = "https://huggingface.co/datasets/cfahlgren1/hub-stats/resolve/main/spaces.parquet"
138
+ response = requests.get(url)
139
+ df = pd.read_parquet(BytesIO(response.content))
140
+
141
+ # 30일치 데이터 준비
142
+ thirty_days_ago = datetime.now() - timedelta(days=30)
143
+ df['createdAt'] = pd.to_datetime(df['createdAt'])
144
+ df = df[df['createdAt'] >= thirty_days_ago].copy()
145
+
146
+ # 날짜별 데이터 처리
147
+ dates = pd.date_range(start=thirty_days_ago, end=datetime.now(), freq='D')
148
+ daily_ranks = []
149
+
150
+ for date in dates:
151
+ # 해당 날짜의 데이터 추출
152
+ date_data = df[df['createdAt'].dt.date <= date.date()].copy()
153
+
154
+ # trendingScore가 같은 경우 id로 정렬하여 유니크한 순위 보장
155
+ date_data = date_data.sort_values(['trendingScore', 'id'], ascending=[False, True])
156
+
157
+ # 순위 계산
158
+ date_data['rank'] = range(1, len(date_data) + 1)
159
+ date_data['date'] = date.date()
160
+
161
+ # 필요한 컬럼만 선택
162
+ daily_ranks.append(
163
+ date_data[['id', 'date', 'rank', 'trendingScore', 'createdAt']]
164
+ )
165
+
166
+ # 전체 데이터 병합
167
+ daily_ranks_df = pd.concat(daily_ranks, ignore_index=True)
168
+
169
+ # 최신 날짜의 top 100 추출
170
+ latest_date = daily_ranks_df['date'].max()
171
+ top_100_spaces = daily_ranks_df[
172
+ (daily_ranks_df['date'] == latest_date) &
173
+ (daily_ranks_df['rank'] <= 100)
174
+ ].sort_values('rank').copy()
175
+
176
+ return daily_ranks_df, top_100_spaces
177
+ except Exception as e:
178
+ print(f"Error loading data: {e}")
179
+ return pd.DataFrame(), pd.DataFrame()
180
 
181
  # 데이터 로드
182
  print("Loading initial data...")
183
  daily_ranks_df, top_100_spaces = load_and_process_data()
184
+ print("Data loaded successfully!")
185
 
186
  # Gradio 인터페이스 생성
187
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
188
+ gr.Markdown("""
189
+ # HF Space Ranking Tracker
190
 
191
+ Track, analyze, and discover trending AI applications in the Hugging Face ecosystem. Our service continuously monitors and ranks all Spaces over a 30-day period, providing detailed analytics and daily ranking changes for the top 100 performers.
 
 
 
 
192
 
193
+ ### What We Track
194
+ - Daily ranking changes for all Hugging Face Spaces
195
+ - Comprehensive trending scores based on 30-day activity
196
+ - Detailed performance metrics for top 100 Spaces
197
+ - Historical ranking data with daily granularity
198
 
199
+ ### Key Features
200
+ - **Real-time Rankings**: Stay updated with daily rank changes
201
+ - **Interactive Visualizations**: Track ranking trajectories over time
202
+ - **Trend Analysis**: Identify emerging popular AI applications
203
+ - **Direct Access**: Quick links to explore trending Spaces
204
+ - **Performance Metrics**: Detailed trending scores and statistics
205
+ """)
206
+
207
+ with gr.Tabs():
208
+ with gr.Tab("Dashboard"):
209
+ with gr.Row():
210
+ trend_plot = gr.Plot(
211
+ label="Daily Rank Trend",
212
+ container=True
213
+ )
214
+
215
+ with gr.Row():
216
+ info_box = gr.HTML(
217
+ value="<div style='text-align: center; padding: 20px; color: #666;'>Select a space to view details</div>"
218
+ )
219
+
220
+ with gr.Row():
221
+ space_grid = gr.HTML(
222
+ value="<div style='display: flex; flex-wrap: wrap; gap: 16px; justify-content: center;'>" +
223
+ "".join([create_space_card(row) for _, row in top_100_spaces.iterrows()]) +
224
+ "</div>"
225
+ )
226
+
227
+ space_selection = gr.Radio(
228
+ choices=[row['id'] for _, row in top_100_spaces.iterrows()],
229
+ value=None,
230
+ visible=False
231
+ )
232
 
233
+ with gr.Tab("About"):
234
+ gr.Markdown("""
235
+ ### Why Use HF Space Ranking Tracker?
236
+ - Discover trending AI demos and applications
237
+ - Monitor your Space's performance and popularity
238
+ - Identify emerging trends in the AI community
239
+ - Make data-driven decisions about your AI projects
240
+ - Stay ahead of the curve in AI application development
241
+
242
+ Our dashboard provides a comprehensive view of the Hugging Face Spaces ecosystem, helping developers, researchers, and enthusiasts track and understand the dynamics of popular AI applications. Whether you're monitoring your own Space's performance or discovering new trending applications, HF Space Ranking Tracker offers the insights you need.
243
+
244
+ Experience the pulse of the AI community through our daily updated rankings and discover what's making waves in the world of practical AI applications.
245
+ """)
246
 
247
  # JavaScript를 통한 카드 클릭 이벤트 처리
248
  space_grid.click(
 
254
  document.addEventListener('click', function(e) {
255
  if (e.target.closest('.space-card')) {
256
  const spaceId = e.target.closest('.space-card').dataset.spaceId;
 
257
  document.querySelector(`input[type="radio"][value="${spaceId}"]`).click();
258
  }
259
  });