akhaliq HF Staff commited on
Commit
fcf74fc
·
verified ·
1 Parent(s): fc5bd53

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -86
app.py CHANGED
@@ -34,6 +34,9 @@ def query_api(payload, progress_callback=None):
34
  del payload["image_bytes"]
35
 
36
  # Submit the job
 
 
 
37
  response = requests.post(API_URL, headers=headers, json=payload)
38
 
39
  if response.status_code != 200:
@@ -41,10 +44,8 @@ def query_api(payload, progress_callback=None):
41
 
42
  # Debug the response
43
  print(f"Response status: {response.status_code}")
44
- print(f"Response headers: {dict(response.headers)}")
45
  print(f"Response content type: {response.headers.get('content-type', 'unknown')}")
46
  print(f"Response content length: {len(response.content)}")
47
- print(f"First 500 chars of response: {response.content[:500]}")
48
 
49
  # Check if response is JSON (queue status) or binary (direct image)
50
  content_type = response.headers.get('content-type', '').lower()
@@ -57,103 +58,36 @@ def query_api(payload, progress_callback=None):
57
 
58
  # Check if job was queued
59
  if json_response.get("status") == "IN_QUEUE":
60
- request_id = json_response.get("request_id")
61
- if not request_id:
62
- raise gr.Error("No request_id provided in queue response")
 
63
 
64
- # Poll for completion using the proper HF router endpoints
65
- max_attempts = 60 # Wait up to 5 minutes
66
- attempt = 0
67
 
68
- while attempt < max_attempts:
69
- if progress_callback:
70
- progress_callback(0.1 + (attempt / max_attempts) * 0.8, f"Processing... (attempt {attempt + 1}/60)")
71
-
72
- time.sleep(5) # Wait 5 seconds between polls
73
-
74
- # Check status using HF router format
75
- status_url = f"https://router.huggingface.co/fal-ai/fal-ai/flux-kontext/dev/requests/{request_id}/status"
76
- status_response = requests.get(status_url, headers=headers)
77
-
78
- if status_response.status_code != 200:
79
- print(f"Status response: {status_response.status_code} - {status_response.text}")
80
- # Continue polling even if status check fails temporarily
81
- attempt += 1
82
- continue
83
-
84
- try:
85
- status_data = status_response.json()
86
- print(f"Status check {attempt + 1}: {status_data}")
87
-
88
- if status_data.get("status") == "COMPLETED":
89
- # Job completed, get the result
90
- result_url = f"https://router.huggingface.co/fal-ai/fal-ai/flux-kontext/dev/requests/{request_id}"
91
- result_response = requests.get(result_url, headers=headers)
92
-
93
- if result_response.status_code != 200:
94
- print(f"Result response: {result_response.status_code} - {result_response.text}")
95
- raise gr.Error(f"Failed to get result: {result_response.status_code}")
96
-
97
- # Check if result is direct image bytes or JSON
98
- result_content_type = result_response.headers.get('content-type', '').lower()
99
- if 'image/' in result_content_type:
100
- # Direct image bytes
101
- return result_response.content
102
- else:
103
- # Try to parse as JSON for image URL or base64
104
- try:
105
- result_data = result_response.json()
106
- print(f"Result data: {result_data}")
107
-
108
- # Look for images in various formats
109
- if 'images' in result_data and len(result_data['images']) > 0:
110
- image_info = result_data['images'][0]
111
- if isinstance(image_info, dict) and 'url' in image_info:
112
- # Download the image
113
- img_response = requests.get(image_info['url'])
114
- return img_response.content
115
- elif isinstance(image_info, str):
116
- # Base64 encoded
117
- return base64.b64decode(image_info)
118
- elif 'image' in result_data:
119
- # Single image field
120
- if isinstance(result_data['image'], str):
121
- return base64.b64decode(result_data['image'])
122
- else:
123
- # Maybe it's direct image bytes
124
- return result_response.content
125
-
126
- except requests.exceptions.JSONDecodeError:
127
- # Result might be direct image bytes
128
- return result_response.content
129
-
130
- elif status_data.get("status") == "FAILED":
131
- error_msg = status_data.get("error", "Unknown error")
132
- raise gr.Error(f"Job failed: {error_msg}")
133
-
134
- # Still processing, continue polling
135
- attempt += 1
136
-
137
- except requests.exceptions.JSONDecodeError:
138
- print("Failed to parse status response, continuing...")
139
- attempt += 1
140
- continue
141
-
142
- raise gr.Error("Job timed out after 5 minutes")
143
 
144
  elif json_response.get("status") == "COMPLETED":
145
  # Job completed immediately
146
  if 'images' in json_response and len(json_response['images']) > 0:
147
  image_info = json_response['images'][0]
148
  if isinstance(image_info, dict) and 'url' in image_info:
 
 
149
  img_response = requests.get(image_info['url'])
150
  return img_response.content
151
  elif isinstance(image_info, str):
 
152
  return base64.b64decode(image_info)
153
  elif 'image' in json_response:
154
  return base64.b64decode(json_response['image'])
155
  else:
156
- raise gr.Error(f"No images found in immediate response: {json_response}")
157
 
158
  else:
159
  raise gr.Error(f"Unexpected response status: {json_response.get('status', 'unknown')}")
@@ -163,11 +97,24 @@ def query_api(payload, progress_callback=None):
163
 
164
  elif 'image/' in content_type:
165
  # Response is direct image bytes
 
 
166
  return response.content
167
 
168
  else:
169
- # Unknown content type, try to handle as bytes
170
- return response.content
 
 
 
 
 
 
 
 
 
 
 
171
 
172
  def upload_image_to_fal(image_bytes):
173
  """Upload image to fal.ai and return the URL"""
 
34
  del payload["image_bytes"]
35
 
36
  # Submit the job
37
+ if progress_callback:
38
+ progress_callback(0.1, "Submitting request...")
39
+
40
  response = requests.post(API_URL, headers=headers, json=payload)
41
 
42
  if response.status_code != 200:
 
44
 
45
  # Debug the response
46
  print(f"Response status: {response.status_code}")
 
47
  print(f"Response content type: {response.headers.get('content-type', 'unknown')}")
48
  print(f"Response content length: {len(response.content)}")
 
49
 
50
  # Check if response is JSON (queue status) or binary (direct image)
51
  content_type = response.headers.get('content-type', '').lower()
 
58
 
59
  # Check if job was queued
60
  if json_response.get("status") == "IN_QUEUE":
61
+ # For HF router, we should wait and let it handle the queue
62
+ # The router should eventually return the result automatically
63
+ if progress_callback:
64
+ progress_callback(0.5, "Processing in queue...")
65
 
66
+ # Wait a bit and try to get the response again
67
+ import time
68
+ time.sleep(10) # Wait 10 seconds for processing
69
 
70
+ # Make another request to check if it's ready
71
+ # But based on the error, we shouldn't poll manually
72
+ # Instead, let's return an error asking user to try again
73
+ raise gr.Error("Request is queued for processing. Please try again in a few moments.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  elif json_response.get("status") == "COMPLETED":
76
  # Job completed immediately
77
  if 'images' in json_response and len(json_response['images']) > 0:
78
  image_info = json_response['images'][0]
79
  if isinstance(image_info, dict) and 'url' in image_info:
80
+ if progress_callback:
81
+ progress_callback(0.9, "Downloading result...")
82
  img_response = requests.get(image_info['url'])
83
  return img_response.content
84
  elif isinstance(image_info, str):
85
+ # Base64 encoded image
86
  return base64.b64decode(image_info)
87
  elif 'image' in json_response:
88
  return base64.b64decode(json_response['image'])
89
  else:
90
+ raise gr.Error(f"No images found in response: {json_response}")
91
 
92
  else:
93
  raise gr.Error(f"Unexpected response status: {json_response.get('status', 'unknown')}")
 
97
 
98
  elif 'image/' in content_type:
99
  # Response is direct image bytes
100
+ if progress_callback:
101
+ progress_callback(1.0, "Complete!")
102
  return response.content
103
 
104
  else:
105
+ # Unknown content type, but try to handle as image bytes
106
+ # This might be the case where the router returns the image directly
107
+ if len(response.content) > 1000: # Likely an image if it's substantial
108
+ if progress_callback:
109
+ progress_callback(1.0, "Complete!")
110
+ return response.content
111
+ else:
112
+ # Small response, probably an error
113
+ try:
114
+ error_response = response.json()
115
+ raise gr.Error(f"API Error: {error_response}")
116
+ except:
117
+ raise gr.Error(f"Unexpected response: {response.content.decode()[:500]}")
118
 
119
  def upload_image_to_fal(image_bytes):
120
  """Upload image to fal.ai and return the URL"""