Rosyad Almas commited on
Commit
2a0dc35
Β·
verified Β·
1 Parent(s): 297ded9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -55
app.py CHANGED
@@ -208,36 +208,35 @@ def infer(images_b64_json, prompt, seed, randomize_seed, guidance_scale, steps,
208
  torch.cuda.empty_cache()
209
 
210
 
211
- # ─────────────────────────────────────────────
212
- # Clean API endpoint β€” usable via Gradio API
213
- # ─────────────────────────────────────────────
214
  @spaces.GPU
215
  def api_edit(
216
- image: Image.Image,
217
  prompt: str,
218
  seed: int = 0,
219
  randomize_seed: bool = True,
220
  guidance_scale: float = 1.0,
221
  steps: int = 4,
222
- extra_image: Image.Image = None,
223
  ) -> tuple:
224
  """
225
- Edit an image using the FireRed / Qwen image editing pipeline.
226
 
227
  Parameters
228
  ----------
229
- image : The main input image (PIL Image).
230
- prompt : Edit instruction, e.g. 'Convert to anime style'.
231
- seed : Random seed (ignored when randomize_seed=True).
232
- randomize_seed : If True a random seed is used each call.
233
- guidance_scale : CFG scale (1.0–10.0). Keep at 1.0 for the rapid model.
234
- steps : Inference steps (default 4 for the rapid/distilled model).
235
- extra_image : Optional second reference image (e.g. clothing reference).
236
 
237
  Returns
238
  -------
239
- result_image : Edited PIL Image.
240
- seed_used : The seed that was actually used.
241
  """
242
  import base64, json
243
  from io import BytesIO
@@ -247,19 +246,14 @@ def api_edit(
247
  if not prompt or not prompt.strip():
248
  raise gr.Error("prompt is required.")
249
 
250
- # Pack images into the b64 JSON format that infer() expects
251
- pil_list = [image]
252
- if extra_image is not None:
253
- pil_list.append(extra_image)
254
-
255
  b64_list = []
256
  for img in pil_list:
257
  buf = BytesIO()
258
  img.save(buf, format="PNG")
259
  b64_list.append("data:image/png;base64," + base64.b64encode(buf.getvalue()).decode())
260
 
261
- images_b64_json = json.dumps(b64_list)
262
- return infer(images_b64_json, prompt, seed, randomize_seed, guidance_scale, steps)
263
 
264
 
265
  css = r"""
@@ -1202,43 +1196,31 @@ with gr.Blocks() as demo:
1202
  queue=False,
1203
  )
1204
 
1205
- # ── Dedicated API tab (separate from the custom HTML UI) ──
1206
- with gr.Blocks() as api_demo:
1207
- gr.Markdown("## Image Edit API")
1208
- gr.Markdown(
1209
- "Send requests to `/api/edit` programmatically. "
1210
- "See the [API docs](/api) for the full schema."
1211
- )
1212
- with gr.Row():
1213
- with gr.Column():
1214
- api_image_in = gr.Image(type="pil", label="Input Image")
1215
- api_extra_in = gr.Image(type="pil", label="Reference Image (optional)")
1216
- api_prompt_in = gr.Textbox(label="Prompt", placeholder="Convert to anime style")
1217
- api_seed_in = gr.Slider(0, MAX_SEED, value=0, step=1, label="Seed")
1218
- api_rand_in = gr.Checkbox(value=True, label="Randomize seed")
1219
- api_cfg_in = gr.Slider(1.0, 10.0, value=1.0, step=0.1, label="Guidance scale")
1220
- api_steps_in = gr.Slider(1, 50, value=4, step=1, label="Steps")
1221
- api_run_btn = gr.Button("Edit", variant="primary")
1222
- with gr.Column():
1223
- api_image_out = gr.Image(type="pil", label="Result")
1224
- api_seed_out = gr.Number(label="Seed used")
1225
-
1226
- api_run_btn.click(
1227
  fn=api_edit,
1228
- inputs=[api_image_in, api_prompt_in, api_seed_in, api_rand_in,
1229
- api_cfg_in, api_steps_in, api_extra_in],
1230
- outputs=[api_image_out, api_seed_out],
1231
- api_name="edit", # β†’ callable as client.predict(..., api_name="/edit")
1232
  )
1233
 
1234
- combined = gr.TabbedInterface(
1235
- [demo, api_demo],
1236
- ["UI", "API"],
1237
- title="FireRed Image Edit",
1238
- )
1239
-
1240
  if __name__ == "__main__":
1241
- combined.queue(max_size=30).launch(
 
1242
  mcp_server=True,
1243
  ssr_mode=False,
1244
  show_error=True,
 
208
  torch.cuda.empty_cache()
209
 
210
 
211
+ # ─────────────────────────────────────────
212
+ # API endpoint β€” /api/predict or /api/edit
213
+ # ─────────────────────────────────────────
214
  @spaces.GPU
215
  def api_edit(
216
+ image: "Image.Image",
217
  prompt: str,
218
  seed: int = 0,
219
  randomize_seed: bool = True,
220
  guidance_scale: float = 1.0,
221
  steps: int = 4,
222
+ extra_image: "Image.Image" = None,
223
  ) -> tuple:
224
  """
225
+ Edit an image with a text prompt.
226
 
227
  Parameters
228
  ----------
229
+ image : Input PIL image.
230
+ prompt : Edit instruction e.g. 'Convert to anime style'.
231
+ seed : Seed (ignored when randomize_seed=True).
232
+ randomize_seed : Use a random seed each call.
233
+ guidance_scale : CFG scale 1.0–10.0 (keep 1.0 for rapid model).
234
+ steps : Inference steps (default 4).
235
+ extra_image : Optional second reference image.
236
 
237
  Returns
238
  -------
239
+ (result_image, seed_used)
 
240
  """
241
  import base64, json
242
  from io import BytesIO
 
246
  if not prompt or not prompt.strip():
247
  raise gr.Error("prompt is required.")
248
 
249
+ pil_list = [image] + ([extra_image] if extra_image is not None else [])
 
 
 
 
250
  b64_list = []
251
  for img in pil_list:
252
  buf = BytesIO()
253
  img.save(buf, format="PNG")
254
  b64_list.append("data:image/png;base64," + base64.b64encode(buf.getvalue()).decode())
255
 
256
+ return infer(json.dumps(b64_list), prompt, seed, randomize_seed, guidance_scale, steps)
 
257
 
258
 
259
  css = r"""
 
1196
  queue=False,
1197
  )
1198
 
1199
+ # Wire a named API route directly onto the existing demo block
1200
+ # This exposes /api/edit without touching the UI at all
1201
+ with demo:
1202
+ _api_img_in = gr.Image(type="pil", visible=False, label="image")
1203
+ _api_extra_in = gr.Image(type="pil", visible=False, label="extra_image")
1204
+ _api_prompt_in = gr.Textbox(visible=False, label="prompt")
1205
+ _api_seed_in = gr.Slider(0, MAX_SEED, value=0, step=1, visible=False, label="seed")
1206
+ _api_rand_in = gr.Checkbox(value=True, visible=False, label="randomize_seed")
1207
+ _api_cfg_in = gr.Slider(1.0, 10.0, value=1.0, step=0.1, visible=False, label="guidance_scale")
1208
+ _api_steps_in = gr.Slider(1, 50, value=4, step=1, visible=False, label="steps")
1209
+ _api_img_out = gr.Image(type="pil", visible=False, label="result_image")
1210
+ _api_seed_out = gr.Number(visible=False, label="seed_used")
1211
+
1212
+ _api_btn = gr.Button(visible=False)
1213
+ _api_btn.click(
 
 
 
 
 
 
 
1214
  fn=api_edit,
1215
+ inputs=[_api_img_in, _api_prompt_in, _api_seed_in, _api_rand_in,
1216
+ _api_cfg_in, _api_steps_in, _api_extra_in],
1217
+ outputs=[_api_img_out, _api_seed_out],
1218
+ api_name="edit",
1219
  )
1220
 
 
 
 
 
 
 
1221
  if __name__ == "__main__":
1222
+ demo.queue(max_size=30).launch(
1223
+ css=css,
1224
  mcp_server=True,
1225
  ssr_mode=False,
1226
  show_error=True,