akhaliq HF Staff commited on
Commit
418eb81
Β·
1 Parent(s): 85de881

add import github and HF model support

Browse files
Files changed (1) hide show
  1. app.py +321 -42
app.py CHANGED
@@ -3437,6 +3437,270 @@ def load_project_from_url(url: str) -> Tuple[str, str]:
3437
 
3438
  return f"βœ… Successfully imported project from {username}/{project_name}", code_content
3439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3440
  # Gradio Theme Configurations with proper theme objects
3441
  def get_saved_theme():
3442
  """Get the saved theme preference from file"""
@@ -3736,18 +4000,16 @@ with gr.Blocks(
3736
  apply_theme_btn = gr.Button("Apply Theme", variant="primary", size="sm")
3737
  theme_status = gr.Markdown("")
3738
 
3739
- # Add Load Project section
3740
- gr.Markdown("πŸ“₯ Load Existing Project")
3741
  load_project_url = gr.Textbox(
3742
- label="Hugging Face Space URL",
3743
- placeholder="https://huggingface.co/spaces/username/project",
3744
  lines=1
3745
  )
3746
  load_project_btn = gr.Button("Import Project", variant="secondary", size="sm")
3747
  load_project_status = gr.Markdown(visible=False)
3748
 
3749
- gr.Markdown("---")
3750
-
3751
  input = gr.Textbox(
3752
  label="What would you like to build?",
3753
  placeholder="Describe your application...",
@@ -3901,6 +4163,7 @@ with gr.Blocks(
3901
  )
3902
  with gr.Tab("Preview"):
3903
  sandbox = gr.HTML(label="Live preview")
 
3904
  # History tab hidden per user request
3905
  # with gr.Tab("History"):
3906
  # history_output = gr.Chatbot(show_label=False, height=400, type="messages")
@@ -3908,58 +4171,74 @@ with gr.Blocks(
3908
  # Keep history_output as hidden component to maintain functionality
3909
  history_output = gr.Chatbot(show_label=False, height=400, type="messages", visible=False)
3910
 
3911
- # Load project function
3912
- def handle_load_project(url):
3913
  if not url.strip():
3914
- return gr.update(value="Please enter a URL.", visible=True)
3915
-
3916
- status, code = load_project_from_url(url)
3917
-
3918
- if code:
3919
  # Extract space info for deployment
3920
  is_valid, username, project_name = check_hf_space_url(url)
3921
  space_info = f"{username}/{project_name}" if is_valid else ""
3922
-
3923
- # Success - update the code output and show success message
3924
- # Also update history to include the loaded project
3925
- loaded_history = [[f"Loaded project from {url}", code]]
3926
- # Determine preview based on content (HTML or Streamlit)
3927
- if code and (code.strip().startswith('<!DOCTYPE html>') or code.strip().startswith('<html')):
3928
- preview_html = send_to_sandbox(code)
3929
- code_lang = "html"
3930
- elif is_streamlit_code(code):
3931
- preview_html = send_streamlit_to_stlite(code)
3932
- code_lang = "python"
3933
- elif is_gradio_code(code):
3934
- preview_html = send_gradio_to_lite(code)
3935
- code_lang = "python"
3936
- else:
3937
- preview_html = "<div style='padding:1em;color:#888;text-align:center;'>Preview not available for this file type.</div>"
3938
- code_lang = "html"
3939
-
3940
  return [
3941
  gr.update(value=status, visible=True),
3942
  gr.update(value=code, language=code_lang),
3943
- gr.update(value=preview_html),
3944
  gr.update(value=""),
3945
  loaded_history,
3946
  history_to_chatbot_messages(loaded_history),
3947
- gr.update(value=space_info, visible=True), # Update space name with loaded project
3948
- gr.update(value="Update Existing Space", visible=True) # Change button text
3949
  ]
3950
  else:
3951
- # Error - just show error message
 
 
 
 
 
 
 
 
3952
  return [
3953
  gr.update(value=status, visible=True),
3954
- gr.update(),
3955
- gr.update(),
3956
- gr.update(),
3957
- [],
3958
- [],
3959
  gr.update(value="", visible=False),
3960
  gr.update(value="πŸš€ Deploy App", visible=False)
3961
  ]
3962
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3963
  # Event handlers
3964
  def update_code_language(language):
3965
  return gr.update(language=get_gradio_language(language))
@@ -4035,9 +4314,9 @@ with gr.Blocks(
4035
  # No imported project found, return no changes
4036
  return [gr.update(), gr.update()]
4037
 
4038
- # Load project button event
4039
  load_project_btn.click(
4040
- handle_load_project,
4041
  inputs=[load_project_url],
4042
  outputs=[load_project_status, code_output, sandbox, load_project_url, history, history_output, space_name_input, deploy_btn]
4043
  )
 
3437
 
3438
  return f"βœ… Successfully imported project from {username}/{project_name}", code_content
3439
 
3440
+ # -------- Repo/Model Import (GitHub & Hugging Face model) --------
3441
+ def _parse_repo_or_model_url(url: str) -> Tuple[str, Optional[dict]]:
3442
+ """Parse a URL and detect if it's a GitHub repo, HF Space, or HF Model.
3443
+
3444
+ Returns a tuple of (kind, meta) where kind in {"github", "hf_space", "hf_model", "unknown"}
3445
+ Meta contains parsed identifiers.
3446
+ """
3447
+ try:
3448
+ parsed = urlparse(url.strip())
3449
+ netloc = (parsed.netloc or "").lower()
3450
+ path = (parsed.path or "").strip("/")
3451
+ # Hugging Face spaces
3452
+ if ("huggingface.co" in netloc or netloc.endswith("hf.co")) and path.startswith("spaces/"):
3453
+ parts = path.split("/")
3454
+ if len(parts) >= 3:
3455
+ return "hf_space", {"username": parts[1], "project": parts[2]}
3456
+ # Hugging Face model repo (default)
3457
+ if ("huggingface.co" in netloc or netloc.endswith("hf.co")) and not path.startswith(("spaces/", "datasets/", "organizations/")):
3458
+ parts = path.split("/")
3459
+ if len(parts) >= 2:
3460
+ repo_id = f"{parts[0]}/{parts[1]}"
3461
+ return "hf_model", {"repo_id": repo_id}
3462
+ # GitHub repo
3463
+ if "github.com" in netloc:
3464
+ parts = path.split("/")
3465
+ if len(parts) >= 2:
3466
+ return "github", {"owner": parts[0], "repo": parts[1]}
3467
+ except Exception:
3468
+ pass
3469
+ return "unknown", None
3470
+
3471
+ def _fetch_hf_model_readme(repo_id: str) -> Optional[str]:
3472
+ """Fetch README.md (model card) for a Hugging Face model repo."""
3473
+ try:
3474
+ api = HfApi()
3475
+ # Try direct README.md first
3476
+ try:
3477
+ local_path = api.hf_hub_download(repo_id=repo_id, filename="README.md", repo_type="model")
3478
+ with open(local_path, "r", encoding="utf-8") as f:
3479
+ return f.read()
3480
+ except Exception:
3481
+ # Some repos use README at root without explicit type
3482
+ local_path = api.hf_hub_download(repo_id=repo_id, filename="README.md")
3483
+ with open(local_path, "r", encoding="utf-8") as f:
3484
+ return f.read()
3485
+ except Exception:
3486
+ return None
3487
+
3488
+ def _fetch_github_readme(owner: str, repo: str) -> Optional[str]:
3489
+ """Fetch README.md from a GitHub repo via raw URLs, trying HEAD/main/master."""
3490
+ bases = [
3491
+ f"https://raw.githubusercontent.com/{owner}/{repo}/HEAD/README.md",
3492
+ f"https://raw.githubusercontent.com/{owner}/{repo}/main/README.md",
3493
+ f"https://raw.githubusercontent.com/{owner}/{repo}/master/README.md",
3494
+ ]
3495
+ for url in bases:
3496
+ try:
3497
+ resp = requests.get(url, timeout=10)
3498
+ if resp.status_code == 200 and resp.text:
3499
+ return resp.text
3500
+ except Exception:
3501
+ continue
3502
+ return None
3503
+
3504
+ def _extract_transformers_or_diffusers_snippet(markdown_text: str) -> Tuple[Optional[str], Optional[str]]:
3505
+ """Extract the most relevant Python code block referencing transformers/diffusers from markdown.
3506
+
3507
+ Returns (language, code). If not found, returns (None, None).
3508
+ """
3509
+ if not markdown_text:
3510
+ return None, None
3511
+ # Find fenced code blocks
3512
+ code_blocks = []
3513
+ import re as _re
3514
+ for match in _re.finditer(r"```([\w+-]+)?\s*\n([\s\S]*?)```", markdown_text, _re.IGNORECASE):
3515
+ lang = (match.group(1) or "").lower()
3516
+ code = match.group(2) or ""
3517
+ code_blocks.append((lang, code.strip()))
3518
+ # Filter for transformers/diffusers relevance
3519
+ def score_block(code: str) -> int:
3520
+ score = 0
3521
+ kws = [
3522
+ "from transformers", "import transformers", "pipeline(",
3523
+ "AutoModel", "AutoTokenizer", "text-generation",
3524
+ "from diffusers", "import diffusers", "DiffusionPipeline",
3525
+ "StableDiffusion", "UNet", "EulerDiscreteScheduler"
3526
+ ]
3527
+ for kw in kws:
3528
+ if kw in code:
3529
+ score += 1
3530
+ # Prefer longer, self-contained snippets
3531
+ score += min(len(code) // 200, 5)
3532
+ return score
3533
+ scored = sorted(
3534
+ [cb for cb in code_blocks if any(kw in cb[1] for kw in ["transformers", "diffusers", "pipeline(", "StableDiffusion"])],
3535
+ key=lambda x: score_block(x[1]),
3536
+ reverse=True,
3537
+ )
3538
+ if scored:
3539
+ return scored[0][0] or None, scored[0][1]
3540
+ return None, None
3541
+
3542
+ def _infer_task_from_context(snippet: Optional[str], pipeline_tag: Optional[str]) -> str:
3543
+ """Infer a task string for transformers pipeline; fall back to provided pipeline_tag or 'text-generation'."""
3544
+ if pipeline_tag:
3545
+ return pipeline_tag
3546
+ if not snippet:
3547
+ return "text-generation"
3548
+ lowered = snippet.lower()
3549
+ task_hints = {
3550
+ "text-generation": ["text-generation", "automodelforcausallm"],
3551
+ "text2text-generation": ["text2text-generation", "t5forconditionalgeneration"],
3552
+ "fill-mask": ["fill-mask", "automodelformaskedlm"],
3553
+ "summarization": ["summarization"],
3554
+ "translation": ["translation"],
3555
+ "text-classification": ["text-classification", "sequenceclassification"],
3556
+ "automatic-speech-recognition": ["speechrecognition", "automatic-speech-recognition", "asr"],
3557
+ "image-classification": ["image-classification"],
3558
+ "zero-shot-image-classification": ["zero-shot-image-classification"],
3559
+ }
3560
+ for task, hints in task_hints.items():
3561
+ if any(h in lowered for h in hints):
3562
+ return task
3563
+ # Inspect explicit pipeline("task")
3564
+ import re as _re
3565
+ m = _re.search(r"pipeline\(\s*['\"]([\w\-]+)['\"]", snippet)
3566
+ if m:
3567
+ return m.group(1)
3568
+ return "text-generation"
3569
+
3570
+ def _generate_gradio_app_from_transformers(repo_id: str, task: str) -> str:
3571
+ """Build a minimal Gradio app using transformers.pipeline for a given model and task."""
3572
+ # Map simple UI per task; default to text in/out
3573
+ if task in {"text-generation", "text2text-generation", "summarization", "translation", "fill-mask"}:
3574
+ return (
3575
+ "import gradio as gr\n"
3576
+ "from transformers import pipeline\n\n"
3577
+ f"pipe = pipeline(task='{task}', model='{repo_id}')\n\n"
3578
+ "def infer(prompt, max_new_tokens=256, temperature=0.7, top_p=0.95):\n"
3579
+ " if '\u2047' in prompt:\n"
3580
+ " # Fill-mask often uses [MASK]; keep generic handling\n"
3581
+ " pass\n"
3582
+ " out = pipe(prompt, max_new_tokens=max_new_tokens, do_sample=True, temperature=temperature, top_p=top_p)\n"
3583
+ " if isinstance(out, list):\n"
3584
+ " if isinstance(out[0], dict):\n"
3585
+ " return next(iter(out[0].values())) if out[0] else str(out)\n"
3586
+ " return str(out[0])\n"
3587
+ " return str(out)\n\n"
3588
+ "demo = gr.Interface(\n"
3589
+ " fn=infer,\n"
3590
+ " inputs=[gr.Textbox(label='Input', lines=8), gr.Slider(1, 2048, value=256, label='max_new_tokens'), gr.Slider(0.0, 1.5, value=0.7, step=0.01, label='temperature'), gr.Slider(0.0, 1.0, value=0.95, step=0.01, label='top_p')],\n"
3591
+ " outputs=gr.Textbox(label='Output', lines=8),\n"
3592
+ " title='Transformers Demo'\n"
3593
+ ")\n\n"
3594
+ "if __name__ == '__main__':\n"
3595
+ " demo.launch()\n"
3596
+ )
3597
+ elif task in {"text-classification"}:
3598
+ return (
3599
+ "import gradio as gr\n"
3600
+ "from transformers import pipeline\n\n"
3601
+ f"pipe = pipeline(task='{task}', model='{repo_id}')\n\n"
3602
+ "def infer(text):\n"
3603
+ " out = pipe(text)\n"
3604
+ " # Expect list of dicts with label/score\n"
3605
+ " return {o['label']: float(o['score']) for o in out}\n\n"
3606
+ "demo = gr.Interface(fn=infer, inputs=gr.Textbox(lines=6), outputs=gr.Label(), title='Text Classification')\n\n"
3607
+ "if __name__ == '__main__':\n"
3608
+ " demo.launch()\n"
3609
+ )
3610
+ else:
3611
+ # Fallback generic text pipeline (pipeline infers task from model config)
3612
+ return (
3613
+ "import gradio as gr\n"
3614
+ "from transformers import pipeline\n\n"
3615
+ f"pipe = pipeline(model='{repo_id}')\n\n"
3616
+ "def infer(prompt):\n"
3617
+ " out = pipe(prompt)\n"
3618
+ " if isinstance(out, list):\n"
3619
+ " if isinstance(out[0], dict):\n"
3620
+ " return next(iter(out[0].values())) if out[0] else str(out)\n"
3621
+ " return str(out[0])\n"
3622
+ " return str(out)\n\n"
3623
+ "demo = gr.Interface(fn=infer, inputs=gr.Textbox(lines=8), outputs=gr.Textbox(lines=8), title='Transformers Demo')\n\n"
3624
+ "if __name__ == '__main__':\n"
3625
+ " demo.launch()\n"
3626
+ )
3627
+
3628
+ def _generate_gradio_app_from_diffusers(repo_id: str) -> str:
3629
+ """Build a minimal Gradio app for text-to-image using diffusers."""
3630
+ return (
3631
+ "import gradio as gr\n"
3632
+ "import torch\n"
3633
+ "from diffusers import DiffusionPipeline\n\n"
3634
+ f"pipe = DiffusionPipeline.from_pretrained('{repo_id}')\n"
3635
+ "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n"
3636
+ "pipe = pipe.to(device)\n\n"
3637
+ "def infer(prompt, guidance_scale=7.0, num_inference_steps=30, seed=0):\n"
3638
+ " generator = None if seed == 0 else torch.Generator(device=device).manual_seed(int(seed))\n"
3639
+ " image = pipe(prompt, guidance_scale=float(guidance_scale), num_inference_steps=int(num_inference_steps), generator=generator).images[0]\n"
3640
+ " return image\n\n"
3641
+ "demo = gr.Interface(\n"
3642
+ " fn=infer,\n"
3643
+ " inputs=[gr.Textbox(label='Prompt'), gr.Slider(0.0, 15.0, value=7.0, step=0.1, label='guidance_scale'), gr.Slider(1, 100, value=30, step=1, label='num_inference_steps'), gr.Slider(0, 2**32-1, value=0, step=1, label='seed')],\n"
3644
+ " outputs=gr.Image(type='pil'),\n"
3645
+ " title='Diffusers Text-to-Image'\n"
3646
+ ")\n\n"
3647
+ "if __name__ == '__main__':\n"
3648
+ " demo.launch()\n"
3649
+ )
3650
+
3651
+ def _generate_streamlit_wrapper(gradio_code: str) -> str:
3652
+ """Convert a simple Gradio app into a Streamlit wrapper by embedding via components if needed.
3653
+ If code is already Streamlit, return as is. Otherwise, provide a basic Streamlit UI calling the same pipeline.
3654
+ """
3655
+ # For now, simply return a minimal placeholder to keep scope tight; prefer Gradio by default.
3656
+ return (
3657
+ "import streamlit as st\n"
3658
+ "st.markdown('This model is best used with a Gradio app in this tool. Switch framework to Gradio for a runnable demo.')\n"
3659
+ )
3660
+
3661
+ def import_repo_to_app(url: str, framework: str = "Gradio") -> Tuple[str, str, str]:
3662
+ """Import a GitHub or HF model repo and return the raw code snippet from README/model card.
3663
+
3664
+ Returns (status_markdown, code_snippet, preview_html). Preview left empty; UI will decide.
3665
+ """
3666
+ if not url or not url.strip():
3667
+ return "Please enter a repository URL.", "", ""
3668
+ kind, meta = _parse_repo_or_model_url(url)
3669
+ if kind == "hf_space" and meta:
3670
+ # Spaces already contain runnable apps; keep existing behavior to fetch main file raw
3671
+ status, code = load_project_from_url(url)
3672
+ return status, code, ""
3673
+ # Fetch markdown
3674
+ markdown = None
3675
+ repo_id = None
3676
+ pipeline_tag = None
3677
+ library_name = None
3678
+ if kind == "hf_model" and meta:
3679
+ repo_id = meta.get("repo_id")
3680
+ # Try model info to get pipeline tag/library
3681
+ try:
3682
+ api = HfApi()
3683
+ info = api.model_info(repo_id)
3684
+ pipeline_tag = getattr(info, "pipeline_tag", None)
3685
+ library_name = getattr(info, "library_name", None)
3686
+ except Exception:
3687
+ pass
3688
+ markdown = _fetch_hf_model_readme(repo_id)
3689
+ elif kind == "github" and meta:
3690
+ markdown = _fetch_github_readme(meta.get("owner"), meta.get("repo"))
3691
+ else:
3692
+ return "Error: Unsupported or invalid URL. Provide a GitHub repo or Hugging Face model URL.", "", ""
3693
+
3694
+ if not markdown:
3695
+ return "Error: Could not fetch README/model card.", "", ""
3696
+
3697
+ lang, snippet = _extract_transformers_or_diffusers_snippet(markdown)
3698
+ if not snippet:
3699
+ return "Error: No relevant transformers/diffusers code block found in README/model card.", "", ""
3700
+
3701
+ status = "βœ… Imported code snippet from README/model card. Use it as a starting point."
3702
+ return status, snippet, ""
3703
+
3704
  # Gradio Theme Configurations with proper theme objects
3705
  def get_saved_theme():
3706
  """Get the saved theme preference from file"""
 
4000
  apply_theme_btn = gr.Button("Apply Theme", variant="primary", size="sm")
4001
  theme_status = gr.Markdown("")
4002
 
4003
+ # Unified Import section
4004
+ gr.Markdown("πŸ“₯ Import Project (Space, GitHub, or Model)")
4005
  load_project_url = gr.Textbox(
4006
+ label="Project URL",
4007
+ placeholder="https://huggingface.co/spaces/user/space OR https://huggingface.co/user/model OR https://github.com/owner/repo",
4008
  lines=1
4009
  )
4010
  load_project_btn = gr.Button("Import Project", variant="secondary", size="sm")
4011
  load_project_status = gr.Markdown(visible=False)
4012
 
 
 
4013
  input = gr.Textbox(
4014
  label="What would you like to build?",
4015
  placeholder="Describe your application...",
 
4163
  )
4164
  with gr.Tab("Preview"):
4165
  sandbox = gr.HTML(label="Live preview")
4166
+ # Removed Import Logs tab for cleaner UI
4167
  # History tab hidden per user request
4168
  # with gr.Tab("History"):
4169
  # history_output = gr.Chatbot(show_label=False, height=400, type="messages")
 
4171
  # Keep history_output as hidden component to maintain functionality
4172
  history_output = gr.Chatbot(show_label=False, height=400, type="messages", visible=False)
4173
 
4174
+ # Unified import handler
4175
+ def handle_import_project(url):
4176
  if not url.strip():
4177
+ return [gr.update(value="Please enter a URL.", visible=True), gr.update(), gr.update(), gr.update(), [], [], gr.update(value="", visible=False), gr.update(value="πŸš€ Deploy App", visible=False)]
4178
+
4179
+ kind, meta = _parse_repo_or_model_url(url)
4180
+ if kind == "hf_space":
4181
+ status, code = load_project_from_url(url)
4182
  # Extract space info for deployment
4183
  is_valid, username, project_name = check_hf_space_url(url)
4184
  space_info = f"{username}/{project_name}" if is_valid else ""
4185
+ loaded_history = [[f"Imported Space from {url}", code]]
4186
+ # Preview not auto-rendered for imported content
4187
+ code_lang = "python" if (is_streamlit_code(code) or is_gradio_code(code)) else "html"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4188
  return [
4189
  gr.update(value=status, visible=True),
4190
  gr.update(value=code, language=code_lang),
4191
+ gr.update(value=""),
4192
  gr.update(value=""),
4193
  loaded_history,
4194
  history_to_chatbot_messages(loaded_history),
4195
+ gr.update(value=space_info, visible=True),
4196
+ gr.update(value="Update Existing Space", visible=True)
4197
  ]
4198
  else:
4199
+ # GitHub or HF model β†’ return raw snippet for LLM starting point
4200
+ status, code, _ = import_repo_to_app(url)
4201
+ loaded_history = [[f"Imported Repo/Model from {url}", code]]
4202
+ code_lang = "python"
4203
+ lower = (code or "").lower()
4204
+ if code.strip().startswith("<!doctype html>") or code.strip().startswith("<html"):
4205
+ code_lang = "html"
4206
+ elif "```json" in lower:
4207
+ code_lang = "json"
4208
  return [
4209
  gr.update(value=status, visible=True),
4210
+ gr.update(value=code, language=code_lang),
4211
+ gr.update(value=""),
4212
+ gr.update(value=""),
4213
+ loaded_history,
4214
+ history_to_chatbot_messages(loaded_history),
4215
  gr.update(value="", visible=False),
4216
  gr.update(value="πŸš€ Deploy App", visible=False)
4217
  ]
4218
 
4219
+ # Import repo/model handler
4220
+ def handle_import_repo(url, framework):
4221
+ status, code, preview = import_repo_to_app(url, framework)
4222
+ # Heuristically set editor language based on snippet fencing or content
4223
+ code_lang = "python"
4224
+ lowered = (code or "").lower()
4225
+ if code.strip().startswith("<!doctype html>") or code.strip().startswith("<html"):
4226
+ code_lang = "html"
4227
+ elif "import gradio" in lowered or "from gradio" in lowered:
4228
+ code_lang = "python"
4229
+ elif "streamlit as st" in lowered or "import streamlit" in lowered:
4230
+ code_lang = "python"
4231
+ elif "from transformers" in lowered or "import transformers" in lowered:
4232
+ code_lang = "python"
4233
+ elif "from diffusers" in lowered or "import diffusers" in lowered:
4234
+ code_lang = "python"
4235
+ return [
4236
+ gr.update(value=status, visible=True),
4237
+ gr.update(value=code, language=code_lang),
4238
+ gr.update(value=""),
4239
+ gr.update(value=f"URL: {url}\n\n{status}"),
4240
+ ]
4241
+
4242
  # Event handlers
4243
  def update_code_language(language):
4244
  return gr.update(language=get_gradio_language(language))
 
4314
  # No imported project found, return no changes
4315
  return [gr.update(), gr.update()]
4316
 
4317
+ # Unified import event
4318
  load_project_btn.click(
4319
+ handle_import_project,
4320
  inputs=[load_project_url],
4321
  outputs=[load_project_status, code_output, sandbox, load_project_url, history, history_output, space_name_input, deploy_btn]
4322
  )