Spaces:
Running
Running
Update admin_routes.py
Browse files- admin_routes.py +113 -19
admin_routes.py
CHANGED
@@ -1128,36 +1128,130 @@ async def spark_delete_project(project_name: str, username: str = Depends(verify
|
|
1128 |
|
1129 |
# ===================== Test Endpoints =====================
|
1130 |
@router.post("/apis/test")
|
1131 |
-
async def test_api(
|
1132 |
-
"""Test API endpoint"""
|
1133 |
import requests
|
|
|
1134 |
|
1135 |
try:
|
1136 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
1137 |
headers = api.headers.copy()
|
1138 |
|
1139 |
-
#
|
|
|
1140 |
if api.auth and api.auth.get("enabled"):
|
1141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1142 |
|
1143 |
-
#
|
1144 |
-
|
1145 |
-
method=api.method,
|
1146 |
-
url=api.url,
|
1147 |
-
headers=headers,
|
1148 |
-
json=api.body_template if api.method in ["POST", "PUT", "PATCH"] else None,
|
1149 |
-
params=api.body_template if api.method == "GET" else None,
|
1150 |
-
timeout=api.timeout_seconds,
|
1151 |
-
proxies={"http": api.proxy, "https": api.proxy} if api.proxy else None
|
1152 |
-
)
|
1153 |
|
1154 |
-
|
1155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1156 |
"status_code": response.status_code,
|
1157 |
-
"response":
|
1158 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1159 |
}
|
1160 |
except Exception as e:
|
|
|
1161 |
return {
|
1162 |
"success": False,
|
1163 |
"error": str(e)
|
|
|
1128 |
|
1129 |
# ===================== Test Endpoints =====================
|
1130 |
@router.post("/apis/test")
|
1131 |
+
async def test_api(api_data: dict = Body(...), username: str = Depends(verify_token)):
|
1132 |
+
"""Test API endpoint with auth support"""
|
1133 |
import requests
|
1134 |
+
import time
|
1135 |
|
1136 |
try:
|
1137 |
+
# Extract test request data if provided
|
1138 |
+
test_request = api_data.pop("test_request", None)
|
1139 |
+
|
1140 |
+
# Parse the APICreate model
|
1141 |
+
api = APICreate(**api_data)
|
1142 |
+
|
1143 |
+
# Prepare headers
|
1144 |
headers = api.headers.copy()
|
1145 |
|
1146 |
+
# Handle authentication if enabled
|
1147 |
+
auth_token = None
|
1148 |
if api.auth and api.auth.get("enabled"):
|
1149 |
+
auth_config = api.auth
|
1150 |
+
try:
|
1151 |
+
log(f"π Fetching auth token for test...")
|
1152 |
+
|
1153 |
+
# Make auth request
|
1154 |
+
auth_response = requests.post(
|
1155 |
+
auth_config["token_endpoint"],
|
1156 |
+
json=auth_config.get("token_request_body", {}),
|
1157 |
+
timeout=10
|
1158 |
+
)
|
1159 |
+
auth_response.raise_for_status()
|
1160 |
+
|
1161 |
+
# Extract token from response
|
1162 |
+
auth_json = auth_response.json()
|
1163 |
+
token_path = auth_config.get("response_token_path", "token").split(".")
|
1164 |
+
|
1165 |
+
auth_token = auth_json
|
1166 |
+
for path_part in token_path:
|
1167 |
+
auth_token = auth_token.get(path_part)
|
1168 |
+
if auth_token is None:
|
1169 |
+
raise ValueError(f"Token not found at path: {auth_config.get('response_token_path')}")
|
1170 |
+
|
1171 |
+
# Add token to headers
|
1172 |
+
headers["Authorization"] = f"Bearer {auth_token}"
|
1173 |
+
log(f"β
Auth token obtained: {auth_token[:20]}...")
|
1174 |
+
|
1175 |
+
except Exception as e:
|
1176 |
+
log(f"β Auth failed during test: {e}")
|
1177 |
+
return {
|
1178 |
+
"success": False,
|
1179 |
+
"error": f"Authentication failed: {str(e)}"
|
1180 |
+
}
|
1181 |
|
1182 |
+
# Use test_request if provided, otherwise use body_template
|
1183 |
+
request_body = test_request if test_request is not None else api.body_template
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1184 |
|
1185 |
+
# Make the actual API request
|
1186 |
+
start_time = time.time()
|
1187 |
+
|
1188 |
+
# Determine how to send the body based on method
|
1189 |
+
if api.method in ["POST", "PUT", "PATCH"]:
|
1190 |
+
response = requests.request(
|
1191 |
+
method=api.method,
|
1192 |
+
url=api.url,
|
1193 |
+
headers=headers,
|
1194 |
+
json=request_body,
|
1195 |
+
timeout=api.timeout_seconds,
|
1196 |
+
proxies={"http": api.proxy, "https": api.proxy} if api.proxy else None
|
1197 |
+
)
|
1198 |
+
elif api.method == "GET":
|
1199 |
+
response = requests.request(
|
1200 |
+
method=api.method,
|
1201 |
+
url=api.url,
|
1202 |
+
headers=headers,
|
1203 |
+
params=request_body if isinstance(request_body, dict) else None,
|
1204 |
+
timeout=api.timeout_seconds,
|
1205 |
+
proxies={"http": api.proxy, "https": api.proxy} if api.proxy else None
|
1206 |
+
)
|
1207 |
+
else: # DELETE, HEAD, etc.
|
1208 |
+
response = requests.request(
|
1209 |
+
method=api.method,
|
1210 |
+
url=api.url,
|
1211 |
+
headers=headers,
|
1212 |
+
timeout=api.timeout_seconds,
|
1213 |
+
proxies={"http": api.proxy, "https": api.proxy} if api.proxy else None
|
1214 |
+
)
|
1215 |
+
|
1216 |
+
response_time_ms = int((time.time() - start_time) * 1000)
|
1217 |
+
|
1218 |
+
# Prepare response body
|
1219 |
+
try:
|
1220 |
+
response_body = response.json()
|
1221 |
+
except:
|
1222 |
+
response_body = response.text
|
1223 |
+
|
1224 |
+
# Check if request was successful (2xx status codes)
|
1225 |
+
is_success = 200 <= response.status_code < 300
|
1226 |
+
|
1227 |
+
result = {
|
1228 |
+
"success": is_success,
|
1229 |
"status_code": response.status_code,
|
1230 |
+
"response": response_body if isinstance(response_body, str) else json.dumps(response_body, indent=2),
|
1231 |
+
"body": json.dumps(response_body, indent=2) if isinstance(response_body, dict) else response_body,
|
1232 |
+
"headers": dict(response.headers),
|
1233 |
+
"response_time_ms": response_time_ms
|
1234 |
+
}
|
1235 |
+
|
1236 |
+
# Add error info for non-2xx responses
|
1237 |
+
if not is_success:
|
1238 |
+
result["error"] = f"HTTP {response.status_code}: {response.reason}"
|
1239 |
+
|
1240 |
+
log(f"π Test result: {response.status_code} in {response_time_ms}ms")
|
1241 |
+
return result
|
1242 |
+
|
1243 |
+
except requests.exceptions.Timeout:
|
1244 |
+
return {
|
1245 |
+
"success": False,
|
1246 |
+
"error": f"Request timed out after {api.timeout_seconds} seconds"
|
1247 |
+
}
|
1248 |
+
except requests.exceptions.ConnectionError as e:
|
1249 |
+
return {
|
1250 |
+
"success": False,
|
1251 |
+
"error": f"Connection error: {str(e)}"
|
1252 |
}
|
1253 |
except Exception as e:
|
1254 |
+
log(f"β Test API error: {e}")
|
1255 |
return {
|
1256 |
"success": False,
|
1257 |
"error": str(e)
|