linxinhua commited on
Commit
e23938f
·
verified ·
1 Parent(s): b4f12ab

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -18
app.py CHANGED
@@ -3,24 +3,38 @@ import pandas as pd
3
  from datetime import datetime, timedelta
4
  import io
5
  import os
6
- from huggingface_hub import HfApi, hf_hub_download
7
  from typing import List, Tuple, Optional
8
  import tempfile
9
  import zipfile
10
 
11
  class DataManager:
12
- def __init__(self):
13
  self.repo_id = "CIV3283/Data_Storage"
14
  self.branch = "data_branch"
15
- self.api = HfApi()
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  def get_available_files(self) -> Tuple[List[str], List[str]]:
18
  """获取所有可用的feedback和query文件"""
19
  try:
20
- # 获取仓库中的所有文件
21
  repo_files = self.api.list_repo_files(
22
  repo_id=self.repo_id,
23
- revision=self.branch
 
 
24
  )
25
 
26
  feedback_files = []
@@ -35,8 +49,24 @@ class DataManager:
35
  return sorted(feedback_files), sorted(query_files)
36
 
37
  except Exception as e:
38
- print(f"Error getting files: {e}")
39
- return [], []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  def download_and_read_csv(self, filename: str) -> pd.DataFrame:
42
  """下载并读取CSV文件"""
@@ -46,6 +76,8 @@ class DataManager:
46
  repo_id=self.repo_id,
47
  filename=filename,
48
  revision=self.branch,
 
 
49
  cache_dir=tempfile.gettempdir()
50
  )
51
 
@@ -59,7 +91,8 @@ class DataManager:
59
  return df
60
 
61
  except Exception as e:
62
- print(f"Error reading {filename}: {e}")
 
63
  return pd.DataFrame()
64
 
65
  def filter_data_by_date(self, df: pd.DataFrame, start_date: str, end_date: str) -> pd.DataFrame:
@@ -136,12 +169,26 @@ class DataManager:
136
  else:
137
  return "", "", "❌ 没有找到符合条件的数据"
138
 
139
- # 初始化数据管理器
140
- data_manager = DataManager()
 
 
 
 
 
 
141
 
142
- def process_and_download(file_type, start_date, end_date):
143
  """处理请求并返回下载文件"""
144
  try:
 
 
 
 
 
 
 
 
145
  csv_content, filename, status = data_manager.process_files(file_type, start_date, end_date)
146
 
147
  if csv_content:
@@ -157,14 +204,30 @@ def process_and_download(file_type, start_date, end_date):
157
  except Exception as e:
158
  return f"❌ 处理过程中出现错误: {str(e)}", None, None
159
 
160
- def get_file_summary():
161
  """获取文件概览"""
162
  try:
 
 
 
 
 
 
 
 
163
  feedback_files, query_files = data_manager.get_available_files()
164
  summary = f"📁 当前可用文件:\n"
165
  summary += f" 反馈文件: {len(feedback_files)} 个\n"
166
  summary += f" 查询文件: {len(query_files)} 个\n"
167
  summary += f" 总计: {len(feedback_files) + len(query_files)} 个文件"
 
 
 
 
 
 
 
 
168
  return summary
169
  except Exception as e:
170
  return f"❌ 获取文件列表失败: {str(e)}"
@@ -175,18 +238,41 @@ def create_interface():
175
  gr.Markdown("# 🗃️ CIV3283 数据存储管理器")
176
  gr.Markdown("从 Hugging Face Space 的 data_branch 分支整理和下载学生数据")
177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  # 文件概览
179
  with gr.Row():
180
  file_summary = gr.Textbox(
181
  label="📊 文件概览",
182
- value=get_file_summary(),
183
  interactive=False,
184
- max_lines=5
185
  )
186
  refresh_btn = gr.Button("🔄 刷新文件列表", variant="secondary")
187
 
 
 
 
 
 
 
188
  refresh_btn.click(
189
  fn=get_file_summary,
 
190
  outputs=file_summary
191
  )
192
 
@@ -230,6 +316,11 @@ def create_interface():
230
  # 使用说明
231
  with gr.Accordion("📖 使用说明", open=False):
232
  gr.Markdown("""
 
 
 
 
 
233
  ### 功能说明
234
  1. **文件类型选择**: 选择要导出的数据类型
235
  - 查询文件: 包含搜索信息和查询响应
@@ -249,12 +340,13 @@ def create_interface():
249
  - 时间戳格式: 2025-06-16 08:55:33
250
  - 导出的数据保持原始顺序,不进行时间排序
251
  - 每次处理会显示详细的文件统计信息
 
252
  """)
253
 
254
  # 绑定处理函数
255
  process_btn.click(
256
  fn=process_and_download,
257
- inputs=[file_type, start_date, end_date],
258
  outputs=[status_box, download_file, gr.State()]
259
  )
260
 
@@ -264,7 +356,4 @@ def create_interface():
264
  if __name__ == "__main__":
265
  demo = create_interface()
266
  demo.launch(
267
- server_name="0.0.0.0",
268
- server_port=7860,
269
- share=True
270
  )
 
3
  from datetime import datetime, timedelta
4
  import io
5
  import os
6
+ from huggingface_hub import HfApi, hf_hub_download, login
7
  from typing import List, Tuple, Optional
8
  import tempfile
9
  import zipfile
10
 
11
  class DataManager:
12
+ def __init__(self, token=None):
13
  self.repo_id = "CIV3283/Data_Storage"
14
  self.branch = "data_branch"
15
+
16
+ # 优先使用传入的token,否则从环境变量获取
17
+ self.token = token or os.getenv('CIV3283_access')
18
+
19
+ # 如果有token,进行认证
20
+ if self.token:
21
+ try:
22
+ login(token=self.token)
23
+ print("✅ 认证成功")
24
+ except Exception as e:
25
+ print(f"❌ 认证失败: {e}")
26
+
27
+ self.api = HfApi(token=self.token)
28
 
29
  def get_available_files(self) -> Tuple[List[str], List[str]]:
30
  """获取所有可用的feedback和query文件"""
31
  try:
32
+ # 尝试获取仓库中的所有文件
33
  repo_files = self.api.list_repo_files(
34
  repo_id=self.repo_id,
35
+ revision=self.branch,
36
+ token=self.token,
37
+ repo_type="space" # 明确指定这是一个space
38
  )
39
 
40
  feedback_files = []
 
49
  return sorted(feedback_files), sorted(query_files)
50
 
51
  except Exception as e:
52
+ print(f"❌ 获取文件列表错误: {e}")
53
+ # 如果API调用失败,尝试手动生成可能的文件名列表
54
+ return self._generate_possible_filenames()
55
+
56
+ def _generate_possible_filenames(self) -> Tuple[List[str], List[str]]:
57
+ """生成可能的文件名列表作为后备方案"""
58
+ feedback_files = []
59
+ query_files = []
60
+
61
+ # 生成01到95的所有可能文件名
62
+ for i in range(1, 96):
63
+ student_id = f"{i:02d}" # 格式化为两位数
64
+ feedback_file = f"CIV3283_Student_{student_id}_feedback_log.csv"
65
+ query_file = f"CIV3283_Student_{student_id}_query_log.csv"
66
+ feedback_files.append(feedback_file)
67
+ query_files.append(query_file)
68
+
69
+ return feedback_files, query_files
70
 
71
  def download_and_read_csv(self, filename: str) -> pd.DataFrame:
72
  """下载并读取CSV文件"""
 
76
  repo_id=self.repo_id,
77
  filename=filename,
78
  revision=self.branch,
79
+ repo_type="space",
80
+ token=self.token,
81
  cache_dir=tempfile.gettempdir()
82
  )
83
 
 
91
  return df
92
 
93
  except Exception as e:
94
+ print(f"❌ 读取文件 {filename} 失败: {e}")
95
+ # 返回空DataFrame而不是完全失败
96
  return pd.DataFrame()
97
 
98
  def filter_data_by_date(self, df: pd.DataFrame, start_date: str, end_date: str) -> pd.DataFrame:
 
169
  else:
170
  return "", "", "❌ 没有找到符合条件的数据"
171
 
172
+ # 全局变量存储数据管理器
173
+ data_manager = None
174
+
175
+ def initialize_data_manager(hf_token=None):
176
+ """初始化数据管理器"""
177
+ global data_manager
178
+ data_manager = DataManager(token=hf_token)
179
+ return data_manager
180
 
181
+ def process_and_download(file_type, start_date, end_date, hf_token):
182
  """处理请求并返回下载文件"""
183
  try:
184
+ # 确保数据管理器已初始化
185
+ global data_manager
186
+ env_token = os.getenv('CIV3283_access')
187
+ current_token = hf_token or env_token
188
+
189
+ if data_manager is None or data_manager.token != current_token:
190
+ data_manager = initialize_data_manager(current_token)
191
+
192
  csv_content, filename, status = data_manager.process_files(file_type, start_date, end_date)
193
 
194
  if csv_content:
 
204
  except Exception as e:
205
  return f"❌ 处理过程中出现错误: {str(e)}", None, None
206
 
207
+ def get_file_summary(hf_token=None):
208
  """获取文件概览"""
209
  try:
210
+ # 如果还没有初始化或token发生变化,重新初始化
211
+ global data_manager
212
+ env_token = os.getenv('CIV3283_access')
213
+ current_token = hf_token or env_token
214
+
215
+ if data_manager is None or data_manager.token != current_token:
216
+ data_manager = initialize_data_manager(current_token)
217
+
218
  feedback_files, query_files = data_manager.get_available_files()
219
  summary = f"📁 当前可用文件:\n"
220
  summary += f" 反馈文件: {len(feedback_files)} 个\n"
221
  summary += f" 查询文件: {len(query_files)} 个\n"
222
  summary += f" 总计: {len(feedback_files) + len(query_files)} 个文件"
223
+
224
+ if env_token:
225
+ summary += f"\n✅ 使用环境变量 CIV3283_access 认证"
226
+ elif hf_token:
227
+ summary += f"\n✅ 使用手动输入的token认证"
228
+ else:
229
+ summary += f"\n⚠️ 未找到认证token(可能无法访问私有仓库)"
230
+
231
  return summary
232
  except Exception as e:
233
  return f"❌ 获取文件列表失败: {str(e)}"
 
238
  gr.Markdown("# 🗃️ CIV3283 数据存储管理器")
239
  gr.Markdown("从 Hugging Face Space 的 data_branch 分支整理和下载学生数据")
240
 
241
+ # 认证部分
242
+ with gr.Row():
243
+ with gr.Column(scale=3):
244
+ hf_token = gr.Textbox(
245
+ label="🔐 Hugging Face Token (可选)",
246
+ placeholder="hf_xxxxxxxxxxxx",
247
+ type="password",
248
+ info="可选:手动输入token,留空将使用环境变量 CIV3283_access"
249
+ )
250
+ with gr.Column(scale=1):
251
+ gr.Markdown(f"""
252
+ **环境变量状态:**
253
+ {'✅ CIV3283_access 已设置' if os.getenv('CIV3283_access') else '❌ CIV3283_access 未找到'}
254
+ """)
255
+
256
+
257
  # 文件概览
258
  with gr.Row():
259
  file_summary = gr.Textbox(
260
  label="📊 文件概览",
261
+ value="点击刷新按钮获取文件列表",
262
  interactive=False,
263
+ max_lines=6
264
  )
265
  refresh_btn = gr.Button("🔄 刷新文件列表", variant="secondary")
266
 
267
+ # 自动刷新一次(使用环境变量)
268
+ demo.load(
269
+ fn=lambda: get_file_summary(None),
270
+ outputs=file_summary
271
+ )
272
+
273
  refresh_btn.click(
274
  fn=get_file_summary,
275
+ inputs=[hf_token],
276
  outputs=file_summary
277
  )
278
 
 
316
  # 使用说明
317
  with gr.Accordion("📖 使用说明", open=False):
318
  gr.Markdown("""
319
+ ### 认证说明
320
+ - **环境变量优先**: 系统会自动使用环境变量 `CIV3283_access` 中的token
321
+ - **手动覆盖**: 如果需要使用不同的token,可以在上方手动输入
322
+ - **获取token**: 如果需要新token,访问 https://huggingface.co/settings/tokens
323
+
324
  ### 功能说明
325
  1. **文件类型选择**: 选择要导出的数据类型
326
  - 查询文件: 包含搜索信息和查询响应
 
340
  - 时间戳格式: 2025-06-16 08:55:33
341
  - 导出的数据保持原始顺序,不进行时间排序
342
  - 每次处理会显示详细的文件统计信息
343
+ - 如果无法访问仓库API,系统会尝试预设的文件名列表
344
  """)
345
 
346
  # 绑定处理函数
347
  process_btn.click(
348
  fn=process_and_download,
349
+ inputs=[file_type, start_date, end_date, hf_token],
350
  outputs=[status_box, download_file, gr.State()]
351
  )
352
 
 
356
  if __name__ == "__main__":
357
  demo = create_interface()
358
  demo.launch(
 
 
 
359
  )