kz209 commited on
Commit
5faa1d3
·
1 Parent(s): d4f8072

cklean up interfaces

Browse files
Files changed (1) hide show
  1. app.py +26 -46
app.py CHANGED
@@ -1,5 +1,4 @@
1
  import os
2
-
3
  import gradio as gr
4
  import pandas as pd
5
  import plotly.express as px
@@ -15,13 +14,15 @@ def run_shell_script(secret_key):
15
  # 记得在 Space 的 Settings -> Variables and secrets 里设置一个环境变量叫 "RUN_KEY"
16
  expected_key = os.environ.get("RUN_KEY")
17
 
 
 
 
18
  if secret_key != expected_key:
19
  return "❌ 鉴权失败:暗号错误!"
20
 
21
  print("收到指令,开始运行脚本...")
22
 
23
  # 2. 核心:运行 .sh 文件
24
- # capture_output=True 可以让我们看到脚本输出的日志
25
  try:
26
  result = subprocess.run(
27
  ["./gpu_info_collector.sh"],
@@ -30,25 +31,16 @@ def run_shell_script(secret_key):
30
  text=True
31
  )
32
  log_output = f"Standard Output:\n{result.stdout}\n\nError Output:\n{result.stderr}"
33
- print(log_output) # 这会打印到 Space 的 Logs 里
34
  return f"✅ 脚本运行完毕!\n{log_output}"
35
  except Exception as e:
36
  return f"⚠️ 运行出错: {str(e)}"
37
 
38
-
39
-
40
  # ==========================================
41
  # 1. Data Reading Engine
42
  # ==========================================
43
 
44
-
45
  def clean_and_read_file(file_path):
46
- """
47
- Robust file reader:
48
- 1. Handles .xlsx masquerading as .csv
49
- 2. Cleans garbage tags like
50
- 3. Fixes broken lines
51
- """
52
  if not file_path or not os.path.exists(file_path):
53
  return pd.DataFrame()
54
 
@@ -122,7 +114,6 @@ def clean_and_read_file(file_path):
122
  # 2. Data Processing
123
  # ==========================================
124
 
125
-
126
  def process_gpu_data(df):
127
  if df.empty:
128
  return df
@@ -168,7 +159,6 @@ def process_llm_data(df):
168
  # 3. Plotting Logic
169
  # ==========================================
170
 
171
-
172
  def plot_gpu_trends(df):
173
  if df is None or df.empty or 'Rent_Price_Num' not in df.columns:
174
  return None
@@ -177,7 +167,8 @@ def plot_gpu_trends(df):
177
  if plot_df.empty:
178
  return None
179
 
180
- chip_col = 'Chip' if 'Chip' in df.columns else df.columns[1]
 
181
 
182
  fig = px.line(plot_df,
183
  x='Date',
@@ -192,18 +183,15 @@ def plot_gpu_trends(df):
192
  return fig
193
 
194
  def plot_llm_trends(df):
195
- """Plot trends for all columns, no selection needed anymore"""
196
  if df is None or df.empty:
197
  return None
198
 
199
- # Automatically select all columns except Date
200
  value_vars = [c for c in df.columns if c != 'Date']
201
  if not value_vars:
202
  return None
203
 
204
  plot_df = df[['Date'] + value_vars].copy().dropna(subset=['Date'])
205
 
206
- # Melt
207
  df_long = plot_df.melt(id_vars=['Date'], var_name='Model', value_name='Price')
208
 
209
  fig = px.line(
@@ -248,10 +236,9 @@ with gr.Blocks(title="AI Price Tracker") as demo:
248
  with gr.Accordion("Data Preview", open=False):
249
  gpu_table = gr.DataFrame()
250
 
251
- # LLM Tab (Updated: No Filter)
252
  with gr.TabItem("LLM Prices"):
253
  with gr.Row():
254
- # Display chart directly, no column division
255
  with gr.Column(scale=1):
256
  llm_plot = gr.Plot(label="Price Trend")
257
 
@@ -261,39 +248,32 @@ with gr.Blocks(title="AI Price Tracker") as demo:
261
 
262
  # --- Initialization Logic ---
263
  def init_on_load():
264
- # Load GPU
265
  g_df, g_fig = load_gpu_pipeline()
266
-
267
- # Load LLM (No checkbox needed anymore)
268
  l_df, l_fig = load_llm_pipeline()
 
269
 
270
- return (
271
- g_fig, # gpu_plot
272
- g_df, # gpu_table
273
- l_fig, # llm_plot
274
- l_df # llm_table
275
- )
276
-
277
- # Bind load event
278
  demo.load(
279
  init_on_load,
280
  inputs=None,
281
- outputs=[
282
- gpu_plot,
283
- gpu_table,
284
- llm_plot,
285
- llm_table
286
- ]
287
  )
288
 
289
- # Create a hidden Gradio Interface for the API endpoint
290
- # This will automatically generate an API endpoint for run_shell_script
291
- gr.Interface(
292
- fn=run_shell_script,
293
- inputs=gr.Textbox(label="Secret Key", type="password"),
294
- outputs=gr.Textbox(label="Script Output"),
295
- api_name="run_collector", # Explicitly set API name
296
- )
 
 
 
 
 
 
 
 
297
 
298
  if __name__ == "__main__":
299
- demo.launch(share=True)
 
1
  import os
 
2
  import gradio as gr
3
  import pandas as pd
4
  import plotly.express as px
 
14
  # 记得在 Space 的 Settings -> Variables and secrets 里设置一个环境变量叫 "RUN_KEY"
15
  expected_key = os.environ.get("RUN_KEY")
16
 
17
+ if not expected_key:
18
+ return "❌ 鉴权失败:服务端未配置 RUN_KEY 环境变量!"
19
+
20
  if secret_key != expected_key:
21
  return "❌ 鉴权失败:暗号错误!"
22
 
23
  print("收到指令,开始运行脚本...")
24
 
25
  # 2. 核心:运行 .sh 文件
 
26
  try:
27
  result = subprocess.run(
28
  ["./gpu_info_collector.sh"],
 
31
  text=True
32
  )
33
  log_output = f"Standard Output:\n{result.stdout}\n\nError Output:\n{result.stderr}"
34
+ print(log_output)
35
  return f"✅ 脚本运行完毕!\n{log_output}"
36
  except Exception as e:
37
  return f"⚠️ 运行出错: {str(e)}"
38
 
 
 
39
  # ==========================================
40
  # 1. Data Reading Engine
41
  # ==========================================
42
 
 
43
  def clean_and_read_file(file_path):
 
 
 
 
 
 
44
  if not file_path or not os.path.exists(file_path):
45
  return pd.DataFrame()
46
 
 
114
  # 2. Data Processing
115
  # ==========================================
116
 
 
117
  def process_gpu_data(df):
118
  if df.empty:
119
  return df
 
159
  # 3. Plotting Logic
160
  # ==========================================
161
 
 
162
  def plot_gpu_trends(df):
163
  if df is None or df.empty or 'Rent_Price_Num' not in df.columns:
164
  return None
 
167
  if plot_df.empty:
168
  return None
169
 
170
+ # 防御性修复:防止 df 列数不够导致 Index 出界
171
+ chip_col = 'Chip' if 'Chip' in df.columns else (df.columns[1] if len(df.columns) > 1 else None)
172
 
173
  fig = px.line(plot_df,
174
  x='Date',
 
183
  return fig
184
 
185
  def plot_llm_trends(df):
 
186
  if df is None or df.empty:
187
  return None
188
 
 
189
  value_vars = [c for c in df.columns if c != 'Date']
190
  if not value_vars:
191
  return None
192
 
193
  plot_df = df[['Date'] + value_vars].copy().dropna(subset=['Date'])
194
 
 
195
  df_long = plot_df.melt(id_vars=['Date'], var_name='Model', value_name='Price')
196
 
197
  fig = px.line(
 
236
  with gr.Accordion("Data Preview", open=False):
237
  gpu_table = gr.DataFrame()
238
 
239
+ # LLM Tab
240
  with gr.TabItem("LLM Prices"):
241
  with gr.Row():
 
242
  with gr.Column(scale=1):
243
  llm_plot = gr.Plot(label="Price Trend")
244
 
 
248
 
249
  # --- Initialization Logic ---
250
  def init_on_load():
 
251
  g_df, g_fig = load_gpu_pipeline()
 
 
252
  l_df, l_fig = load_llm_pipeline()
253
+ return g_fig, g_df, l_fig, l_df
254
 
 
 
 
 
 
 
 
 
255
  demo.load(
256
  init_on_load,
257
  inputs=None,
258
+ outputs=[gpu_plot, gpu_table, llm_plot, llm_table]
 
 
 
 
 
259
  )
260
 
261
+ # ---------------- 修复区 ----------------
262
+ # 替换原本违规的 gr.Interface 为一个隐形的组件组 (visible=False)
263
+ # 这样可以在不破坏 UI 布局的前提下,成功暴露名为 "run_collector" 的 API
264
+ with gr.Group(visible=False):
265
+ api_input = gr.Textbox(label="Secret Key")
266
+ api_output = gr.Textbox(label="Script Output")
267
+ api_btn = gr.Button("Run")
268
+
269
+ # 绑定点击事件并赋予 API Name
270
+ api_btn.click(
271
+ fn=run_shell_script,
272
+ inputs=api_input,
273
+ outputs=api_output,
274
+ api_name="run_collector"
275
+ )
276
+ # ----------------------------------------
277
 
278
  if __name__ == "__main__":
279
+ demo.launch(share=True)