3a05chatgpt commited on
Commit
ca9cc44
·
verified ·
1 Parent(s): a87aef6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +18 -38
app.py CHANGED
@@ -1,6 +1,6 @@
1
  import openai
2
  import gradio as gr
3
- import fitz # PyMuPDF
4
  from openai import OpenAI
5
  import traceback
6
 
@@ -12,7 +12,6 @@ client = None
12
  pdf_text = ""
13
 
14
  def set_api_key(user_api_key):
15
- """設定 OpenAI API Key 並初始化客戶端"""
16
  global api_key, client
17
  try:
18
  api_key = user_api_key.strip()
@@ -20,26 +19,21 @@ def set_api_key(user_api_key):
20
  return "❌ API Key 不能為空"
21
 
22
  client = OpenAI(api_key=api_key)
23
-
24
- # 測試 API Key 是否有效
25
  client.chat.completions.create(
26
  model="gpt-4",
27
  messages=[{"role": "user", "content": "你好"}],
28
  max_tokens=5
29
  )
30
-
31
  return "✅ API Key 已設定並驗證成功"
32
  except Exception as e:
33
  return f"❌ API Key 設定失敗: {str(e)}"
34
 
35
  def set_model(model_name):
36
- """設定選擇的模型"""
37
  global selected_model
38
  selected_model = model_name
39
  return f"✅ 模型已選擇:{model_name}"
40
 
41
  def extract_pdf_text(file_path):
42
- """從 PDF 文件中提取文字"""
43
  try:
44
  doc = fitz.open(file_path)
45
  text = ""
@@ -53,99 +47,85 @@ def extract_pdf_text(file_path):
53
  return f"❌ PDF 解析錯誤: {str(e)}"
54
 
55
  def generate_summary(pdf_file):
56
- """從 PDF 內容生成摘要"""
57
  global summary_text, pdf_text
58
-
59
  if not client:
60
- return "❌ 請先設定 OpenAI API Key"
61
-
62
  if not pdf_file:
63
  return "❌ 請先上傳 PDF 文件"
64
-
65
  try:
66
  pdf_text = extract_pdf_text(pdf_file.name)
67
  if not pdf_text.strip():
68
- return "⚠️ 無法解析 PDF 文字,可能為純圖片 PDF 或空白文件。"
69
-
70
- pdf_text_truncated = pdf_text[:8000] # 簡單限制長度
71
  response = client.chat.completions.create(
72
  model=selected_model,
73
  messages=[
74
- {"role": "system", "content": "請將以下 PDF 內容整理為條列式摘要,並用繁體中文回答:"},
75
  {"role": "user", "content": pdf_text_truncated}
76
  ],
77
  temperature=0.3
78
  )
79
-
80
  summary_text = response.choices[0].message.content
81
  return summary_text
82
-
83
  except Exception as e:
84
- print(f"錯誤詳情: {traceback.format_exc()}")
85
  return f"❌ 摘要生成失敗: {str(e)}"
86
 
87
  def ask_question(user_question):
88
- """基於 PDF 內容回答問題"""
89
  if not client:
90
- return "❌ 請先設定 OpenAI API Key"
91
-
92
  if not summary_text and not pdf_text:
93
  return "❌ 請先生成 PDF 摘要"
94
-
95
  if not user_question.strip():
96
  return "❌ 請輸入問題"
97
-
98
  try:
99
  context = f"PDF 摘要:\n{summary_text}\n\n原始內容(部分):\n{pdf_text[:2000]}"
100
  response = client.chat.completions.create(
101
  model=selected_model,
102
  messages=[
103
- {"role": "system", "content": f"根據以下 PDF 內容回答用戶的問題,請用繁體中文回答並客觀精準:\n{context}"},
104
  {"role": "user", "content": user_question}
105
  ],
106
  temperature=0.2
107
  )
108
  return response.choices[0].message.content
109
-
110
  except Exception as e:
111
- print(f"錯誤詳情: {traceback.format_exc()}")
112
  return f"❌ 問答生成失敗: {str(e)}"
113
 
114
  def clear_all():
115
- """清除所有資料"""
116
  global summary_text, pdf_text
117
  summary_text = ""
118
  pdf_text = ""
119
  return "", "", ""
120
 
121
- # Gradio 介面
122
  with gr.Blocks(title="PDF 摘要助手") as demo:
123
- gr.Markdown("# 📄 PDF 摘要 & 問答助手 (修正版)")
124
 
125
  with gr.Tab("🔧 設定"):
126
- api_key_input = gr.Textbox(label="🔑 輸入 OpenAI API Key", type="password")
127
- api_key_status = gr.Textbox(label="狀態", interactive=False, value="等待設定 API Key...")
128
- api_key_btn = gr.Button("確認設定 API Key")
129
  api_key_btn.click(set_api_key, inputs=api_key_input, outputs=api_key_status)
130
 
131
  model_choice = gr.Radio(["gpt-4", "gpt-4.1", "gpt-4.5"], label="選擇 AI 模型", value="gpt-4")
132
  model_status = gr.Textbox(label="模型狀態", interactive=False, value="✅ 已選擇:gpt-4")
133
  model_choice.change(set_model, inputs=model_choice, outputs=model_status)
134
 
135
- with gr.Tab("📄 PDF 摘要"):
136
- pdf_upload = gr.File(label="選擇 PDF 文件", file_types=[".pdf"])
137
  summary_btn = gr.Button("生成摘要")
138
  summary_output = gr.Textbox(label="PDF 摘要", lines=10)
139
  summary_btn.click(generate_summary, inputs=pdf_upload, outputs=summary_output)
140
 
141
  with gr.Tab("❓ 問答"):
142
- question_input = gr.Textbox(label="請輸入您的問題", lines=2)
143
  question_btn = gr.Button("送出問題")
144
- answer_output = gr.Textbox(label="AI 回答", lines=10)
145
  question_btn.click(ask_question, inputs=question_input, outputs=answer_output)
146
  question_input.submit(ask_question, inputs=question_input, outputs=answer_output)
147
 
148
- clear_btn = gr.Button("🗑️ 清除所有資料")
149
  clear_btn.click(clear_all, outputs=[summary_output, question_input, answer_output])
150
 
151
  if __name__ == "__main__":
 
1
  import openai
2
  import gradio as gr
3
+ import fitz
4
  from openai import OpenAI
5
  import traceback
6
 
 
12
  pdf_text = ""
13
 
14
  def set_api_key(user_api_key):
 
15
  global api_key, client
16
  try:
17
  api_key = user_api_key.strip()
 
19
  return "❌ API Key 不能為空"
20
 
21
  client = OpenAI(api_key=api_key)
 
 
22
  client.chat.completions.create(
23
  model="gpt-4",
24
  messages=[{"role": "user", "content": "你好"}],
25
  max_tokens=5
26
  )
 
27
  return "✅ API Key 已設定並驗證成功"
28
  except Exception as e:
29
  return f"❌ API Key 設定失敗: {str(e)}"
30
 
31
  def set_model(model_name):
 
32
  global selected_model
33
  selected_model = model_name
34
  return f"✅ 模型已選擇:{model_name}"
35
 
36
  def extract_pdf_text(file_path):
 
37
  try:
38
  doc = fitz.open(file_path)
39
  text = ""
 
47
  return f"❌ PDF 解析錯誤: {str(e)}"
48
 
49
  def generate_summary(pdf_file):
 
50
  global summary_text, pdf_text
 
51
  if not client:
52
+ return "❌ 請先設定 API Key"
 
53
  if not pdf_file:
54
  return "❌ 請先上傳 PDF 文件"
 
55
  try:
56
  pdf_text = extract_pdf_text(pdf_file.name)
57
  if not pdf_text.strip():
58
+ return "⚠️ 無法解析 PDF 文字"
59
+ pdf_text_truncated = pdf_text[:8000]
 
60
  response = client.chat.completions.create(
61
  model=selected_model,
62
  messages=[
63
+ {"role": "system", "content": "請用繁體中文整理以下 PDF 內容摘要。"},
64
  {"role": "user", "content": pdf_text_truncated}
65
  ],
66
  temperature=0.3
67
  )
 
68
  summary_text = response.choices[0].message.content
69
  return summary_text
 
70
  except Exception as e:
71
+ print(traceback.format_exc())
72
  return f"❌ 摘要生成失敗: {str(e)}"
73
 
74
  def ask_question(user_question):
 
75
  if not client:
76
+ return "❌ 請先設定 API Key"
 
77
  if not summary_text and not pdf_text:
78
  return "❌ 請先生成 PDF 摘要"
 
79
  if not user_question.strip():
80
  return "❌ 請輸入問題"
 
81
  try:
82
  context = f"PDF 摘要:\n{summary_text}\n\n原始內容(部分):\n{pdf_text[:2000]}"
83
  response = client.chat.completions.create(
84
  model=selected_model,
85
  messages=[
86
+ {"role": "system", "content": f"根據以下 PDF 內容回答問題,用繁體中文:\n{context}"},
87
  {"role": "user", "content": user_question}
88
  ],
89
  temperature=0.2
90
  )
91
  return response.choices[0].message.content
 
92
  except Exception as e:
93
+ print(traceback.format_exc())
94
  return f"❌ 問答生成失敗: {str(e)}"
95
 
96
  def clear_all():
 
97
  global summary_text, pdf_text
98
  summary_text = ""
99
  pdf_text = ""
100
  return "", "", ""
101
 
 
102
  with gr.Blocks(title="PDF 摘要助手") as demo:
103
+ gr.Markdown("## 📄 PDF 摘要 & 問答助手")
104
 
105
  with gr.Tab("🔧 設定"):
106
+ api_key_input = gr.Textbox(label="輸入 OpenAI API Key", type="password")
107
+ api_key_status = gr.Textbox(label="API 狀態", interactive=False)
108
+ api_key_btn = gr.Button("確認 API Key")
109
  api_key_btn.click(set_api_key, inputs=api_key_input, outputs=api_key_status)
110
 
111
  model_choice = gr.Radio(["gpt-4", "gpt-4.1", "gpt-4.5"], label="選擇 AI 模型", value="gpt-4")
112
  model_status = gr.Textbox(label="模型狀態", interactive=False, value="✅ 已選擇:gpt-4")
113
  model_choice.change(set_model, inputs=model_choice, outputs=model_status)
114
 
115
+ with gr.Tab("📄 摘要"):
116
+ pdf_upload = gr.File(label="上傳 PDF", file_types=[".pdf"])
117
  summary_btn = gr.Button("生成摘要")
118
  summary_output = gr.Textbox(label="PDF 摘要", lines=10)
119
  summary_btn.click(generate_summary, inputs=pdf_upload, outputs=summary_output)
120
 
121
  with gr.Tab("❓ 問答"):
122
+ question_input = gr.Textbox(label="請輸入問題", lines=2)
123
  question_btn = gr.Button("送出問題")
124
+ answer_output = gr.Textbox(label="AI 回答", lines=8)
125
  question_btn.click(ask_question, inputs=question_input, outputs=answer_output)
126
  question_input.submit(ask_question, inputs=question_input, outputs=answer_output)
127
 
128
+ clear_btn = gr.Button("清除所有資料")
129
  clear_btn.click(clear_all, outputs=[summary_output, question_input, answer_output])
130
 
131
  if __name__ == "__main__":