LeafCat79 commited on
Commit
507bbf7
Β·
verified Β·
1 Parent(s): d455ec5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -14
app.py CHANGED
@@ -19,6 +19,8 @@ import traceback
19
  import time
20
  import gradio as gr
21
  from openai import OpenAI
 
 
22
  from huggingface_hub import InferenceClient
23
  from PIL import Image
24
 
@@ -32,6 +34,7 @@ HF_TOKEN = os.environ.get("HF_TOKEN", "")
32
  CODE_MODEL = "llama-3.1-8b-instant" # Groq β€” game code
33
  PROMPT_MODEL = "llama-3.3-70b-versatile" # Groq β€” image prompt enhancement
34
  IMAGE_MODEL = "black-forest-labs/FLUX.1-dev" # fal-ai β€” image generation
 
35
 
36
  # Canvas dimensions β€” iframe is fixed to these so game fits perfectly
37
  CANVAS_W = 800
@@ -258,33 +261,71 @@ def _colored_placeholder(name: str) -> str:
258
  return "data:image/svg+xml;base64," + base64.b64encode(svg.encode()).decode()
259
 
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  def generate_sprites(image_prompts: dict) -> tuple:
262
  sprite_map = {}
263
  errors = []
264
 
265
- if not HF_TOKEN:
266
- errors.append("HF_TOKEN not set β€” using placeholder sprites. Add HF_TOKEN as a Space secret.")
267
- for sprite_name in image_prompts:
268
- sprite_map[sprite_name] = _colored_placeholder(sprite_name.replace(".png", ""))
269
- return sprite_map, errors
270
-
271
- client = InferenceClient(provider="fal-ai", api_key=HF_TOKEN)
272
-
273
- for sprite_name, prompt in image_prompts.items():
274
  try:
275
- is_bg = "background" in sprite_name
276
- pil_img = client.text_to_image(prompt, model=IMAGE_MODEL)
277
- # Remove background for character/object sprites (not background scene)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  if not is_bg:
279
  pil_img = _remove_background(pil_img)
280
  size = None if is_bg else (64, 64)
281
  sprite_map[sprite_name] = _pil_to_data_uri(pil_img, size=size)
282
- print(f"[FLUX.1-dev] OK: {sprite_name}")
 
283
  except Exception as exc:
284
  error_msg = str(exc)
285
  errors.append(f"{sprite_name}: {error_msg[:80]}")
286
- print(f"[FLUX.1-dev] FAILED {sprite_name}: {error_msg}")
287
  sprite_map[sprite_name] = _colored_placeholder(sprite_name.replace(".png", ""))
 
288
  return sprite_map, errors
289
 
290
  # ---------------------------------------------------------------------------
 
19
  import time
20
  import gradio as gr
21
  from openai import OpenAI
22
+ import requests
23
+ from urllib.parse import quote
24
  from huggingface_hub import InferenceClient
25
  from PIL import Image
26
 
 
34
  CODE_MODEL = "llama-3.1-8b-instant" # Groq β€” game code
35
  PROMPT_MODEL = "llama-3.3-70b-versatile" # Groq β€” image prompt enhancement
36
  IMAGE_MODEL = "black-forest-labs/FLUX.1-dev" # fal-ai β€” image generation
37
+ POLLINATIONS_URL = "https://image.pollinations.ai/prompt/{prompt}?width={w}&height={h}&model=flux&nologo=true&seed={seed}"
38
 
39
  # Canvas dimensions β€” iframe is fixed to these so game fits perfectly
40
  CANVAS_W = 800
 
261
  return "data:image/svg+xml;base64," + base64.b64encode(svg.encode()).decode()
262
 
263
 
264
+ def _generate_via_hf(prompt: str) -> Image.Image:
265
+ """Try FLUX.1-dev via HF auto-provider selection.
266
+ HF automatically picks the fastest available provider β€” if one is
267
+ quota-depleted it routes to the next available one automatically."""
268
+ client = InferenceClient(api_key=HF_TOKEN)
269
+ return client.text_to_image(prompt, model=IMAGE_MODEL)
270
+
271
+
272
+ def _generate_via_pollinations(prompt: str, sprite_name: str, is_bg: bool) -> Image.Image:
273
+ """Fallback: Pollinations.AI, free, no key needed."""
274
+ w, h = (CANVAS_W, CANVAS_H) if is_bg else (64, 64)
275
+ seed = abs(hash(sprite_name)) % 99999
276
+ url = POLLINATIONS_URL.format(prompt=quote(prompt), w=w, h=h, seed=seed)
277
+ for attempt in range(3):
278
+ try:
279
+ resp = requests.get(url, timeout=120)
280
+ resp.raise_for_status()
281
+ return Image.open(io.BytesIO(resp.content))
282
+ except Exception as exc:
283
+ if attempt < 2:
284
+ time.sleep(20)
285
+ else:
286
+ raise exc
287
+
288
+
289
  def generate_sprites(image_prompts: dict) -> tuple:
290
  sprite_map = {}
291
  errors = []
292
 
293
+ for i, (sprite_name, prompt) in enumerate(image_prompts.items()):
 
 
 
 
 
 
 
 
294
  try:
295
+ is_bg = "background" in sprite_name
296
+
297
+ # Try FLUX.1-dev via fal-ai if HF_TOKEN is set
298
+ if HF_TOKEN:
299
+ try:
300
+ pil_img = _generate_via_hf(prompt)
301
+ provider = "FLUX.1-dev/auto"
302
+ except Exception as fal_exc:
303
+ fal_err = str(fal_exc)
304
+ print(f"[fal-ai] Failed {sprite_name}: {fal_err} β€” falling back to Pollinations")
305
+ errors.append(f"{sprite_name} (fal-ai failed, used Pollinations): {fal_err[:60]}")
306
+ if i > 0:
307
+ time.sleep(20)
308
+ pil_img = _generate_via_pollinations(prompt, sprite_name, is_bg)
309
+ provider = "Pollinations"
310
+ else:
311
+ # No HF_TOKEN β€” go straight to Pollinations
312
+ if i > 0:
313
+ time.sleep(20)
314
+ pil_img = _generate_via_pollinations(prompt, sprite_name, is_bg)
315
+ provider = "Pollinations"
316
+
317
  if not is_bg:
318
  pil_img = _remove_background(pil_img)
319
  size = None if is_bg else (64, 64)
320
  sprite_map[sprite_name] = _pil_to_data_uri(pil_img, size=size)
321
+ print(f"[{provider}] OK: {sprite_name}")
322
+
323
  except Exception as exc:
324
  error_msg = str(exc)
325
  errors.append(f"{sprite_name}: {error_msg[:80]}")
326
+ print(f"[Image] FAILED {sprite_name}: {error_msg}")
327
  sprite_map[sprite_name] = _colored_placeholder(sprite_name.replace(".png", ""))
328
+
329
  return sprite_map, errors
330
 
331
  # ---------------------------------------------------------------------------