Marathon23 commited on
Commit
e910cb2
·
verified ·
1 Parent(s): 28b6c57

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -30
app.py CHANGED
@@ -10,49 +10,54 @@ from langchain.vectorstores import Chroma
10
  from langchain.embeddings.openai import OpenAIEmbeddings
11
  from langchain.chat_models import ChatOpenAI
12
  import shutil # 用於文件複製
 
 
 
 
 
13
 
14
  # 獲取 OpenAI API 密鑰
15
  api_key = os.getenv("OPENAI_API_KEY")
16
  if not api_key:
17
  raise ValueError("未能獲取 OPENAI_API_KEY。請在 Hugging Face Spaces 的 Secrets 中設置它。")
18
  openai.api_key = api_key
19
- print("OpenAI API 密鑰已設置。")
20
 
21
  # 確保向量資料庫目錄存在且有寫入權限
22
  VECTORDB_DIR = os.path.abspath("./data")
23
  os.makedirs(VECTORDB_DIR, exist_ok=True)
24
  os.chmod(VECTORDB_DIR, 0o755) # 設置適當的權限
25
- print(f"VECTORDB_DIR set to: {VECTORDB_DIR}")
26
 
27
  # 定義測試 PDF 加載器的函數
28
  def test_pdf_loader(file_path, loader_type='PyMuPDFLoader'):
29
- print(f"Testing PDF loader ({loader_type}) with file: {file_path}")
30
  try:
31
  if loader_type == 'PyMuPDFLoader':
32
  loader = PyMuPDFLoader(file_path)
33
  elif loader_type == 'PyPDFLoader':
34
  loader = PyPDFLoader(file_path)
35
  else:
36
- print(f"Unknown loader type: {loader_type}")
37
  return
38
  loaded_docs = loader.load()
39
  if loaded_docs:
40
- print(f"Successfully loaded {file_path} with {len(loaded_docs)} documents.")
41
- print(f"Document content (first 500 chars): {loaded_docs[0].page_content[:500]}")
42
  else:
43
- print(f"No documents loaded from {file_path}.")
44
  except Exception as e:
45
- print(f"Error loading {file_path} with {loader_type}: {e}")
46
 
47
  # 定義載入和處理 PDF 文件的函數
48
  def load_and_process_documents(file_paths, loader_type='PyMuPDFLoader'):
49
  documents = []
50
- print("開始載入上傳的 PDF 文件。")
51
 
52
  for file_path in file_paths:
53
- print(f"載入 PDF 文件: {file_path}")
54
  if not os.path.exists(file_path):
55
- print(f"文件不存在: {file_path}")
56
  continue
57
  try:
58
  if loader_type == 'PyMuPDFLoader':
@@ -60,28 +65,28 @@ def load_and_process_documents(file_paths, loader_type='PyMuPDFLoader'):
60
  elif loader_type == 'PyPDFLoader':
61
  loader = PyPDFLoader(file_path)
62
  else:
63
- print(f"Unknown loader type: {loader_type}")
64
  continue
65
  loaded_docs = loader.load()
66
  if loaded_docs:
67
- print(f"載入 {file_path} 成功,包含 {len(loaded_docs)} 個文檔。")
68
  # 打印第一個文檔的部分內容以確認
69
- print(f"第一個文檔內容: {loaded_docs[0].page_content[:500]}")
70
  documents.extend(loaded_docs)
71
  else:
72
- print(f"載入 {file_path} 但未找到任何文檔。")
73
  except Exception as e:
74
- print(f"載入 {file_path} 時出現錯誤: {e}")
75
 
76
  if not documents:
77
  raise ValueError("沒有找到任何 PDF 文件或 PDF 文件無法載入。")
78
  else:
79
- print(f"總共載入了 {len(documents)} 個文檔。")
80
 
81
  # 分割長文本
82
  text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=50)
83
  documents = text_splitter.split_documents(documents)
84
- print(f"分割後的文檔數量: {len(documents)}")
85
 
86
  if not documents:
87
  raise ValueError("分割後的文檔列表為空。請檢查 PDF 文件內容。")
@@ -89,7 +94,7 @@ def load_and_process_documents(file_paths, loader_type='PyMuPDFLoader'):
89
  # 初始化向量資料庫
90
  try:
91
  embeddings = OpenAIEmbeddings(openai_api_key=api_key) # 直接傳遞 API 密鑰
92
- print("初始化 OpenAIEmbeddings 成功。")
93
  except Exception as e:
94
  raise ValueError(f"初始化 OpenAIEmbeddings 時出現錯誤: {e}")
95
 
@@ -99,7 +104,7 @@ def load_and_process_documents(file_paths, loader_type='PyMuPDFLoader'):
99
  embedding=embeddings,
100
  persist_directory=VECTORDB_DIR
101
  )
102
- print("初始化 Chroma 向量資料庫成功。")
103
  except Exception as e:
104
  raise ValueError(f"初始化 Chroma 向量資料庫時出現錯誤: {e}")
105
 
@@ -136,36 +141,48 @@ def handle_query(user_message, chat_history, vectordb):
136
  return chat_history
137
 
138
  except Exception as e:
 
139
  return chat_history + [("系統", f"出現錯誤: {str(e)}")]
140
 
141
  # 定義 Gradio 的處理函數
142
  def process_files(files, state):
143
- print("process_files called")
144
  if files:
145
  try:
146
- print(f"Received {len(files)} files")
147
  saved_file_paths = []
148
  for file in files:
149
- print(f"Processing file: {file.name}")
150
  save_path = os.path.join(VECTORDB_DIR, file.name)
151
  with open(save_path, "wb") as f:
152
  f.write(file.read())
153
- # 確認文件是否存在
154
  if os.path.exists(save_path):
155
- print(f"File successfully saved to: {save_path}")
 
 
 
 
 
156
  else:
157
- print(f"Failed to save file to: {save_path}")
 
158
  saved_file_paths.append(save_path)
159
- # 測試 PDF 加載器
160
- test_pdf_loader(save_path, loader_type='PyMuPDFLoader')
 
 
 
 
 
161
  # 列出 VECTORDB_DIR 中的所有文件
162
  saved_files = os.listdir(VECTORDB_DIR)
163
- print(f"Files in VECTORDB_DIR ({VECTORDB_DIR}): {saved_files}")
164
  vectordb = load_and_process_documents(saved_file_paths, loader_type='PyMuPDFLoader')
165
  state['vectordb'] = vectordb
166
  return "PDF 文件已成功上傳並處理。您現在可以開始提問。", state
167
  except Exception as e:
168
- print(f"Error in process_files: {e}")
169
  return f"處理文件時出現錯誤: {e}", state
170
  else:
171
  return "請上傳至少一個 PDF 文件。", state
 
10
  from langchain.embeddings.openai import OpenAIEmbeddings
11
  from langchain.chat_models import ChatOpenAI
12
  import shutil # 用於文件複製
13
+ import logging
14
+
15
+ # 設置日誌配置
16
+ logging.basicConfig(level=logging.INFO)
17
+ logger = logging.getLogger(__name__)
18
 
19
  # 獲取 OpenAI API 密鑰
20
  api_key = os.getenv("OPENAI_API_KEY")
21
  if not api_key:
22
  raise ValueError("未能獲取 OPENAI_API_KEY。請在 Hugging Face Spaces 的 Secrets 中設置它。")
23
  openai.api_key = api_key
24
+ logger.info("OpenAI API 密鑰已設置。")
25
 
26
  # 確保向量資料庫目錄存在且有寫入權限
27
  VECTORDB_DIR = os.path.abspath("./data")
28
  os.makedirs(VECTORDB_DIR, exist_ok=True)
29
  os.chmod(VECTORDB_DIR, 0o755) # 設置適當的權限
30
+ logger.info(f"VECTORDB_DIR set to: {VECTORDB_DIR}")
31
 
32
  # 定義測試 PDF 加載器的函數
33
  def test_pdf_loader(file_path, loader_type='PyMuPDFLoader'):
34
+ logger.info(f"Testing PDF loader ({loader_type}) with file: {file_path}")
35
  try:
36
  if loader_type == 'PyMuPDFLoader':
37
  loader = PyMuPDFLoader(file_path)
38
  elif loader_type == 'PyPDFLoader':
39
  loader = PyPDFLoader(file_path)
40
  else:
41
+ logger.error(f"Unknown loader type: {loader_type}")
42
  return
43
  loaded_docs = loader.load()
44
  if loaded_docs:
45
+ logger.info(f"Successfully loaded {file_path} with {len(loaded_docs)} documents.")
46
+ logger.info(f"Document content (first 500 chars): {loaded_docs[0].page_content[:500]}")
47
  else:
48
+ logger.error(f"No documents loaded from {file_path}.")
49
  except Exception as e:
50
+ logger.error(f"Error loading {file_path} with {loader_type}: {e}")
51
 
52
  # 定義載入和處理 PDF 文件的函數
53
  def load_and_process_documents(file_paths, loader_type='PyMuPDFLoader'):
54
  documents = []
55
+ logger.info("開始載入上傳的 PDF 文件。")
56
 
57
  for file_path in file_paths:
58
+ logger.info(f"載入 PDF 文件: {file_path}")
59
  if not os.path.exists(file_path):
60
+ logger.error(f"文件不存在: {file_path}")
61
  continue
62
  try:
63
  if loader_type == 'PyMuPDFLoader':
 
65
  elif loader_type == 'PyPDFLoader':
66
  loader = PyPDFLoader(file_path)
67
  else:
68
+ logger.error(f"Unknown loader type: {loader_type}")
69
  continue
70
  loaded_docs = loader.load()
71
  if loaded_docs:
72
+ logger.info(f"載入 {file_path} 成功,包含 {len(loaded_docs)} 個文檔。")
73
  # 打印第一個文檔的部分內容以確認
74
+ logger.info(f"第一個文檔內容: {loaded_docs[0].page_content[:500]}")
75
  documents.extend(loaded_docs)
76
  else:
77
+ logger.error(f"載入 {file_path} 但未找到任何文檔。")
78
  except Exception as e:
79
+ logger.error(f"載入 {file_path} 時出現錯誤: {e}")
80
 
81
  if not documents:
82
  raise ValueError("沒有找到任何 PDF 文件或 PDF 文件無法載入。")
83
  else:
84
+ logger.info(f"總共載入了 {len(documents)} 個文檔。")
85
 
86
  # 分割長文本
87
  text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=50)
88
  documents = text_splitter.split_documents(documents)
89
+ logger.info(f"分割後的文檔數量: {len(documents)}")
90
 
91
  if not documents:
92
  raise ValueError("分割後的文檔列表為空。請檢查 PDF 文件內容。")
 
94
  # 初始化向量資料庫
95
  try:
96
  embeddings = OpenAIEmbeddings(openai_api_key=api_key) # 直接傳遞 API 密鑰
97
+ logger.info("初始化 OpenAIEmbeddings 成功。")
98
  except Exception as e:
99
  raise ValueError(f"初始化 OpenAIEmbeddings 時出現錯誤: {e}")
100
 
 
104
  embedding=embeddings,
105
  persist_directory=VECTORDB_DIR
106
  )
107
+ logger.info("初始化 Chroma 向量資料庫成功。")
108
  except Exception as e:
109
  raise ValueError(f"初始化 Chroma 向量資料庫時出現錯誤: {e}")
110
 
 
141
  return chat_history
142
 
143
  except Exception as e:
144
+ logger.error(f"Error in handle_query: {e}")
145
  return chat_history + [("系統", f"出現錯誤: {str(e)}")]
146
 
147
  # 定義 Gradio 的處理函數
148
  def process_files(files, state):
149
+ logger.info("process_files called")
150
  if files:
151
  try:
152
+ logger.info(f"Received {len(files)} files")
153
  saved_file_paths = []
154
  for file in files:
155
+ logger.info(f"Processing file: {file.name}")
156
  save_path = os.path.join(VECTORDB_DIR, file.name)
157
  with open(save_path, "wb") as f:
158
  f.write(file.read())
159
+ # 確認文件是否存在並檢查文件大小
160
  if os.path.exists(save_path):
161
+ file_size = os.path.getsize(save_path)
162
+ if file_size > 0:
163
+ logger.info(f"File successfully saved to: {save_path} (Size: {file_size} bytes)")
164
+ else:
165
+ logger.error(f"File saved to {save_path} is empty.")
166
+ raise ValueError(f"上傳的文件 {file.name} 為空。")
167
  else:
168
+ logger.error(f"Failed to save file to: {save_path}")
169
+ raise FileNotFoundError(f"無法保存文件到 {save_path}")
170
  saved_file_paths.append(save_path)
171
+ # 測試 PDF 加載器,先用 PyMuPDFLoader,再用 PyPDFLoader
172
+ try:
173
+ test_pdf_loader(save_path, loader_type='PyMuPDFLoader')
174
+ except Exception as e:
175
+ logger.error(f"PyMuPDFLoader failed: {e}")
176
+ logger.info("Attempting to load with PyPDFLoader...")
177
+ test_pdf_loader(save_path, loader_type='PyPDFLoader')
178
  # 列出 VECTORDB_DIR 中的所有文件
179
  saved_files = os.listdir(VECTORDB_DIR)
180
+ logger.info(f"Files in VECTORDB_DIR ({VECTORDB_DIR}): {saved_files}")
181
  vectordb = load_and_process_documents(saved_file_paths, loader_type='PyMuPDFLoader')
182
  state['vectordb'] = vectordb
183
  return "PDF 文件已成功上傳並處理。您現在可以開始提問。", state
184
  except Exception as e:
185
+ logger.error(f"Error in process_files: {e}")
186
  return f"處理文件時出現錯誤: {e}", state
187
  else:
188
  return "請上傳至少一個 PDF 文件。", state