SonyaX20 commited on
Commit
581381b
·
1 Parent(s): ebbac58
Files changed (3) hide show
  1. README.md +13 -1
  2. app.py +106 -70
  3. requirements.txt +1 -1
README.md CHANGED
@@ -38,4 +38,16 @@ short_description: 课程幻灯片智能理解助手
38
 
39
  ## License
40
 
41
- MIT License
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
  ## License
40
 
41
+ MIT License
42
+
43
+ ## Hugging Face Spaces 部署说明
44
+
45
+ 1. Fork 这个项目到你的 Hugging Face Space
46
+ 2. 在 Space 设置中添加 Secret:
47
+ - 进入 Space 设置页面
48
+ - 找到 "Repository Secrets" 部分
49
+ - 添加新的 secret:
50
+ - 名称:`OPENAI_API_KEY`
51
+ - 值:你的 OpenAI API Key
52
+
53
+ 注意:请勿在代码中直接硬编码 API Key,务必使用 Secrets 功能进行配置。
app.py CHANGED
@@ -10,8 +10,15 @@ import torch
10
  # 加载环境变量
11
  load_dotenv()
12
 
13
- # 初始化 OpenAI 客户端
14
- client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
 
 
 
 
 
 
 
15
 
16
  # 检查是否有 GPU
17
  device = 'cuda' if torch.cuda.is_available() else 'cpu'
@@ -138,79 +145,108 @@ def chat_with_assistant(message, history, slide_text):
138
  history.append((message, f"回答出错: {str(e)}"))
139
  return history
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  # 创建 Gradio 界面
142
  with gr.Blocks(title="课程幻灯片理解助手") as demo:
143
- gr.Markdown(f"# 📚 课程幻灯片理解助手 ({device.upper()} 模式)")
144
- gr.Markdown("上传幻灯片图片,AI 将自动识别内容并提供详细讲解")
145
-
146
- # 存储当前识别的文字,用于对话上下文
147
- current_text = gr.State("")
148
-
149
- with gr.Row():
150
- with gr.Column(scale=1):
151
- image_input = gr.Image(
152
- label="上传幻灯片图片",
153
- type="pil",
154
- sources=["upload", "clipboard"]
155
- )
156
- status_text = gr.Markdown("等待上传图片...")
157
 
158
- with gr.Column(scale=2):
159
- text_output = gr.Textbox(
160
- label="识别的文字内容",
161
- lines=3,
162
- placeholder="上传图片后将显示识别的文字内容..."
163
- )
164
- analysis_output = gr.Textbox(
165
- label="AI 讲解分析",
166
- lines=10,
167
- placeholder="等待分析结果..."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  )
169
-
170
- gr.Markdown("---")
171
- gr.Markdown("### 💬 与 AI 助手对话")
172
- chatbot = gr.Chatbot(
173
- label="对话历史",
174
- height=400,
175
- placeholder="在这里可以看到对话历史..."
176
- )
177
- with gr.Row():
178
- msg = gr.Textbox(
179
- label="输入你的问题",
180
- placeholder="请输入你的问题...",
181
- scale=4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  )
183
- clear = gr.Button("🗑️ 清除对话", scale=1)
184
-
185
- # 设置事件处理
186
- def update_status(image):
187
- return "正在处理图片..." if image is not None else "等待上传图片..."
188
-
189
- image_input.change(
190
- fn=update_status,
191
- inputs=[image_input],
192
- outputs=[status_text]
193
- ).then(
194
- fn=process_image,
195
- inputs=[image_input],
196
- outputs=[text_output, analysis_output]
197
- ).then(
198
- fn=lambda x: x,
199
- inputs=[text_output],
200
- outputs=[current_text]
201
- ).then(
202
- fn=lambda: "处理完成",
203
- outputs=[status_text]
204
- )
205
-
206
- msg.submit(
207
- fn=chat_with_assistant,
208
- inputs=[msg, chatbot, current_text],
209
- outputs=[chatbot],
210
- clear_input=True
211
- )
212
-
213
- clear.click(lambda: ([], ""), outputs=[chatbot, msg])
214
 
215
  # 启动应用
216
  if __name__ == "__main__":
 
10
  # 加载环境变量
11
  load_dotenv()
12
 
13
+ # 修改初始化 OpenAI 客户端的方式
14
+ try:
15
+ openai_api_key = os.getenv('OPENAI_API_KEY')
16
+ if not openai_api_key:
17
+ raise ValueError("No OpenAI API key found")
18
+ client = OpenAI(api_key=openai_api_key)
19
+ except Exception as e:
20
+ print(f"Error initializing OpenAI client: {str(e)}")
21
+ raise
22
 
23
  # 检查是否有 GPU
24
  device = 'cuda' if torch.cuda.is_available() else 'cpu'
 
145
  history.append((message, f"回答出错: {str(e)}"))
146
  return history
147
 
148
+ def check_api_key():
149
+ """检查 API Key 是否已设置"""
150
+ if not os.getenv('OPENAI_API_KEY'):
151
+ return """
152
+ <div style="padding: 1rem; background-color: #ffebee; border-radius: 0.5rem; margin: 1rem 0;">
153
+ <h2 style="color: #c62828;">⚠️ OpenAI API Key 未设置</h2>
154
+ <p>请在 Hugging Face Space 的 Settings 中设置 Repository Secrets:</p>
155
+ <ol>
156
+ <li>进入 Space Settings</li>
157
+ <li>找到 Repository Secrets 部分</li>
158
+ <li>添加名为 OPENAI_API_KEY 的 Secret</li>
159
+ <li>将你的 OpenAI API Key 填入值中</li>
160
+ <li>保存后重新启动 Space</li>
161
+ </ol>
162
+ </div>
163
+ """
164
+ return None
165
+
166
  # 创建 Gradio 界面
167
  with gr.Blocks(title="课程幻灯片理解助手") as demo:
168
+ api_key_error = check_api_key()
169
+ if api_key_error:
170
+ gr.Markdown(api_key_error)
171
+ else:
172
+ gr.Markdown(f"# 📚 课程幻灯片理解助手 ({device.upper()} 模式)")
173
+ gr.Markdown("上传幻灯片图片,AI 将自动识别内容并提供详细讲解")
 
 
 
 
 
 
 
 
174
 
175
+ # 存储当前识别的文字,用于对话上下文
176
+ current_text = gr.State("")
177
+
178
+ with gr.Row():
179
+ with gr.Column(scale=1):
180
+ image_input = gr.Image(
181
+ label="上传幻灯片图片",
182
+ type="pil",
183
+ sources=["upload", "clipboard"]
184
+ )
185
+ status_text = gr.Markdown("等待上传图片...")
186
+
187
+ with gr.Column(scale=2):
188
+ text_output = gr.Textbox(
189
+ label="识别的文字内容",
190
+ lines=3,
191
+ placeholder="上传图片后将显示识别的文字内容..."
192
+ )
193
+ analysis_output = gr.Textbox(
194
+ label="AI 讲解分析",
195
+ lines=10,
196
+ placeholder="等待分析结果..."
197
+ )
198
+
199
+ gr.Markdown("---")
200
+ gr.Markdown("### 💬 与 AI 助手对话")
201
+ chatbot = gr.Chatbot(
202
+ label="对话历史",
203
+ height=400,
204
+ placeholder="在这里可以看到对话历史..."
205
+ )
206
+ with gr.Row():
207
+ msg = gr.Textbox(
208
+ label="输入你的问题",
209
+ placeholder="请输入你的问题...",
210
+ scale=4
211
  )
212
+ clear = gr.Button("🗑️ 清除对话", scale=1)
213
+
214
+ # 设置事件处理
215
+ def update_status(image):
216
+ return "正在处理图片..." if image is not None else "等待上传图片..."
217
+
218
+ image_input.change(
219
+ fn=update_status,
220
+ inputs=[image_input],
221
+ outputs=[status_text]
222
+ ).then(
223
+ fn=process_image,
224
+ inputs=[image_input],
225
+ outputs=[text_output, analysis_output]
226
+ ).then(
227
+ fn=lambda x: x,
228
+ inputs=[text_output],
229
+ outputs=[current_text]
230
+ ).then(
231
+ fn=lambda: "处理完成",
232
+ outputs=[status_text]
233
+ )
234
+
235
+ def chat_and_clear(message, history, slide_text):
236
+ """聊天并清除输入"""
237
+ result = chat_with_assistant(message, history, slide_text)
238
+ return result, "" # 返回对话历史和空字符串来清除输入
239
+
240
+ msg.submit(
241
+ fn=chat_and_clear,
242
+ inputs=[msg, chatbot, current_text],
243
+ outputs=[chatbot, msg] # 添加 msg 作为输出来清除它
244
+ )
245
+
246
+ clear.click(
247
+ fn=lambda: ([], ""),
248
+ outputs=[chatbot, msg]
249
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
 
251
  # 启动应用
252
  if __name__ == "__main__":
requirements.txt CHANGED
@@ -1,5 +1,5 @@
1
  huggingface_hub==0.25.2
2
- gradio>=4.0.0,<5.0.0
3
  easyocr>=1.7.1
4
  python-dotenv>=1.0.0
5
  openai>=1.0.0
 
1
  huggingface_hub==0.25.2
2
+ gradio==4.19.2
3
  easyocr>=1.7.1
4
  python-dotenv>=1.0.0
5
  openai>=1.0.0