Repository navigation
Expand file tree
/
Copy pathendpoint_test_script.py
More file actions
369 lines (314 loc) Β· 13.3 KB
/
Copy pathendpoint_test_script.py
File metadata and controls
369 lines (314 loc) Β· 13.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
#!/usr/bin/env python3
"""
Comprehensive test script for Flask RAG API endpoints
Run this script to test all your endpoints systematically
"""
import requests
import json
import time
import os
from pathlib import Path
# Configuration
BASE_URL = "http://localhost:5001"
TEST_FILE_PATH = "test_document.txt"
class APITester:
def __init__(self, base_url=BASE_URL):
self.base_url = base_url
self.session = requests.Session()
self.conversation_id = None
self.test_results = []
def log_result(self, test_name, success, response_data=None, error=None):
"""Log test results"""
result = {
"test": test_name,
"success": success,
"timestamp": time.strftime("%H:%M:%S"),
"response": response_data,
"error": str(error) if error else None
}
self.test_results.append(result)
status = "β
PASS" if success else "β FAIL"
print(f"{status} {test_name}")
if error:
print(f" Error: {error}")
if response_data and isinstance(response_data, dict):
print(f" Response: {json.dumps(response_data, indent=2)[:200]}...")
print()
def create_test_file(self):
"""Create a test document for upload"""
test_content = """
# Test Document for RAG System
This is a test document for the RAG (Retrieval-Augmented Generation) system.
## Key Information
- This document contains test data
- The RAG system should be able to search and retrieve this content
- OpenAI embeddings are used for vector similarity search
- Pinecone is used as the vector database
## Technical Details
The system uses:
1. OpenAI text-embedding-3-small for embeddings (1536 dimensions)
2. Pinecone serverless for vector storage
3. Flask for the API backend
4. Chunking strategy with 500 character chunks and 50 character overlap
## Sample Questions
You can ask questions like:
- "What embedding model is used?"
- "How many dimensions do the embeddings have?"
- "What vector database is used?"
"""
with open(TEST_FILE_PATH, 'w') as f:
f.write(test_content)
print(f"π Created test file: {TEST_FILE_PATH}")
def test_health_check(self):
"""Test the health check endpoint"""
try:
response = self.session.get(f"{self.base_url}/health")
if response.status_code == 200:
data = response.json()
self.log_result("Health Check", True, data)
return True
else:
self.log_result("Health Check", False, error=f"Status: {response.status_code}")
return False
except Exception as e:
self.log_result("Health Check", False, error=e)
return False
def test_services_info(self):
"""Test the services info endpoint"""
try:
response = self.session.get(f"{self.base_url}/services/info")
if response.status_code == 200:
data = response.json()
self.log_result("Services Info", True, data)
return True
else:
self.log_result("Services Info", False, error=f"Status: {response.status_code}")
return False
except Exception as e:
self.log_result("Services Info", False, error=e)
return False
def test_upload_document(self):
"""Test document upload to RAG system"""
try:
if not os.path.exists(TEST_FILE_PATH):
self.create_test_file()
with open(TEST_FILE_PATH, 'rb') as f:
files = {'file': (TEST_FILE_PATH, f, 'text/plain')}
data = {'metadata': json.dumps({"source": "test", "type": "documentation"})}
response = self.session.post(
f"{self.base_url}/rag/upload",
files=files,
data=data
)
if response.status_code == 200:
data = response.json()
self.log_result("Document Upload", True, data)
return data.get('document_id')
else:
self.log_result("Document Upload", False, error=f"Status: {response.status_code}, Response: {response.text}")
return None
except Exception as e:
self.log_result("Document Upload", False, error=e)
return None
def test_list_documents(self):
"""Test listing uploaded documents"""
try:
response = self.session.get(f"{self.base_url}/rag/documents")
if response.status_code == 200:
data = response.json()
self.log_result("List Documents", True, data)
return True
else:
self.log_result("List Documents", False, error=f"Status: {response.status_code}")
return False
except Exception as e:
self.log_result("List Documents", False, error=e)
return False
def test_rag_search(self):
"""Test RAG search functionality"""
try:
query_data = {
"query": "What embedding model is used in the system?",
"top_k": 3
}
response = self.session.post(
f"{self.base_url}/rag/search",
json=query_data,
headers={'Content-Type': 'application/json'}
)
if response.status_code == 200:
data = response.json()
self.log_result("RAG Search", True, data)
return True
else:
self.log_result("RAG Search", False, error=f"Status: {response.status_code}, Response: {response.text}")
return False
except Exception as e:
self.log_result("RAG Search", False, error=e)
return False
def test_chat_with_rag(self):
"""Test chat endpoint with RAG context"""
try:
chat_data = {
"message": "What vector database is used in this system?",
"use_rag": True,
"conversation_id": self.conversation_id
}
response = self.session.post(
f"{self.base_url}/chat",
json=chat_data,
headers={'Content-Type': 'application/json'}
)
if response.status_code == 200:
data = response.json()
self.conversation_id = data.get('conversation_id') # Store for future tests
self.log_result("Chat with RAG", True, data)
return True
else:
self.log_result("Chat with RAG", False, error=f"Status: {response.status_code}, Response: {response.text}")
return False
except Exception as e:
self.log_result("Chat with RAG", False, error=e)
return False
def test_chat_without_rag(self):
"""Test chat endpoint without RAG context"""
try:
chat_data = {
"message": "Hello, how are you?",
"use_rag": False,
"conversation_id": self.conversation_id
}
response = self.session.post(
f"{self.base_url}/chat",
json=chat_data,
headers={'Content-Type': 'application/json'}
)
if response.status_code == 200:
data = response.json()
self.log_result("Chat without RAG", True, data)
return True
else:
self.log_result("Chat without RAG", False, error=f"Status: {response.status_code}, Response: {response.text}")
return False
except Exception as e:
self.log_result("Chat without RAG", False, error=e)
return False
def test_conversation_history(self):
"""Test getting conversation history"""
if not self.conversation_id:
self.log_result("Conversation History", False, error="No conversation ID available")
return False
try:
response = self.session.get(f"{self.base_url}/conversation/{self.conversation_id}")
if response.status_code == 200:
data = response.json()
self.log_result("Conversation History", True, data)
return True
else:
self.log_result("Conversation History", False, error=f"Status: {response.status_code}")
return False
except Exception as e:
self.log_result("Conversation History", False, error=e)
return False
def test_tts_synthesis(self):
"""Test text-to-speech synthesis"""
try:
tts_data = {
"text": "Hello, this is a test of the text to speech system.",
"voice": "alloy"
}
response = self.session.post(
f"{self.base_url}/tts/synthesize",
json=tts_data,
headers={'Content-Type': 'application/json'}
)
if response.status_code == 200:
# TTS returns audio data, so we just check the response headers
content_type = response.headers.get('content-type', '')
success = 'audio' in content_type or len(response.content) > 1000
self.log_result("TTS Synthesis", success, {"content_length": len(response.content), "content_type": content_type})
return success
else:
self.log_result("TTS Synthesis", False, error=f"Status: {response.status_code}")
return False
except Exception as e:
self.log_result("TTS Synthesis", False, error=e)
return False
def run_all_tests(self):
"""Run all tests in sequence"""
print("π Starting comprehensive API endpoint tests")
print("=" * 60)
# Basic connectivity tests
print("π‘ Testing basic connectivity...")
health_ok = self.test_health_check()
info_ok = self.test_services_info()
if not health_ok:
print("β Health check failed - stopping tests")
return self.print_summary()
# Document and RAG tests
print("π Testing document and RAG functionality...")
doc_id = self.test_upload_document()
self.test_list_documents()
if doc_id:
# Wait a moment for vector indexing
print("β³ Waiting for document indexing...")
time.sleep(2)
self.test_rag_search()
self.test_chat_with_rag()
else:
print("β οΈ Skipping RAG tests due to upload failure")
# Chat tests
print("π¬ Testing chat functionality...")
self.test_chat_without_rag()
self.test_conversation_history()
# Audio tests
print("π Testing audio functionality...")
self.test_tts_synthesis()
# Note: STT testing would require audio file upload
print("βΉοΈ STT testing requires audio file - skipping for now")
return self.print_summary()
def print_summary(self):
"""Print test summary"""
print("\n" + "=" * 60)
print("π TEST SUMMARY")
print("=" * 60)
total_tests = len(self.test_results)
passed_tests = sum(1 for result in self.test_results if result['success'])
failed_tests = total_tests - passed_tests
print(f"Total Tests: {total_tests}")
print(f"β
Passed: {passed_tests}")
print(f"β Failed: {failed_tests}")
print(f"Success Rate: {(passed_tests/total_tests)*100:.1f}%")
if failed_tests > 0:
print("\nβ Failed Tests:")
for result in self.test_results:
if not result['success']:
print(f" - {result['test']}: {result['error']}")
print("\nπ§Ή Cleaning up...")
if os.path.exists(TEST_FILE_PATH):
os.remove(TEST_FILE_PATH)
print(f" Removed test file: {TEST_FILE_PATH}")
return passed_tests == total_tests
def main():
"""Main test function"""
print("π§ͺ Flask RAG API Endpoint Tester")
print(f"π― Target: {BASE_URL}")
print("=" * 60)
# Check if server is running
try:
response = requests.get(f"{BASE_URL}/health", timeout=5)
print("β
Server is responding")
except requests.exceptions.RequestException as e:
print(f"β Server is not responding: {e}")
print("π‘ Make sure your Flask app is running on http://localhost:5001")
return False
# Run tests
tester = APITester()
success = tester.run_all_tests()
if success:
print("π All tests passed!")
else:
print("β οΈ Some tests failed - check the logs above")
return success
if __name__ == "__main__":
main()