HarshitaSuri commited on
Commit
a0d9e71
Β·
verified Β·
1 Parent(s): e19d6f0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -33
app.py CHANGED
@@ -37,10 +37,12 @@ def validate_json_response(expected, actual) -> Tuple[bool, str]:
37
  except Exception as e:
38
  return False, f"Invalid JSON: {str(e)}"
39
 
40
- def run_single_test(endpoint: str, method: str, bearer_token: str,
41
- expected_status: int, expected_body: str) -> Dict:
 
42
  """Run a single API test with AI-powered semantic validation"""
43
  result = {
 
44
  'Endpoint': endpoint,
45
  'Method': method,
46
  'Expected Status': expected_status,
@@ -51,60 +53,64 @@ def run_single_test(endpoint: str, method: str, bearer_token: str,
51
  'Similarity': None,
52
  'Notes': ''
53
  }
54
-
55
  try:
56
  headers = {}
57
  if bearer_token and bearer_token.strip():
58
  headers['Authorization'] = f'Bearer {bearer_token.strip()}'
59
-
 
 
 
 
60
  # Make API call
61
  if method.upper() == 'GET':
62
  response = requests.get(endpoint, headers=headers, timeout=10)
63
  elif method.upper() == 'POST':
64
- response = requests.post(endpoint, headers=headers, timeout=10)
65
  elif method.upper() == 'PUT':
66
- response = requests.put(endpoint, headers=headers, timeout=10)
67
  elif method.upper() == 'DELETE':
68
  response = requests.delete(endpoint, headers=headers, timeout=10)
69
  else:
70
  result['Notes'] = f'Unsupported method: {method}'
71
  return result
72
-
73
  result['Actual Status'] = response.status_code
74
  actual_body = response.text
75
  result['Actual Body'] = actual_body[:100] + '...' if len(actual_body) > 100 else actual_body
76
-
77
- # Check status code
78
  if response.status_code != expected_status:
79
  result['Outcome'] = 'FAIL'
80
  result['Notes'] = f'Status mismatch: expected {expected_status}, got {response.status_code}'
81
  return result
82
-
83
- # Status matches - now check body
84
  if not expected_body or is_empty_response(expected_body):
85
  result['Outcome'] = 'PASS'
86
  result['Notes'] = 'Status matches, no body validation'
87
  return result
88
-
89
  if is_empty_response(actual_body):
90
  result['Outcome'] = 'UNCERTAIN'
91
  result['Similarity'] = 0.0
92
  result['Notes'] = 'Response is empty (manual review needed)'
93
  return result
94
-
95
- # Try JSON validation first
96
  json_match, _ = validate_json_response(expected_body, actual_body)
97
  if json_match:
98
  result['Outcome'] = 'PASS'
99
  result['Similarity'] = 1.0
100
  result['Notes'] = 'Exact JSON match'
101
  return result
102
-
103
- # Use AI semantic similarity
104
  try:
105
  similarity = calculate_semantic_similarity(expected_body, actual_body)
106
  result['Similarity'] = round(similarity, 3)
107
-
108
  if similarity >= 0.75:
109
  result['Outcome'] = 'PASS'
110
  result['Notes'] = f'High semantic similarity: {similarity:.1%}'
@@ -117,9 +123,9 @@ def run_single_test(endpoint: str, method: str, bearer_token: str,
117
  except Exception as sim_error:
118
  result['Outcome'] = 'UNCERTAIN'
119
  result['Notes'] = f'Cannot compute similarity: {str(sim_error)}'
120
-
121
  return result
122
-
123
  except requests.exceptions.Timeout:
124
  result['Notes'] = 'Request timeout'
125
  return result
@@ -134,31 +140,33 @@ def process_excel_file(file, bearer_token: str) -> Tuple[pd.DataFrame, str]:
134
  """Process uploaded Excel file and run all tests"""
135
  try:
136
  df = pd.read_excel(file)
137
-
138
- required_columns = ['Endpoint', 'Method', 'Expected Status Code', 'Expected Response Body']
139
  missing_columns = [col for col in required_columns if col not in df.columns]
140
-
141
  if missing_columns:
142
  return None, f"❌ Missing columns: {', '.join(missing_columns)}"
143
-
144
  results = []
145
  for _, row in df.iterrows():
146
  result = run_single_test(
147
  endpoint=str(row['Endpoint']),
148
  method=str(row['Method']),
149
  bearer_token=bearer_token,
150
- expected_status=int(row['Expected Status Code']),
151
- expected_body=str(row['Expected Response Body'])
 
 
152
  )
153
  results.append(result)
154
-
155
  results_df = pd.DataFrame(results)
156
-
157
  total = len(results_df)
158
  passed = len(results_df[results_df['Outcome'] == 'PASS'])
159
  failed = len(results_df[results_df['Outcome'] == 'FAIL'])
160
  uncertain = len(results_df[results_df['Outcome'] == 'UNCERTAIN'])
161
-
162
  summary = f"""
163
  πŸ“Š **Test Summary**
164
  - Total Tests: {total}
@@ -166,9 +174,9 @@ def process_excel_file(file, bearer_token: str) -> Tuple[pd.DataFrame, str]:
166
  - ❌ Failed: {failed}
167
  - ⚠️ Uncertain: {uncertain}
168
  """
169
-
170
  return results_df, summary
171
-
172
  except Exception as e:
173
  return None, f"❌ Error processing file: {str(e)}"
174
 
@@ -191,7 +199,7 @@ with gr.Blocks(title="API Test Runner with AI", theme=gr.themes.Soft()) as app:
191
 
192
  Upload an Excel file with your API test cases and get automated validation with semantic similarity analysis.
193
  """)
194
-
195
  with gr.Row():
196
  with gr.Column(scale=2):
197
  file_input = gr.File(label="Upload Excel File (.xlsx)", file_types=['.xlsx'])
@@ -208,8 +216,8 @@ with gr.Blocks(title="API Test Runner with AI", theme=gr.themes.Soft()) as app:
208
  with gr.Row():
209
  results_output = gr.Dataframe(
210
  label="Test Results",
211
- headers=['Endpoint', 'Method', 'Expected Status', 'Actual Status',
212
- 'Outcome', 'Similarity', 'Notes'],
213
  interactive=False
214
  )
215
 
 
37
  except Exception as e:
38
  return False, f"Invalid JSON: {str(e)}"
39
 
40
+ def run_single_test(endpoint: str, method: str, bearer_token: str,
41
+ expected_status: int, expected_body: str,
42
+ payload: str = None, test_name: str = None) -> Dict:
43
  """Run a single API test with AI-powered semantic validation"""
44
  result = {
45
+ 'TestName': test_name,
46
  'Endpoint': endpoint,
47
  'Method': method,
48
  'Expected Status': expected_status,
 
53
  'Similarity': None,
54
  'Notes': ''
55
  }
56
+
57
  try:
58
  headers = {}
59
  if bearer_token and bearer_token.strip():
60
  headers['Authorization'] = f'Bearer {bearer_token.strip()}'
61
+
62
+ data = None
63
+ if payload and isinstance(payload, str) and payload.strip():
64
+ data = payload
65
+
66
  # Make API call
67
  if method.upper() == 'GET':
68
  response = requests.get(endpoint, headers=headers, timeout=10)
69
  elif method.upper() == 'POST':
70
+ response = requests.post(endpoint, headers=headers, data=data, timeout=10)
71
  elif method.upper() == 'PUT':
72
+ response = requests.put(endpoint, headers=headers, data=data, timeout=10)
73
  elif method.upper() == 'DELETE':
74
  response = requests.delete(endpoint, headers=headers, timeout=10)
75
  else:
76
  result['Notes'] = f'Unsupported method: {method}'
77
  return result
78
+
79
  result['Actual Status'] = response.status_code
80
  actual_body = response.text
81
  result['Actual Body'] = actual_body[:100] + '...' if len(actual_body) > 100 else actual_body
82
+
83
+ # Status code check
84
  if response.status_code != expected_status:
85
  result['Outcome'] = 'FAIL'
86
  result['Notes'] = f'Status mismatch: expected {expected_status}, got {response.status_code}'
87
  return result
88
+
89
+ # Body validation
90
  if not expected_body or is_empty_response(expected_body):
91
  result['Outcome'] = 'PASS'
92
  result['Notes'] = 'Status matches, no body validation'
93
  return result
94
+
95
  if is_empty_response(actual_body):
96
  result['Outcome'] = 'UNCERTAIN'
97
  result['Similarity'] = 0.0
98
  result['Notes'] = 'Response is empty (manual review needed)'
99
  return result
100
+
101
+ # JSON validation
102
  json_match, _ = validate_json_response(expected_body, actual_body)
103
  if json_match:
104
  result['Outcome'] = 'PASS'
105
  result['Similarity'] = 1.0
106
  result['Notes'] = 'Exact JSON match'
107
  return result
108
+
109
+ # Semantic similarity
110
  try:
111
  similarity = calculate_semantic_similarity(expected_body, actual_body)
112
  result['Similarity'] = round(similarity, 3)
113
+
114
  if similarity >= 0.75:
115
  result['Outcome'] = 'PASS'
116
  result['Notes'] = f'High semantic similarity: {similarity:.1%}'
 
123
  except Exception as sim_error:
124
  result['Outcome'] = 'UNCERTAIN'
125
  result['Notes'] = f'Cannot compute similarity: {str(sim_error)}'
126
+
127
  return result
128
+
129
  except requests.exceptions.Timeout:
130
  result['Notes'] = 'Request timeout'
131
  return result
 
140
  """Process uploaded Excel file and run all tests"""
141
  try:
142
  df = pd.read_excel(file)
143
+
144
+ required_columns = ['Endpoint', 'Method', 'ExpectedStatus', 'ExpectedBody']
145
  missing_columns = [col for col in required_columns if col not in df.columns]
146
+
147
  if missing_columns:
148
  return None, f"❌ Missing columns: {', '.join(missing_columns)}"
149
+
150
  results = []
151
  for _, row in df.iterrows():
152
  result = run_single_test(
153
  endpoint=str(row['Endpoint']),
154
  method=str(row['Method']),
155
  bearer_token=bearer_token,
156
+ expected_status=int(row['ExpectedStatus']),
157
+ expected_body=str(row['ExpectedBody']),
158
+ payload=row.get('Payload', None),
159
+ test_name=row.get('TestName', None)
160
  )
161
  results.append(result)
162
+
163
  results_df = pd.DataFrame(results)
164
+
165
  total = len(results_df)
166
  passed = len(results_df[results_df['Outcome'] == 'PASS'])
167
  failed = len(results_df[results_df['Outcome'] == 'FAIL'])
168
  uncertain = len(results_df[results_df['Outcome'] == 'UNCERTAIN'])
169
+
170
  summary = f"""
171
  πŸ“Š **Test Summary**
172
  - Total Tests: {total}
 
174
  - ❌ Failed: {failed}
175
  - ⚠️ Uncertain: {uncertain}
176
  """
177
+
178
  return results_df, summary
179
+
180
  except Exception as e:
181
  return None, f"❌ Error processing file: {str(e)}"
182
 
 
199
 
200
  Upload an Excel file with your API test cases and get automated validation with semantic similarity analysis.
201
  """)
202
+
203
  with gr.Row():
204
  with gr.Column(scale=2):
205
  file_input = gr.File(label="Upload Excel File (.xlsx)", file_types=['.xlsx'])
 
216
  with gr.Row():
217
  results_output = gr.Dataframe(
218
  label="Test Results",
219
+ headers=['TestName','Endpoint','Method','Expected Status','Actual Status',
220
+ 'Outcome','Similarity','Notes'],
221
  interactive=False
222
  )
223