akhaliq HF Staff commited on
Commit
e1f8042
·
verified ·
1 Parent(s): 90342ab

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -25
app.py CHANGED
@@ -14,7 +14,7 @@ MAX_SEED = np.iinfo(np.int32).max
14
  API_URL = "https://router.huggingface.co/fal-ai/fal-ai/flux-kontext/dev?_subdomain=queue"
15
 
16
  def get_headers():
17
- """Get headers for API requests"""
18
  hf_token = os.getenv("HF_TOKEN")
19
  if not hf_token:
20
  raise gr.Error("HF_TOKEN environment variable not found. Please add your Hugging Face token to the Space settings.")
@@ -24,12 +24,25 @@ def get_headers():
24
  "X-HF-Bill-To": "huggingface"
25
  }
26
 
27
- def query_api(payload, progress_callback=None):
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  """Send request to the API and return response"""
29
- headers = get_headers()
30
 
31
  # Submit the job
32
- response = requests.post(API_URL, headers=headers, json=payload)
33
 
34
  if response.status_code != 200:
35
  raise gr.Error(f"API request failed with status {response.status_code}: {response.text}")
@@ -47,6 +60,9 @@ def query_api(payload, progress_callback=None):
47
  if not status_url:
48
  raise gr.Error("No status URL provided in queue response")
49
 
 
 
 
50
  # Poll for completion
51
  max_attempts = 60 # Wait up to 5 minutes (60 * 5 seconds)
52
  attempt = 0
@@ -57,12 +73,8 @@ def query_api(payload, progress_callback=None):
57
 
58
  time.sleep(5) # Wait 5 seconds between polls
59
 
60
- # Check status - try without auth headers first, then with auth headers
61
- status_response = requests.get(status_url)
62
-
63
- # If unauthorized, try with headers
64
- if status_response.status_code == 401:
65
- status_response = requests.get(status_url, headers=headers)
66
 
67
  if status_response.status_code != 200:
68
  print(f"Status response: {status_response.status_code} - {status_response.text}")
@@ -78,10 +90,8 @@ def query_api(payload, progress_callback=None):
78
  if not response_url:
79
  raise gr.Error("No response URL provided")
80
 
81
- # Try to get result without auth first, then with auth
82
- result_response = requests.get(response_url)
83
- if result_response.status_code == 401:
84
- result_response = requests.get(response_url, headers=headers)
85
 
86
  if result_response.status_code != 200:
87
  print(f"Result response: {result_response.status_code} - {result_response.text}")
@@ -161,7 +171,7 @@ def chat_fn(message, chat_history, seed, randomize_seed, guidance_scale, steps,
161
  if randomize_seed:
162
  seed = random.randint(0, MAX_SEED)
163
 
164
- # Prepare the payload
165
  payload = {
166
  "parameters": {
167
  "prompt": prompt,
@@ -182,14 +192,14 @@ def chat_fn(message, chat_history, seed, randomize_seed, guidance_scale, steps,
182
  # Auto-orient the image based on EXIF data
183
  input_image = ImageOps.exif_transpose(input_image)
184
 
185
- # Convert PIL image to base64 for the API
186
  img_byte_arr = io.BytesIO()
187
  input_image.save(img_byte_arr, format='PNG')
188
  img_byte_arr.seek(0)
189
- image_base64 = base64.b64encode(img_byte_arr.getvalue()).decode('utf-8')
190
 
191
- # Add image to payload for image-to-image
192
- payload["inputs"] = image_base64
193
 
194
  except Exception as e:
195
  raise gr.Error(f"Could not process the uploaded image: {str(e)}. Please try uploading a different image format (JPEG, PNG, WebP).")
@@ -197,12 +207,12 @@ def chat_fn(message, chat_history, seed, randomize_seed, guidance_scale, steps,
197
  progress(0.1, desc="Processing image...")
198
  else:
199
  print(f"Received prompt for text-to-image: {prompt}")
200
- # For text-to-image, we don't need the inputs field
201
  progress(0.1, desc="Generating image...")
202
 
203
  try:
204
- # Make API request with progress callback
205
- image_bytes = query_api(payload, progress_callback=progress)
206
 
207
  # Try to convert response bytes to PIL Image
208
  try:
@@ -236,11 +246,11 @@ steps_slider = gr.Slider(label="Steps", minimum=1, maximum=30, value=28, step=1)
236
 
237
  demo = gr.ChatInterface(
238
  fn=chat_fn,
239
- title="FLUX.1 Kontext [dev] - Direct API",
240
  description="""<p style='text-align: center;'>
241
- A simple chat UI for the <b>FLUX.1 Kontext</b> model using direct API calls with requests.
242
  <br>
243
- To edit an image, upload it and type your instructions (e.g., "Add a hat").
244
  <br>
245
  To generate an image, just type a prompt (e.g., "A photo of an astronaut on a horse").
246
  <br>
 
14
  API_URL = "https://router.huggingface.co/fal-ai/fal-ai/flux-kontext/dev?_subdomain=queue"
15
 
16
  def get_headers():
17
+ """Get headers for Hugging Face router API requests"""
18
  hf_token = os.getenv("HF_TOKEN")
19
  if not hf_token:
20
  raise gr.Error("HF_TOKEN environment variable not found. Please add your Hugging Face token to the Space settings.")
 
24
  "X-HF-Bill-To": "huggingface"
25
  }
26
 
27
+ def upload_image_to_fal(image_bytes):
28
+ """Upload image to fal.ai and return the URL"""
29
+ # For now, we'll use base64 data URI as mentioned in the docs
30
+ # fal.ai supports base64 data URIs for image_url
31
+ image_base64 = base64.b64encode(image_bytes).decode('utf-8')
32
+ # Detect image format
33
+ try:
34
+ img = Image.open(io.BytesIO(image_bytes))
35
+ format_map = {'JPEG': 'jpeg', 'PNG': 'png', 'WEBP': 'webp'}
36
+ img_format = format_map.get(img.format, 'jpeg')
37
+ except:
38
+ img_format = 'jpeg'
39
+
40
+ return f"data:image/{img_format};base64,{image_base64}"
41
  """Send request to the API and return response"""
42
+ hf_headers = get_headers()
43
 
44
  # Submit the job
45
+ response = requests.post(API_URL, headers=hf_headers, json=payload)
46
 
47
  if response.status_code != 200:
48
  raise gr.Error(f"API request failed with status {response.status_code}: {response.text}")
 
60
  if not status_url:
61
  raise gr.Error("No status URL provided in queue response")
62
 
63
+ # For fal.ai endpoints, we need different headers
64
+ fal_headers = get_fal_headers()
65
+
66
  # Poll for completion
67
  max_attempts = 60 # Wait up to 5 minutes (60 * 5 seconds)
68
  attempt = 0
 
73
 
74
  time.sleep(5) # Wait 5 seconds between polls
75
 
76
+ # Check status with fal.ai headers
77
+ status_response = requests.get(status_url, headers=fal_headers)
 
 
 
 
78
 
79
  if status_response.status_code != 200:
80
  print(f"Status response: {status_response.status_code} - {status_response.text}")
 
90
  if not response_url:
91
  raise gr.Error("No response URL provided")
92
 
93
+ # Get result with fal.ai headers
94
+ result_response = requests.get(response_url, headers=fal_headers)
 
 
95
 
96
  if result_response.status_code != 200:
97
  print(f"Result response: {result_response.status_code} - {result_response.text}")
 
171
  if randomize_seed:
172
  seed = random.randint(0, MAX_SEED)
173
 
174
+ # Prepare the payload for Hugging Face router
175
  payload = {
176
  "parameters": {
177
  "prompt": prompt,
 
192
  # Auto-orient the image based on EXIF data
193
  input_image = ImageOps.exif_transpose(input_image)
194
 
195
+ # Convert PIL image to bytes
196
  img_byte_arr = io.BytesIO()
197
  input_image.save(img_byte_arr, format='PNG')
198
  img_byte_arr.seek(0)
199
+ image_bytes = img_byte_arr.getvalue()
200
 
201
+ # Add image bytes to payload - will be converted to base64 in query_api
202
+ payload["image_bytes"] = image_bytes
203
 
204
  except Exception as e:
205
  raise gr.Error(f"Could not process the uploaded image: {str(e)}. Please try uploading a different image format (JPEG, PNG, WebP).")
 
207
  progress(0.1, desc="Processing image...")
208
  else:
209
  print(f"Received prompt for text-to-image: {prompt}")
210
+ # For text-to-image, we don't need an input image
211
  progress(0.1, desc="Generating image...")
212
 
213
  try:
214
+ # Make API request
215
+ image_bytes = query_api(payload)
216
 
217
  # Try to convert response bytes to PIL Image
218
  try:
 
246
 
247
  demo = gr.ChatInterface(
248
  fn=chat_fn,
249
+ title="FLUX.1 Kontext [dev] - Hugging Face Router",
250
  description="""<p style='text-align: center;'>
251
+ A simple chat UI for the <b>FLUX.1 Kontext [dev]</b> model using Hugging Face router.
252
  <br>
253
+ To edit an image, upload it and type your instructions (e.g., "Add a hat", "Turn the cat into a tiger").
254
  <br>
255
  To generate an image, just type a prompt (e.g., "A photo of an astronaut on a horse").
256
  <br>