Commit
·
0503b45
1
Parent(s):
4514838
fixed some module import issue
Browse files
backend/services/business_query_service.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
"""
|
5 |
|
6 |
import logging
|
7 |
-
from typing import Dict, Any, Optional
|
8 |
from backend.services.nlp_service import NLPService
|
9 |
from backend.services.database_service import DatabaseService
|
10 |
from backend.models.schemas import DatabaseResult
|
|
|
4 |
"""
|
5 |
|
6 |
import logging
|
7 |
+
from typing import Dict, Any, Optional, List
|
8 |
from backend.services.nlp_service import NLPService
|
9 |
from backend.services.database_service import DatabaseService
|
10 |
from backend.models.schemas import DatabaseResult
|
tmp_rovodev_test_groq_integration.py
DELETED
@@ -1,340 +0,0 @@
|
|
1 |
-
#!/usr/bin/env python3
|
2 |
-
"""
|
3 |
-
Groq 整合測試腳本
|
4 |
-
測試新的路由系統和 Groq 服務
|
5 |
-
"""
|
6 |
-
|
7 |
-
import requests
|
8 |
-
import json
|
9 |
-
import os
|
10 |
-
from typing import Dict, Any
|
11 |
-
|
12 |
-
class GroqIntegrationTester:
|
13 |
-
def __init__(self, base_url: str = "http://localhost:7860"):
|
14 |
-
self.base_url = base_url
|
15 |
-
self.test_results = []
|
16 |
-
|
17 |
-
def test_health_check(self):
|
18 |
-
"""測試健康檢查"""
|
19 |
-
print("🔍 測試健康檢查...")
|
20 |
-
try:
|
21 |
-
response = requests.get(f"{self.base_url}/health")
|
22 |
-
success = response.status_code == 200
|
23 |
-
result = {
|
24 |
-
"test": "health_check",
|
25 |
-
"success": success,
|
26 |
-
"status_code": response.status_code,
|
27 |
-
"response": response.json() if success else response.text
|
28 |
-
}
|
29 |
-
self.test_results.append(result)
|
30 |
-
print(f"✅ 健康檢查: {response.status_code}")
|
31 |
-
return success
|
32 |
-
except Exception as e:
|
33 |
-
print(f"❌ 健康檢查失敗: {e}")
|
34 |
-
self.test_results.append({
|
35 |
-
"test": "health_check",
|
36 |
-
"success": False,
|
37 |
-
"error": str(e)
|
38 |
-
})
|
39 |
-
return False
|
40 |
-
|
41 |
-
def test_chat_api(self):
|
42 |
-
"""測試聊天 API"""
|
43 |
-
print("\n💬 測試聊天 API...")
|
44 |
-
test_messages = [
|
45 |
-
"你好!",
|
46 |
-
"今天天氣如何?",
|
47 |
-
"請介紹一下你自己",
|
48 |
-
"推薦一些好用的功能"
|
49 |
-
]
|
50 |
-
|
51 |
-
for message in test_messages:
|
52 |
-
try:
|
53 |
-
response = requests.post(
|
54 |
-
f"{self.base_url}/chat",
|
55 |
-
json={"message": message, "user_id": "test_user"},
|
56 |
-
headers={"Content-Type": "application/json"}
|
57 |
-
)
|
58 |
-
|
59 |
-
success = response.status_code == 200
|
60 |
-
result = {
|
61 |
-
"test": "chat_api",
|
62 |
-
"message": message,
|
63 |
-
"success": success,
|
64 |
-
"status_code": response.status_code,
|
65 |
-
"response": response.json() if success else response.text
|
66 |
-
}
|
67 |
-
self.test_results.append(result)
|
68 |
-
|
69 |
-
if success:
|
70 |
-
data = response.json()
|
71 |
-
print(f"✅ 聊天: {message[:20]}... -> {data.get('text', '')[:50]}...")
|
72 |
-
else:
|
73 |
-
print(f"❌ 聊天失敗: {message[:20]}... -> {response.status_code}")
|
74 |
-
|
75 |
-
except Exception as e:
|
76 |
-
print(f"❌ 聊天 API 錯誤: {e}")
|
77 |
-
self.test_results.append({
|
78 |
-
"test": "chat_api",
|
79 |
-
"message": message,
|
80 |
-
"success": False,
|
81 |
-
"error": str(e)
|
82 |
-
})
|
83 |
-
|
84 |
-
def test_search_api(self):
|
85 |
-
"""測試搜尋 API"""
|
86 |
-
print("\n🔍 測試搜尋 API...")
|
87 |
-
test_queries = [
|
88 |
-
"iPhone 15 Pro",
|
89 |
-
"價格 1000-5000",
|
90 |
-
"庫存查詢",
|
91 |
-
"我的訂單",
|
92 |
-
"低庫存商品"
|
93 |
-
]
|
94 |
-
|
95 |
-
for query in test_queries:
|
96 |
-
try:
|
97 |
-
response = requests.post(
|
98 |
-
f"{self.base_url}/search",
|
99 |
-
json={"message": query, "user_id": "test_user"},
|
100 |
-
headers={"Content-Type": "application/json"}
|
101 |
-
)
|
102 |
-
|
103 |
-
success = response.status_code == 200
|
104 |
-
result = {
|
105 |
-
"test": "search_api",
|
106 |
-
"query": query,
|
107 |
-
"success": success,
|
108 |
-
"status_code": response.status_code,
|
109 |
-
"response": response.json() if success else response.text
|
110 |
-
}
|
111 |
-
self.test_results.append(result)
|
112 |
-
|
113 |
-
if success:
|
114 |
-
data = response.json()
|
115 |
-
print(f"✅ 搜尋: {query} -> {data.get('text', '')[:50]}...")
|
116 |
-
else:
|
117 |
-
print(f"❌ 搜尋失敗: {query} -> {response.status_code}")
|
118 |
-
|
119 |
-
except Exception as e:
|
120 |
-
print(f"❌ 搜尋 API 錯誤: {e}")
|
121 |
-
self.test_results.append({
|
122 |
-
"test": "search_api",
|
123 |
-
"query": query,
|
124 |
-
"success": False,
|
125 |
-
"error": str(e)
|
126 |
-
})
|
127 |
-
|
128 |
-
def test_smart_routing(self):
|
129 |
-
"""測試智能路由"""
|
130 |
-
print("\n🧠 測試智能路由...")
|
131 |
-
test_messages = [
|
132 |
-
# 應該路由到聊天
|
133 |
-
"你好,今天天氣如何?",
|
134 |
-
"請介紹一下你的功能",
|
135 |
-
|
136 |
-
# 應該路由到搜尋
|
137 |
-
"iPhone 還有庫存嗎?",
|
138 |
-
"查詢價格在 2000 到 5000 的商品",
|
139 |
-
"我想看看訂單狀態",
|
140 |
-
|
141 |
-
# 前綴指令
|
142 |
-
"/chat 你好!",
|
143 |
-
"/search iPhone 15",
|
144 |
-
"/help"
|
145 |
-
]
|
146 |
-
|
147 |
-
for message in test_messages:
|
148 |
-
try:
|
149 |
-
response = requests.post(
|
150 |
-
f"{self.base_url}/route",
|
151 |
-
json={"message": message, "user_id": "test_user"},
|
152 |
-
headers={"Content-Type": "application/json"}
|
153 |
-
)
|
154 |
-
|
155 |
-
success = response.status_code == 200
|
156 |
-
result = {
|
157 |
-
"test": "smart_routing",
|
158 |
-
"message": message,
|
159 |
-
"success": success,
|
160 |
-
"status_code": response.status_code,
|
161 |
-
"response": response.json() if success else response.text
|
162 |
-
}
|
163 |
-
self.test_results.append(result)
|
164 |
-
|
165 |
-
if success:
|
166 |
-
data = response.json()
|
167 |
-
mode = data.get('mode', 'unknown')
|
168 |
-
print(f"✅ 路由: {message[:30]}... -> {mode}")
|
169 |
-
else:
|
170 |
-
print(f"❌ 路由失敗: {message[:30]}... -> {response.status_code}")
|
171 |
-
|
172 |
-
except Exception as e:
|
173 |
-
print(f"❌ 智能路由錯誤: {e}")
|
174 |
-
self.test_results.append({
|
175 |
-
"test": "smart_routing",
|
176 |
-
"message": message,
|
177 |
-
"success": False,
|
178 |
-
"error": str(e)
|
179 |
-
})
|
180 |
-
|
181 |
-
def test_stats_api(self):
|
182 |
-
"""測試統計 API"""
|
183 |
-
print("\n📊 測試統計 API...")
|
184 |
-
try:
|
185 |
-
response = requests.get(f"{self.base_url}/stats")
|
186 |
-
success = response.status_code == 200
|
187 |
-
result = {
|
188 |
-
"test": "stats_api",
|
189 |
-
"success": success,
|
190 |
-
"status_code": response.status_code,
|
191 |
-
"response": response.json() if success else response.text
|
192 |
-
}
|
193 |
-
self.test_results.append(result)
|
194 |
-
|
195 |
-
if success:
|
196 |
-
data = response.json()
|
197 |
-
stats = data.get('data', {}).get('stats', {})
|
198 |
-
total = data.get('data', {}).get('total', 0)
|
199 |
-
print(f"✅ 統計: 總計 {total} 次路由")
|
200 |
-
for mode, count in stats.items():
|
201 |
-
print(f" {mode}: {count}")
|
202 |
-
else:
|
203 |
-
print(f"❌ 統計失敗: {response.status_code}")
|
204 |
-
|
205 |
-
except Exception as e:
|
206 |
-
print(f"❌ 統計 API 錯誤: {e}")
|
207 |
-
self.test_results.append({
|
208 |
-
"test": "stats_api",
|
209 |
-
"success": False,
|
210 |
-
"error": str(e)
|
211 |
-
})
|
212 |
-
|
213 |
-
def test_line_webhook_simulation(self):
|
214 |
-
"""模擬 LINE Webhook"""
|
215 |
-
print("\n📱 測試 LINE Webhook 模擬...")
|
216 |
-
test_messages = [
|
217 |
-
"/chat 你好!",
|
218 |
-
"/search iPhone",
|
219 |
-
"iPhone 還有庫存嗎?",
|
220 |
-
"幫助"
|
221 |
-
]
|
222 |
-
|
223 |
-
for message in test_messages:
|
224 |
-
webhook_data = {
|
225 |
-
"events": [
|
226 |
-
{
|
227 |
-
"type": "message",
|
228 |
-
"message": {
|
229 |
-
"type": "text",
|
230 |
-
"text": message
|
231 |
-
},
|
232 |
-
"source": {
|
233 |
-
"type": "user",
|
234 |
-
"userId": "test_user_webhook"
|
235 |
-
},
|
236 |
-
"replyToken": "test_reply_token"
|
237 |
-
}
|
238 |
-
]
|
239 |
-
}
|
240 |
-
|
241 |
-
try:
|
242 |
-
response = requests.post(
|
243 |
-
f"{self.base_url}/webhook",
|
244 |
-
json=webhook_data,
|
245 |
-
headers={"Content-Type": "application/json"}
|
246 |
-
)
|
247 |
-
|
248 |
-
success = response.status_code == 200
|
249 |
-
result = {
|
250 |
-
"test": "line_webhook",
|
251 |
-
"message": message,
|
252 |
-
"success": success,
|
253 |
-
"status_code": response.status_code
|
254 |
-
}
|
255 |
-
self.test_results.append(result)
|
256 |
-
|
257 |
-
print(f"{'✅' if success else '❌'} Webhook: {message} -> {response.status_code}")
|
258 |
-
|
259 |
-
except Exception as e:
|
260 |
-
print(f"❌ Webhook 錯誤: {e}")
|
261 |
-
self.test_results.append({
|
262 |
-
"test": "line_webhook",
|
263 |
-
"message": message,
|
264 |
-
"success": False,
|
265 |
-
"error": str(e)
|
266 |
-
})
|
267 |
-
|
268 |
-
def generate_report(self):
|
269 |
-
"""生成測試報告"""
|
270 |
-
print("\n" + "="*50)
|
271 |
-
print("📋 測試報告")
|
272 |
-
print("="*50)
|
273 |
-
|
274 |
-
total_tests = len(self.test_results)
|
275 |
-
successful_tests = sum(1 for result in self.test_results if result.get('success', False))
|
276 |
-
|
277 |
-
print(f"總測試數: {total_tests}")
|
278 |
-
print(f"���功: {successful_tests}")
|
279 |
-
print(f"失敗: {total_tests - successful_tests}")
|
280 |
-
print(f"成功率: {successful_tests/total_tests*100:.1f}%")
|
281 |
-
|
282 |
-
# 按測試類型分組
|
283 |
-
test_types = {}
|
284 |
-
for result in self.test_results:
|
285 |
-
test_type = result['test']
|
286 |
-
if test_type not in test_types:
|
287 |
-
test_types[test_type] = {'total': 0, 'success': 0}
|
288 |
-
test_types[test_type]['total'] += 1
|
289 |
-
if result.get('success', False):
|
290 |
-
test_types[test_type]['success'] += 1
|
291 |
-
|
292 |
-
print("\n📊 各功能測試結果:")
|
293 |
-
for test_type, stats in test_types.items():
|
294 |
-
success_rate = stats['success'] / stats['total'] * 100
|
295 |
-
print(f" {test_type}: {stats['success']}/{stats['total']} ({success_rate:.1f}%)")
|
296 |
-
|
297 |
-
# 顯示失敗的測試
|
298 |
-
failed_tests = [result for result in self.test_results if not result.get('success', False)]
|
299 |
-
if failed_tests:
|
300 |
-
print(f"\n❌ 失敗的測試 ({len(failed_tests)}):")
|
301 |
-
for result in failed_tests:
|
302 |
-
print(f" - {result['test']}: {result.get('error', 'Unknown error')}")
|
303 |
-
|
304 |
-
return {
|
305 |
-
'total': total_tests,
|
306 |
-
'successful': successful_tests,
|
307 |
-
'failed': total_tests - successful_tests,
|
308 |
-
'success_rate': successful_tests/total_tests*100,
|
309 |
-
'details': test_types,
|
310 |
-
'failed_tests': failed_tests
|
311 |
-
}
|
312 |
-
|
313 |
-
def run_all_tests():
|
314 |
-
"""執行所有測試"""
|
315 |
-
print("🚀 開始 Groq 整合測試")
|
316 |
-
print("="*50)
|
317 |
-
|
318 |
-
tester = GroqIntegrationTester()
|
319 |
-
|
320 |
-
# 執行所有測試
|
321 |
-
tester.test_health_check()
|
322 |
-
tester.test_chat_api()
|
323 |
-
tester.test_search_api()
|
324 |
-
tester.test_smart_routing()
|
325 |
-
tester.test_stats_api()
|
326 |
-
tester.test_line_webhook_simulation()
|
327 |
-
|
328 |
-
# 生成報告
|
329 |
-
report = tester.generate_report()
|
330 |
-
|
331 |
-
return report
|
332 |
-
|
333 |
-
if __name__ == "__main__":
|
334 |
-
report = run_all_tests()
|
335 |
-
|
336 |
-
# 保存詳細結果到文件
|
337 |
-
with open("tmp_rovodev_test_results.json", "w", encoding="utf-8") as f:
|
338 |
-
json.dump(report, f, ensure_ascii=False, indent=2)
|
339 |
-
|
340 |
-
print(f"\n📄 詳細測試結果已保存到: tmp_rovodev_test_results.json")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|