Laramie2 commited on
Commit
d7f1367
·
verified ·
1 Parent(s): 9d4ee7c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -35
app.py CHANGED
@@ -171,7 +171,6 @@ def save_api_settings(api_key, api_base_url=None):
171
  if api_base_url:
172
  success_msg += ", Base URL updated"
173
 
174
- # 返回成功消息和 True (表示 API 已就绪)
175
  return success_msg, get_debug_info(), True
176
  except Exception as e:
177
  return f"❌ Error: {str(e)}", get_debug_info(), False
@@ -186,7 +185,6 @@ def save_pdf(file):
186
 
187
  file_path = os.path.join(PAPERS_DIR, os.path.basename(file.name))
188
  shutil.copy(file.name, file_path)
189
- # 返回成功消息和 True (表示 PDF 已就绪)
190
  return f"✅ Saved: {os.path.basename(file.name)}", get_debug_info(), True
191
  except Exception as e:
192
  return f"❌ Error: {str(e)}", get_debug_info(), False
@@ -221,7 +219,6 @@ def clear_pdf():
221
  os.remove(ZIP_OUTPUT_PATH)
222
 
223
  disable_btn = gr.update(interactive=False)
224
- # 返回:状态文本, debug视窗, pdf_ready=False, 以及锁定4个生成按钮
225
  if deleted_files or deleted_dirs:
226
  return f"🗑️ Workspace cleared", get_debug_info(), False, disable_btn, disable_btn, disable_btn, disable_btn
227
  return "ℹ️ Workspace is already empty", get_debug_info(), False, disable_btn, disable_btn, disable_btn, disable_btn
@@ -232,8 +229,12 @@ def run_mineru_parsing_and_dag_gen():
232
  no_change = gr.update()
233
  disable_btn = gr.update(interactive=False)
234
 
 
 
 
 
235
  if not os.path.exists(PAPERS_DIR) or not any(f.endswith('.pdf') for f in os.listdir(PAPERS_DIR)):
236
- yield "❌ No PDF file found", get_debug_info(), "No execution logs.", no_change, no_change, no_change, no_change
237
  return
238
 
239
  full_log = ""
@@ -246,55 +247,59 @@ def run_mineru_parsing_and_dag_gen():
246
 
247
  command_mineru = ["mineru", "-p", PAPERS_DIR, "-o", OUTPUT_DIR]
248
  full_log += "--- Mineru Executing ---\n"
249
- # 运行中保持按钮状态不变
250
- yield "⏳ Executing Mineru parsing...", get_debug_info(), full_log, no_change, no_change, no_change, no_change
 
251
 
252
  process_mineru = subprocess.Popen(
253
  command_mineru, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1
254
  )
255
  for line in iter(process_mineru.stdout.readline, ''):
256
  full_log += line
257
- yield "⏳ Executing Mineru parsing...", get_debug_info(), full_log, no_change, no_change, no_change, no_change
258
  process_mineru.stdout.close()
259
  returncode_mineru = process_mineru.wait()
260
 
261
  if returncode_mineru != 0:
262
- yield f"❌ Mineru parsing failed (Exit Code: {returncode_mineru})", get_debug_info(), full_log, disable_btn, disable_btn, disable_btn, disable_btn
263
  return
264
 
265
  command_dag = [sys.executable, "gen_dag.py"]
266
  full_log += "\n--- DAG Gen Executing ---\n"
267
- yield "⏳ Mineru parsing complete, executing DAG generation...", get_debug_info(), full_log, no_change, no_change, no_change, no_change
268
 
269
  process_dag = subprocess.Popen(
270
  command_dag, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1
271
  )
272
  for line in iter(process_dag.stdout.readline, ''):
273
  full_log += line
274
- yield "⏳ Executing DAG generation...", get_debug_info(), full_log, no_change, no_change, no_change, no_change
275
  process_dag.stdout.close()
276
  returncode_dag = process_dag.wait()
277
 
278
- # 解析完全成功,解锁第三部分的按钮
279
  if returncode_dag == 0:
280
  status = "✅ PDF parsing & DAG generation fully completed"
281
  enable_btn = gr.update(interactive=True)
282
- yield status, get_debug_info(), full_log, enable_btn, enable_btn, enable_btn, enable_btn
283
  else:
284
  status = f"❌ DAG generation failed (Exit Code: {returncode_dag})"
285
- yield status, get_debug_info(), full_log, disable_btn, disable_btn, disable_btn, disable_btn
286
 
287
  except Exception as e:
288
  error_log = full_log + f"\n[Global Exception] Exception occurred:\n{str(e)}"
289
- yield "❌ Execution Exception", get_debug_info(), error_log, disable_btn, disable_btn, disable_btn, disable_btn
290
 
291
 
292
  def run_final_generation(task_type="all"):
293
  """
294
  使用队列和多线程实时获取子进程的流式输出,并通过 yield 推送到前端界面。
295
  """
 
 
 
296
  if not os.path.exists(OUTPUT_DIR):
297
- yield "❌ Please run the parsing step first", get_debug_info(), "No output folder found.", gr.update(visible=False)
298
  return
299
 
300
  scripts_to_run = []
@@ -303,11 +308,12 @@ def run_final_generation(task_type="all"):
303
  elif task_type == "pr": scripts_to_run = ["gen_pr.py"]
304
  elif task_type == "all": scripts_to_run = ["gen_ppt.py", "gen_poster.py", "gen_pr.py"]
305
  else:
306
- yield "❌ Unknown task type", get_debug_info(), "Invalid task_type.", gr.update(visible=False)
307
  return
308
 
309
  full_log = f"🚀 Preparing to start {len(scripts_to_run)} tasks...\n"
310
- yield f"⏳ Starting {task_type.upper()} generation...", get_debug_info(), full_log, gr.update(visible=False)
 
311
 
312
  q = queue.Queue()
313
  processes = []
@@ -336,7 +342,7 @@ def run_final_generation(task_type="all"):
336
  try:
337
  script_name, line = q.get(timeout=0.1)
338
  full_log += f"[{script_name}] {line}"
339
- yield f"⏳ Generating {task_type.upper()}...", get_debug_info(), full_log, gr.update(visible=False)
340
  except queue.Empty:
341
  active_processes = sum(1 for _, p in processes if p.poll() is None)
342
 
@@ -347,21 +353,21 @@ def run_final_generation(task_type="all"):
347
  full_log += f"\n❌ [Error] {script} returned non-zero exit code (Exit Code: {p.returncode})\n"
348
 
349
  if not success:
350
- yield f"❌ {task_type.upper()} contains failed tasks, please check logs", get_debug_info(), full_log, gr.update(visible=False)
351
  return
352
 
353
  full_log += "\n📦 Zipping output directory...\n"
354
- yield f"⏳ Zipping outputs...", get_debug_info(), full_log, gr.update(visible=False)
355
 
356
  zip_base_name = ZIP_OUTPUT_PATH.replace(".zip", "")
357
  shutil.make_archive(zip_base_name, 'zip', OUTPUT_DIR)
358
 
359
  full_log += "✅ All tasks and zipping completed successfully.\n"
360
- yield f"✅ {task_type.upper()} generated and zipped successfully", get_debug_info(), full_log, gr.update(value=ZIP_OUTPUT_PATH, visible=True)
361
 
362
  except Exception as e:
363
  error_log = full_log + f"\n[Global Exception] Exception occurred:\n{str(e)}"
364
- yield "❌ Global exception during final generation", get_debug_info(), error_log, gr.update(visible=False)
365
 
366
 
367
  # ==========================================
@@ -395,10 +401,29 @@ body, .gradio-container {
395
 
396
  @keyframes gradient-shift { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
397
 
398
- #subtitle { text-align: center !important; margin-bottom: 2rem; }
399
  #subtitle p { margin: 0 auto; color: #666; font-size: 1.1rem; font-weight: 500; }
400
  .dark #subtitle p { color: #DAB2FF; }
401
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
402
  .gradio-group {
403
  background: rgba(255, 255, 255, 0.9) !important;
404
  border: 2px solid #E9D5FF !important;
@@ -473,7 +498,7 @@ body, .gradio-container {
473
  margin-right: auto !important;
474
  margin-top: 10px !important;
475
  margin-bottom: 10px !important;
476
- display: block !important;
477
  transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.3s ease !important;
478
  box-shadow: 0 4px 15px rgba(126, 34, 206, 0.3) !important;
479
  cursor: pointer !important;
@@ -549,6 +574,13 @@ with gr.Blocks(theme=purple_theme, css=custom_css) as demo:
549
  gr.Markdown("# **PaperX Platform**", elem_id="main-title")
550
  gr.Markdown("One-click parsing of academic PDFs, DAG structuring, and multi-modal asset generation.", elem_id="subtitle")
551
 
 
 
 
 
 
 
 
552
  with gr.Row():
553
  # ================= LEFT COLUMN: SETTINGS & ACTIONS =================
554
  with gr.Column(scale=1):
@@ -625,7 +657,6 @@ with gr.Blocks(theme=purple_theme, css=custom_css) as demo:
625
  # ================= LOGIC BINDINGS =================
626
 
627
  # [步骤 1] 配置 API
628
- # 成功后不仅更新 UI 文本,还会将 api_saved_state 设置为 True
629
  key_btn.click(
630
  fn=save_api_settings,
631
  inputs=[key_input, api_base_url_input],
@@ -633,11 +664,9 @@ with gr.Blocks(theme=purple_theme, css=custom_css) as demo:
633
  )
634
 
635
  # [步骤 2.1] 上传 PDF
636
- # 成功后更新文本,并将 pdf_ready_state 设置为 True
637
  pdf_input.upload(fn=save_pdf, inputs=pdf_input, outputs=[parse_status, debug_view, pdf_ready_state])
638
 
639
  # [步骤 2.2] 清除 PDF
640
- # 会锁定第四步的所有生成按钮,同时将 pdf_ready_state 重置为 False
641
  pdf_input.clear(
642
  fn=clear_pdf,
643
  outputs=[parse_status, debug_view, pdf_ready_state, gen_ppt_btn, gen_poster_btn, gen_pr_btn, gen_all_btn]
@@ -650,11 +679,10 @@ with gr.Blocks(theme=purple_theme, css=custom_css) as demo:
650
  api_saved_state.change(fn=check_parse_btn_ready, inputs=[api_saved_state, pdf_ready_state], outputs=parse_btn)
651
  pdf_ready_state.change(fn=check_parse_btn_ready, inputs=[api_saved_state, pdf_ready_state], outputs=parse_btn)
652
 
653
- # [步骤 2.3] 执行解析
654
- # 如果完全成功,函数最后的一个 yield 会连带输出 interactive=True 给这4个生成按钮
655
  parse_btn.click(
656
  fn=run_mineru_parsing_and_dag_gen,
657
- outputs=[parse_status, debug_view, cmd_logs, gen_ppt_btn, gen_poster_btn, gen_pr_btn, gen_all_btn]
658
  )
659
 
660
  # [步骤 3] 资产生成
@@ -663,12 +691,13 @@ with gr.Blocks(theme=purple_theme, css=custom_css) as demo:
663
  def trigger_gen_pr(): yield from run_final_generation("pr")
664
  def trigger_gen_all(): yield from run_final_generation("all")
665
 
666
- gen_ppt_btn.click(fn=trigger_gen_ppt, outputs=[gen_status, debug_view, cmd_logs, download_file])
667
- gen_poster_btn.click(fn=trigger_gen_poster, outputs=[gen_status, debug_view, cmd_logs, download_file])
668
- gen_pr_btn.click(fn=trigger_gen_pr, outputs=[gen_status, debug_view, cmd_logs, download_file])
669
- gen_all_btn.click(fn=trigger_gen_all, outputs=[gen_status, debug_view, cmd_logs, download_file])
 
670
 
671
  refresh_btn.click(fn=get_debug_info, outputs=debug_view)
672
 
673
  if __name__ == "__main__":
674
- demo.launch(debug=True)
 
171
  if api_base_url:
172
  success_msg += ", Base URL updated"
173
 
 
174
  return success_msg, get_debug_info(), True
175
  except Exception as e:
176
  return f"❌ Error: {str(e)}", get_debug_info(), False
 
185
 
186
  file_path = os.path.join(PAPERS_DIR, os.path.basename(file.name))
187
  shutil.copy(file.name, file_path)
 
188
  return f"✅ Saved: {os.path.basename(file.name)}", get_debug_info(), True
189
  except Exception as e:
190
  return f"❌ Error: {str(e)}", get_debug_info(), False
 
219
  os.remove(ZIP_OUTPUT_PATH)
220
 
221
  disable_btn = gr.update(interactive=False)
 
222
  if deleted_files or deleted_dirs:
223
  return f"🗑️ Workspace cleared", get_debug_info(), False, disable_btn, disable_btn, disable_btn, disable_btn
224
  return "ℹ️ Workspace is already empty", get_debug_info(), False, disable_btn, disable_btn, disable_btn, disable_btn
 
229
  no_change = gr.update()
230
  disable_btn = gr.update(interactive=False)
231
 
232
+ # 进度条显示 (visible=True)
233
+ show_progress = gr.update(visible=True)
234
+ hide_progress = gr.update(visible=False)
235
+
236
  if not os.path.exists(PAPERS_DIR) or not any(f.endswith('.pdf') for f in os.listdir(PAPERS_DIR)):
237
+ yield "❌ No PDF file found", get_debug_info(), "No execution logs.", no_change, no_change, no_change, no_change, hide_progress
238
  return
239
 
240
  full_log = ""
 
247
 
248
  command_mineru = ["mineru", "-p", PAPERS_DIR, "-o", OUTPUT_DIR]
249
  full_log += "--- Mineru Executing ---\n"
250
+
251
+ # 激活显示全局进度条
252
+ yield "⏳ Executing Mineru parsing...", get_debug_info(), full_log, no_change, no_change, no_change, no_change, show_progress
253
 
254
  process_mineru = subprocess.Popen(
255
  command_mineru, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1
256
  )
257
  for line in iter(process_mineru.stdout.readline, ''):
258
  full_log += line
259
+ yield "⏳ Executing Mineru parsing...", get_debug_info(), full_log, no_change, no_change, no_change, no_change, show_progress
260
  process_mineru.stdout.close()
261
  returncode_mineru = process_mineru.wait()
262
 
263
  if returncode_mineru != 0:
264
+ yield f"❌ Mineru parsing failed (Exit Code: {returncode_mineru})", get_debug_info(), full_log, disable_btn, disable_btn, disable_btn, disable_btn, hide_progress
265
  return
266
 
267
  command_dag = [sys.executable, "gen_dag.py"]
268
  full_log += "\n--- DAG Gen Executing ---\n"
269
+ yield "⏳ Mineru parsing complete, executing DAG generation...", get_debug_info(), full_log, no_change, no_change, no_change, no_change, show_progress
270
 
271
  process_dag = subprocess.Popen(
272
  command_dag, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1
273
  )
274
  for line in iter(process_dag.stdout.readline, ''):
275
  full_log += line
276
+ yield "⏳ Executing DAG generation...", get_debug_info(), full_log, no_change, no_change, no_change, no_change, show_progress
277
  process_dag.stdout.close()
278
  returncode_dag = process_dag.wait()
279
 
280
+ # 解析完全成功,解锁第三部分的按钮,并隐藏进度条
281
  if returncode_dag == 0:
282
  status = "✅ PDF parsing & DAG generation fully completed"
283
  enable_btn = gr.update(interactive=True)
284
+ yield status, get_debug_info(), full_log, enable_btn, enable_btn, enable_btn, enable_btn, hide_progress
285
  else:
286
  status = f"❌ DAG generation failed (Exit Code: {returncode_dag})"
287
+ yield status, get_debug_info(), full_log, disable_btn, disable_btn, disable_btn, disable_btn, hide_progress
288
 
289
  except Exception as e:
290
  error_log = full_log + f"\n[Global Exception] Exception occurred:\n{str(e)}"
291
+ yield "❌ Execution Exception", get_debug_info(), error_log, disable_btn, disable_btn, disable_btn, disable_btn, hide_progress
292
 
293
 
294
  def run_final_generation(task_type="all"):
295
  """
296
  使用队列和多线程实时获取子进程的流式输出,并通过 yield 推送到前端界面。
297
  """
298
+ show_progress = gr.update(visible=True)
299
+ hide_progress = gr.update(visible=False)
300
+
301
  if not os.path.exists(OUTPUT_DIR):
302
+ yield "❌ Please run the parsing step first", get_debug_info(), "No output folder found.", gr.update(visible=False), hide_progress
303
  return
304
 
305
  scripts_to_run = []
 
308
  elif task_type == "pr": scripts_to_run = ["gen_pr.py"]
309
  elif task_type == "all": scripts_to_run = ["gen_ppt.py", "gen_poster.py", "gen_pr.py"]
310
  else:
311
+ yield "❌ Unknown task type", get_debug_info(), "Invalid task_type.", gr.update(visible=False), hide_progress
312
  return
313
 
314
  full_log = f"🚀 Preparing to start {len(scripts_to_run)} tasks...\n"
315
+ # 激活全局进度条
316
+ yield f"⏳ Starting {task_type.upper()} generation...", get_debug_info(), full_log, gr.update(visible=False), show_progress
317
 
318
  q = queue.Queue()
319
  processes = []
 
342
  try:
343
  script_name, line = q.get(timeout=0.1)
344
  full_log += f"[{script_name}] {line}"
345
+ yield f"⏳ Generating {task_type.upper()}...", get_debug_info(), full_log, gr.update(visible=False), show_progress
346
  except queue.Empty:
347
  active_processes = sum(1 for _, p in processes if p.poll() is None)
348
 
 
353
  full_log += f"\n❌ [Error] {script} returned non-zero exit code (Exit Code: {p.returncode})\n"
354
 
355
  if not success:
356
+ yield f"❌ {task_type.upper()} contains failed tasks, please check logs", get_debug_info(), full_log, gr.update(visible=False), hide_progress
357
  return
358
 
359
  full_log += "\n📦 Zipping output directory...\n"
360
+ yield f"⏳ Zipping outputs...", get_debug_info(), full_log, gr.update(visible=False), show_progress
361
 
362
  zip_base_name = ZIP_OUTPUT_PATH.replace(".zip", "")
363
  shutil.make_archive(zip_base_name, 'zip', OUTPUT_DIR)
364
 
365
  full_log += "✅ All tasks and zipping completed successfully.\n"
366
+ yield f"✅ {task_type.upper()} generated and zipped successfully", get_debug_info(), full_log, gr.update(value=ZIP_OUTPUT_PATH, visible=True), hide_progress
367
 
368
  except Exception as e:
369
  error_log = full_log + f"\n[Global Exception] Exception occurred:\n{str(e)}"
370
+ yield "❌ Global exception during final generation", get_debug_info(), error_log, gr.update(visible=False), hide_progress
371
 
372
 
373
  # ==========================================
 
401
 
402
  @keyframes gradient-shift { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
403
 
404
+ #subtitle { text-align: center !important; margin-bottom: 1.5rem; }
405
  #subtitle p { margin: 0 auto; color: #666; font-size: 1.1rem; font-weight: 500; }
406
  .dark #subtitle p { color: #DAB2FF; }
407
 
408
+ /* ======== CSS FOR GLOBAL PROGRESS BAR ======== */
409
+ #global-progress { margin-bottom: 20px !important; transition: opacity 0.3s ease; }
410
+ .progress-container {
411
+ width: 100%; background-color: rgba(243, 232, 255, 0.8);
412
+ border: 1px solid #C084FC; border-radius: 16px; overflow: hidden;
413
+ position: relative; height: 38px; display: flex; align-items: center; justify-content: center;
414
+ box-shadow: 0 4px 15px rgba(168, 85, 247, 0.15);
415
+ }
416
+ .progress-bar {
417
+ height: 100%; width: 40%;
418
+ background: linear-gradient(90deg, transparent, rgba(168, 85, 247, 0.6), rgba(192, 132, 252, 0.8), rgba(168, 85, 247, 0.6), transparent);
419
+ position: absolute; left: -40%; top: 0;
420
+ animation: loading-slide 1.5s infinite linear;
421
+ }
422
+ @keyframes loading-slide { 0% { left: -40%; } 100% { left: 100%; } }
423
+ .progress-text { position: relative; z-index: 1; color: #6B21A8; font-weight: 600; font-size: 15px; letter-spacing: 0.5px; }
424
+ .dark .progress-container { background-color: rgba(30, 30, 30, 0.9); border-color: rgba(168, 85, 247, 0.4); }
425
+ .dark .progress-text { color: #DAB2FF; }
426
+
427
  .gradio-group {
428
  background: rgba(255, 255, 255, 0.9) !important;
429
  border: 2px solid #E9D5FF !important;
 
498
  margin-right: auto !important;
499
  margin-top: 10px !important;
500
  margin-bottom: 10px !important;
501
+ display: block !important;
502
  transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.3s ease !important;
503
  box-shadow: 0 4px 15px rgba(126, 34, 206, 0.3) !important;
504
  cursor: pointer !important;
 
574
  gr.Markdown("# **PaperX Platform**", elem_id="main-title")
575
  gr.Markdown("One-click parsing of academic PDFs, DAG structuring, and multi-modal asset generation.", elem_id="subtitle")
576
 
577
+ # 🟢 新增的全局加载动画条,默认隐藏
578
+ global_progress = gr.HTML(
579
+ '<div class="progress-container"><div class="progress-bar"></div><div class="progress-text">⏳ 加载中... (Task in progress, please wait)</div></div>',
580
+ visible=False,
581
+ elem_id="global-progress"
582
+ )
583
+
584
  with gr.Row():
585
  # ================= LEFT COLUMN: SETTINGS & ACTIONS =================
586
  with gr.Column(scale=1):
 
657
  # ================= LOGIC BINDINGS =================
658
 
659
  # [步骤 1] 配置 API
 
660
  key_btn.click(
661
  fn=save_api_settings,
662
  inputs=[key_input, api_base_url_input],
 
664
  )
665
 
666
  # [步骤 2.1] 上传 PDF
 
667
  pdf_input.upload(fn=save_pdf, inputs=pdf_input, outputs=[parse_status, debug_view, pdf_ready_state])
668
 
669
  # [步骤 2.2] 清除 PDF
 
670
  pdf_input.clear(
671
  fn=clear_pdf,
672
  outputs=[parse_status, debug_view, pdf_ready_state, gen_ppt_btn, gen_poster_btn, gen_pr_btn, gen_all_btn]
 
679
  api_saved_state.change(fn=check_parse_btn_ready, inputs=[api_saved_state, pdf_ready_state], outputs=parse_btn)
680
  pdf_ready_state.change(fn=check_parse_btn_ready, inputs=[api_saved_state, pdf_ready_state], outputs=parse_btn)
681
 
682
+ # [步骤 2.3] 执行解析,绑定 8 个 outputs (新增控制 global_progress)
 
683
  parse_btn.click(
684
  fn=run_mineru_parsing_and_dag_gen,
685
+ outputs=[parse_status, debug_view, cmd_logs, gen_ppt_btn, gen_poster_btn, gen_pr_btn, gen_all_btn, global_progress]
686
  )
687
 
688
  # [步骤 3] 资产生成
 
691
  def trigger_gen_pr(): yield from run_final_generation("pr")
692
  def trigger_gen_all(): yield from run_final_generation("all")
693
 
694
+ # [步骤 3 绑定] 绑定 5 个 outputs (新增控制 global_progress)
695
+ gen_ppt_btn.click(fn=trigger_gen_ppt, outputs=[gen_status, debug_view, cmd_logs, download_file, global_progress])
696
+ gen_poster_btn.click(fn=trigger_gen_poster, outputs=[gen_status, debug_view, cmd_logs, download_file, global_progress])
697
+ gen_pr_btn.click(fn=trigger_gen_pr, outputs=[gen_status, debug_view, cmd_logs, download_file, global_progress])
698
+ gen_all_btn.click(fn=trigger_gen_all, outputs=[gen_status, debug_view, cmd_logs, download_file, global_progress])
699
 
700
  refresh_btn.click(fn=get_debug_info, outputs=debug_view)
701
 
702
  if __name__ == "__main__":
703
+ demo.launch()