import gradio as gr import base64 from PIL import Image from io import BytesIO import os from tryon_api_client import TryOnAPIClient, TryOnAPIError def process_tryon(rapid_key, rapid_host, person_img, garment_img, garment_type): print(f"DEBUG INPUT: key='{rapid_key}', host='{rapid_host}'") if rapid_key: rapid_key = rapid_key.strip() if rapid_host: rapid_host = rapid_host.strip() # Determine API URL api_url = os.environ.get("API_BASE_URL", "http://localhost:5001") if not rapid_key: raise gr.Error("⚠️ Please enter your X-RapidAPI-Key.") if not rapid_host: raise gr.Error("⚠️ Please enter your X-RapidAPI-Host.") if rapid_host: api_url = f"https://{rapid_host}" client = TryOnAPIClient(base_url=api_url, rapid_api_key=rapid_key, rapid_api_host=rapid_host) # Validate inputs if not person_img or not garment_img: raise gr.Error("⚠️ Please upload both Person and Garment images.") # Validate file formats try: valid_extensions = ('.png', '.jpg', '.jpeg') if not person_img.lower().endswith(valid_extensions): raise gr.Error("⚠️ Person image must be PNG, JPEG, or JPG format.") if not garment_img.lower().endswith(valid_extensions): raise gr.Error("⚠️ Garment image must be PNG, JPEG, or JPG format.") except AttributeError: raise gr.Error("⚠️ Invalid image file. Please upload valid image files.") try: # 1. Create Task try: task_data = client.create_task(person_img, garment_img, garment_type) except TryOnAPIError as e: raise gr.Error(f"❌ API Error {e.status_code}: {e.message}") except ConnectionError: raise gr.Error("🔌 Cannot connect to the Try-On service. Please check if the API server is running.") except TimeoutError: raise gr.Error("⏱️ Connection timeout. The server is taking too long to respond.") except Exception as e: raise gr.Error(f"❌ Failed to create try-on task: {str(e)}") task_id = task_data.get('task_id') if not task_id: raise gr.Error("❌ No task ID returned from API. Please try again.") # 2. Wait for Completion using Client logic try: result = client.wait_for_completion(task_id) except TimeoutError: raise gr.Error("⏱️ Try-on process is taking too long. Please try again with smaller images.") except Exception as e: raise gr.Error(f"❌ Failed while processing try-on: {str(e)}") # 3. Process result image_base64 = result.get('image_base64') if image_base64: try: return base64_to_image(image_base64) except Exception as e: raise gr.Error(f"❌ Failed to decode result image: {str(e)}") else: raise gr.Error("❌ Try-on completed but no image was generated. Please try again.") except gr.Error: # Re-raise Gradio errors as-is raise except Exception as e: # Catch any unexpected errors raise gr.Error(f"❌ Unexpected error occurred: {str(e)}") def base64_to_image(base64_string): try: image_data = base64.b64decode(base64_string) image = Image.open(BytesIO(image_data)) return image except base64.binascii.Error: raise ValueError("Invalid base64 string format") except Exception as e: raise ValueError(f"Cannot decode image: {str(e)}") # UI Layout with gr.Blocks(title="Virtual Try-On") as app: gr.Markdown("# 👕 Virtual Try-On Demo") gr.Markdown("Upload a person image and a garment image to see the magic") gr.HTML( """