Spaces:
Running
Running
sunheycho
commited on
Commit
Β·
0a08210
1
Parent(s):
4429488
Debug: Add comprehensive debugging to start analysis endpoint
Browse files- Add step-by-step debugging messages to /api/product/compare/start endpoint
- Track coordinator availability, image processing, session creation, and background thread execution
- This will help identify exactly where the workflow fails when Start Analysis button is clicked
api.py
CHANGED
@@ -933,63 +933,91 @@ def add_detected_objects():
|
|
933 |
@login_required
|
934 |
def start_product_comparison():
|
935 |
"""Start a new product comparison session"""
|
|
|
|
|
|
|
936 |
if get_product_comparison_coordinator is None:
|
|
|
937 |
return jsonify({"error": "Product comparison module not available"}), 500
|
938 |
|
939 |
try:
|
|
|
940 |
# Generate session ID if provided in form or query params, otherwise create new one
|
941 |
session_id = request.form.get('session_id') or request.args.get('session_id') or str(uuid.uuid4())
|
|
|
942 |
|
943 |
# Get analysis type if provided (info, compare, value, recommend)
|
944 |
analysis_type = request.form.get('analysisType') or request.args.get('analysisType', 'info')
|
|
|
945 |
|
946 |
# Process images from FormData or JSON
|
947 |
images = []
|
|
|
|
|
|
|
948 |
|
949 |
# Check if request is multipart form data
|
950 |
if request.files:
|
|
|
951 |
# Handle FormData with file uploads (from frontend)
|
952 |
if 'image1' in request.files and request.files['image1']:
|
953 |
img1 = request.files['image1']
|
|
|
954 |
try:
|
955 |
images.append(Image.open(img1.stream))
|
|
|
956 |
except Exception as e:
|
957 |
-
print(f"Error processing image1: {e}")
|
958 |
|
959 |
if 'image2' in request.files and request.files['image2']:
|
960 |
img2 = request.files['image2']
|
|
|
961 |
try:
|
962 |
images.append(Image.open(img2.stream))
|
|
|
963 |
except Exception as e:
|
964 |
-
print(f"Error processing image2: {e}")
|
965 |
|
966 |
# Fallback to JSON with base64 images (for API testing)
|
967 |
elif request.json and 'images' in request.json:
|
|
|
968 |
image_data_list = request.json.get('images', [])
|
969 |
-
for image_data in image_data_list:
|
|
|
970 |
img = decode_base64_image(image_data)
|
971 |
if img is not None:
|
972 |
images.append(img)
|
|
|
|
|
|
|
973 |
|
|
|
974 |
if not images:
|
|
|
975 |
return jsonify({"error": "No valid images provided"}), 400
|
976 |
|
977 |
# Get coordinator instance
|
|
|
978 |
coordinator = get_product_comparison_coordinator()
|
|
|
979 |
|
980 |
# Pass the analysis type and session metadata to the coordinator
|
981 |
session_metadata = {
|
982 |
'analysis_type': analysis_type,
|
983 |
'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
|
984 |
}
|
|
|
985 |
|
986 |
# Start processing in a background thread
|
|
|
987 |
def run_async_task(loop):
|
988 |
try:
|
|
|
989 |
asyncio.set_event_loop(loop)
|
990 |
loop.run_until_complete(coordinator.process_images(session_id, images, session_metadata))
|
|
|
991 |
except Exception as e:
|
992 |
-
print(f"Error in async task: {e}")
|
993 |
import traceback
|
994 |
traceback.print_exc()
|
995 |
|
@@ -997,17 +1025,22 @@ def start_product_comparison():
|
|
997 |
thread = Thread(target=run_async_task, args=(loop,))
|
998 |
thread.daemon = True
|
999 |
thread.start()
|
|
|
1000 |
|
1001 |
# Return session ID for client to use with streaming endpoint
|
1002 |
-
|
1003 |
"session_id": session_id,
|
1004 |
"message": "Product comparison started",
|
1005 |
"status": "processing"
|
1006 |
-
}
|
|
|
|
|
1007 |
|
1008 |
except Exception as e:
|
1009 |
-
print(f"
|
|
|
1010 |
import traceback
|
|
|
1011 |
traceback.print_exc()
|
1012 |
return jsonify({"error": str(e)}), 500
|
1013 |
|
|
|
933 |
@login_required
|
934 |
def start_product_comparison():
|
935 |
"""Start a new product comparison session"""
|
936 |
+
print(f"[DEBUG] π start_product_comparison endpoint called")
|
937 |
+
print(f"[DEBUG] π get_product_comparison_coordinator: {get_product_comparison_coordinator}")
|
938 |
+
|
939 |
if get_product_comparison_coordinator is None:
|
940 |
+
print(f"[DEBUG] β Product comparison coordinator is None - returning 500")
|
941 |
return jsonify({"error": "Product comparison module not available"}), 500
|
942 |
|
943 |
try:
|
944 |
+
print(f"[DEBUG] π Processing request data...")
|
945 |
# Generate session ID if provided in form or query params, otherwise create new one
|
946 |
session_id = request.form.get('session_id') or request.args.get('session_id') or str(uuid.uuid4())
|
947 |
+
print(f"[DEBUG] π Session ID: {session_id}")
|
948 |
|
949 |
# Get analysis type if provided (info, compare, value, recommend)
|
950 |
analysis_type = request.form.get('analysisType') or request.args.get('analysisType', 'info')
|
951 |
+
print(f"[DEBUG] π Analysis type: {analysis_type}")
|
952 |
|
953 |
# Process images from FormData or JSON
|
954 |
images = []
|
955 |
+
print(f"[DEBUG] πΌοΈ Processing images...")
|
956 |
+
print(f"[DEBUG] π Request files: {list(request.files.keys())}")
|
957 |
+
print(f"[DEBUG] π Request form: {dict(request.form)}")
|
958 |
|
959 |
# Check if request is multipart form data
|
960 |
if request.files:
|
961 |
+
print(f"[DEBUG] π Processing multipart form data...")
|
962 |
# Handle FormData with file uploads (from frontend)
|
963 |
if 'image1' in request.files and request.files['image1']:
|
964 |
img1 = request.files['image1']
|
965 |
+
print(f"[DEBUG] πΌοΈ Processing image1: {img1.filename}")
|
966 |
try:
|
967 |
images.append(Image.open(img1.stream))
|
968 |
+
print(f"[DEBUG] β
Image1 processed successfully")
|
969 |
except Exception as e:
|
970 |
+
print(f"[DEBUG] β Error processing image1: {e}")
|
971 |
|
972 |
if 'image2' in request.files and request.files['image2']:
|
973 |
img2 = request.files['image2']
|
974 |
+
print(f"[DEBUG] πΌοΈ Processing image2: {img2.filename}")
|
975 |
try:
|
976 |
images.append(Image.open(img2.stream))
|
977 |
+
print(f"[DEBUG] β
Image2 processed successfully")
|
978 |
except Exception as e:
|
979 |
+
print(f"[DEBUG] β Error processing image2: {e}")
|
980 |
|
981 |
# Fallback to JSON with base64 images (for API testing)
|
982 |
elif request.json and 'images' in request.json:
|
983 |
+
print(f"[DEBUG] π Processing JSON with base64 images...")
|
984 |
image_data_list = request.json.get('images', [])
|
985 |
+
for i, image_data in enumerate(image_data_list):
|
986 |
+
print(f"[DEBUG] πΌοΈ Processing base64 image {i+1}")
|
987 |
img = decode_base64_image(image_data)
|
988 |
if img is not None:
|
989 |
images.append(img)
|
990 |
+
print(f"[DEBUG] β
Base64 image {i+1} processed successfully")
|
991 |
+
else:
|
992 |
+
print(f"[DEBUG] β Failed to decode base64 image {i+1}")
|
993 |
|
994 |
+
print(f"[DEBUG] π Total images processed: {len(images)}")
|
995 |
if not images:
|
996 |
+
print(f"[DEBUG] β No valid images provided - returning 400")
|
997 |
return jsonify({"error": "No valid images provided"}), 400
|
998 |
|
999 |
# Get coordinator instance
|
1000 |
+
print(f"[DEBUG] π― Getting coordinator instance...")
|
1001 |
coordinator = get_product_comparison_coordinator()
|
1002 |
+
print(f"[DEBUG] β
Coordinator obtained: {type(coordinator).__name__}")
|
1003 |
|
1004 |
# Pass the analysis type and session metadata to the coordinator
|
1005 |
session_metadata = {
|
1006 |
'analysis_type': analysis_type,
|
1007 |
'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
|
1008 |
}
|
1009 |
+
print(f"[DEBUG] π Session metadata: {session_metadata}")
|
1010 |
|
1011 |
# Start processing in a background thread
|
1012 |
+
print(f"[DEBUG] π§΅ Starting background processing thread...")
|
1013 |
def run_async_task(loop):
|
1014 |
try:
|
1015 |
+
print(f"[DEBUG] π Setting event loop and starting coordinator.process_images...")
|
1016 |
asyncio.set_event_loop(loop)
|
1017 |
loop.run_until_complete(coordinator.process_images(session_id, images, session_metadata))
|
1018 |
+
print(f"[DEBUG] β
coordinator.process_images completed successfully")
|
1019 |
except Exception as e:
|
1020 |
+
print(f"[DEBUG] β Error in async task: {e}")
|
1021 |
import traceback
|
1022 |
traceback.print_exc()
|
1023 |
|
|
|
1025 |
thread = Thread(target=run_async_task, args=(loop,))
|
1026 |
thread.daemon = True
|
1027 |
thread.start()
|
1028 |
+
print(f"[DEBUG] π Background thread started")
|
1029 |
|
1030 |
# Return session ID for client to use with streaming endpoint
|
1031 |
+
response_data = {
|
1032 |
"session_id": session_id,
|
1033 |
"message": "Product comparison started",
|
1034 |
"status": "processing"
|
1035 |
+
}
|
1036 |
+
print(f"[DEBUG] β
Returning success response: {response_data}")
|
1037 |
+
return jsonify(response_data)
|
1038 |
|
1039 |
except Exception as e:
|
1040 |
+
print(f"[DEBUG] β Exception in start_product_comparison: {e}")
|
1041 |
+
print(f"[DEBUG] β Exception type: {type(e).__name__}")
|
1042 |
import traceback
|
1043 |
+
print(f"[DEBUG] β Full traceback:")
|
1044 |
traceback.print_exc()
|
1045 |
return jsonify({"error": str(e)}), 500
|
1046 |
|