akhaliq HF Staff commited on
Commit
5d2d97e
·
1 Parent(s): f8f29e0

add streamit and dropdown and preview support

Browse files
Files changed (1) hide show
  1. app.py +105 -19
app.py CHANGED
@@ -35,6 +35,9 @@ GRADIO_SUPPORTED_LANGUAGES = [
35
  ]
36
 
37
  def get_gradio_language(language):
 
 
 
38
  return language if language in GRADIO_SUPPORTED_LANGUAGES else None
39
 
40
  # Search/Replace Constants
@@ -1563,6 +1566,43 @@ def send_to_sandbox(code):
1563
  iframe = f'<iframe src="{data_uri}" width="100%" height="920px" sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-presentation" allow="display-capture"></iframe>'
1564
  return iframe
1565
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1566
  def demo_card_click(e: gr.EventData):
1567
  try:
1568
  # Get the index from the event data
@@ -2091,10 +2131,16 @@ This will help me create a better design for you."""
2091
  if chunk.choices[0].delta.content:
2092
  content += chunk.choices[0].delta.content
2093
  clean_code = remove_code_block(content)
 
 
 
 
 
 
2094
  yield {
2095
  code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
2096
  history_output: history_to_chatbot_messages(_history),
2097
- sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
2098
  }
2099
 
2100
  except Exception as e:
@@ -2291,10 +2337,15 @@ This will help me create a better design for you."""
2291
  text_to_image_prompt=text_to_image_prompt,
2292
  )
2293
 
 
 
 
 
 
2294
  yield {
2295
  code_output: final_content,
2296
  history: _history,
2297
- sandbox: send_to_sandbox(final_content) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
2298
  history_output: history_to_chatbot_messages(_history),
2299
  }
2300
  return
@@ -2400,26 +2451,41 @@ This will help me create a better design for you."""
2400
  # Handle modification of existing content
2401
  if clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html"):
2402
  # Model returned a complete HTML file
 
 
 
 
 
2403
  yield {
2404
  code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
2405
  history_output: history_to_chatbot_messages(_history),
2406
- sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
2407
  }
2408
  else:
2409
  # Model returned search/replace changes - apply them
2410
  last_content = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
2411
  modified_content = apply_search_replace_changes(last_content, clean_code)
2412
  clean_content = remove_code_block(modified_content)
 
 
 
 
 
2413
  yield {
2414
  code_output: gr.update(value=clean_content, language=get_gradio_language(language)),
2415
  history_output: history_to_chatbot_messages(_history),
2416
- sandbox: send_to_sandbox(clean_content) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
2417
  }
2418
  else:
 
 
 
 
 
2419
  yield {
2420
  code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
2421
  history_output: history_to_chatbot_messages(_history),
2422
- sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
2423
  }
2424
  # Skip chunks with empty choices (end of stream)
2425
  # Do not treat as error
@@ -2518,7 +2584,7 @@ This will help me create a better design for you."""
2518
  yield {
2519
  code_output: clean_content,
2520
  history: _history,
2521
- sandbox: send_to_sandbox(clean_content) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
2522
  history_output: history_to_chatbot_messages(_history),
2523
  }
2524
  else:
@@ -2537,10 +2603,15 @@ This will help me create a better design for you."""
2537
  )
2538
 
2539
  _history.append([query, final_content])
 
 
 
 
 
2540
  yield {
2541
  code_output: final_content,
2542
  history: _history,
2543
- sandbox: send_to_sandbox(final_content),
2544
  history_output: history_to_chatbot_messages(_history),
2545
  }
2546
  except Exception as e:
@@ -3287,9 +3358,9 @@ with gr.Blocks(
3287
  lines=3,
3288
  visible=True
3289
  )
3290
- # Language dropdown for code generation
3291
  language_choices = [
3292
- "html", "python", "transformers.js", "svelte", "c", "cpp", "markdown", "latex", "json", "css", "javascript", "jinja2", "typescript", "yaml", "dockerfile", "shell", "r", "sql", "sql-msSQL", "sql-mySQL", "sql-mariaDB", "sql-sqlite", "sql-cassandra", "sql-plSQL", "sql-hive", "sql-pgSQL", "sql-gql", "sql-gpSQL", "sql-sparkSQL", "sql-esper"
3293
  ]
3294
  language_dropdown = gr.Dropdown(
3295
  choices=language_choices,
@@ -3456,10 +3527,21 @@ with gr.Blocks(
3456
  # Success - update the code output and show success message
3457
  # Also update history to include the loaded project
3458
  loaded_history = [[f"Loaded project from {url}", code]]
 
 
 
 
 
 
 
 
 
 
 
3459
  return [
3460
  gr.update(value=status, visible=True),
3461
- gr.update(value=code, language="html"),
3462
- gr.update(value=send_to_sandbox(code) if code.strip().startswith('<!DOCTYPE html>') or code.strip().startswith('<html') else "<div style='padding:1em;color:#888;text-align:center;'>Preview not available for this file type.</div>"),
3463
  gr.update(value=""),
3464
  loaded_history,
3465
  history_to_chatbot_messages(loaded_history),
@@ -3490,6 +3572,8 @@ with gr.Blocks(
3490
  return gr.update(value="Svelte")
3491
  elif language == "html":
3492
  return gr.update(value="Static (HTML)")
 
 
3493
  else:
3494
  return gr.update(value="Gradio (Python)")
3495
 
@@ -3499,18 +3583,20 @@ with gr.Blocks(
3499
  def preview_logic(code, language):
3500
  if language == "html":
3501
  return send_to_sandbox(code)
3502
- elif language == "transformers.js":
3503
- # For transformers.js, extract the HTML part for preview
 
 
 
 
 
3504
  files = parse_transformers_js_output(code)
3505
  if files['index.html']:
3506
  return send_to_sandbox(files['index.html'])
3507
- else:
3508
- return "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>"
3509
- elif language == "svelte":
3510
- # For Svelte, we can't preview the compiled app, so show a message
3511
- return "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your Svelte code and deploy it to see the result.</div>"
3512
- else:
3513
  return "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>"
 
 
 
3514
 
3515
  def show_deploy_components(*args):
3516
  return [gr.Textbox(visible=True), gr.Dropdown(visible=True), gr.Button(visible=True)]
 
35
  ]
36
 
37
  def get_gradio_language(language):
38
+ # Map composite options to a supported syntax highlighting
39
+ if language == "streamlit":
40
+ return "python"
41
  return language if language in GRADIO_SUPPORTED_LANGUAGES else None
42
 
43
  # Search/Replace Constants
 
1566
  iframe = f'<iframe src="{data_uri}" width="100%" height="920px" sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-presentation" allow="display-capture"></iframe>'
1567
  return iframe
1568
 
1569
+ def is_streamlit_code(code: str) -> bool:
1570
+ """Heuristic check to determine if Python code is a Streamlit app."""
1571
+ if not code:
1572
+ return False
1573
+ lowered = code.lower()
1574
+ return ("import streamlit" in lowered) or ("from streamlit" in lowered) or ("st." in code and "streamlit" in lowered)
1575
+
1576
+ def send_streamlit_to_stlite(code: str) -> str:
1577
+ """Render Streamlit code using stlite inside a sandboxed iframe for preview."""
1578
+ # Build an HTML document that loads stlite and mounts the Streamlit app defined inline
1579
+ html_doc = (
1580
+ """<!doctype html>
1581
+ <html>
1582
+ <head>
1583
+ <meta charset=\"UTF-8\" />
1584
+ <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />
1585
+ <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\" />
1586
+ <title>Streamlit Preview</title>
1587
+ <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/@stlite/browser@0.86.0/build/stlite.css\" />
1588
+ <style>html,body{margin:0;padding:0;height:100%;} streamlit-app{display:block;height:100%;}</style>
1589
+ <script type=\"module\" src=\"https://cdn.jsdelivr.net/npm/@stlite/browser@0.86.0/build/stlite.js\"></script>
1590
+ </head>
1591
+ <body>
1592
+ <streamlit-app>
1593
+ """
1594
+ + (code or "")
1595
+ + """
1596
+ </streamlit-app>
1597
+ </body>
1598
+ </html>
1599
+ """
1600
+ )
1601
+ encoded_html = base64.b64encode(html_doc.encode('utf-8')).decode('utf-8')
1602
+ data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
1603
+ iframe = f'<iframe src="{data_uri}" width="100%" height="920px" sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-presentation" allow="display-capture"></iframe>'
1604
+ return iframe
1605
+
1606
  def demo_card_click(e: gr.EventData):
1607
  try:
1608
  # Get the index from the event data
 
2131
  if chunk.choices[0].delta.content:
2132
  content += chunk.choices[0].delta.content
2133
  clean_code = remove_code_block(content)
2134
+ # Live streaming preview
2135
+ preview_val = None
2136
+ if language == "html":
2137
+ preview_val = send_to_sandbox(clean_code)
2138
+ elif language == "python" and is_streamlit_code(clean_code):
2139
+ preview_val = send_streamlit_to_stlite(clean_code)
2140
  yield {
2141
  code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
2142
  history_output: history_to_chatbot_messages(_history),
2143
+ sandbox: preview_val or "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>",
2144
  }
2145
 
2146
  except Exception as e:
 
2337
  text_to_image_prompt=text_to_image_prompt,
2338
  )
2339
 
2340
+ preview_val = None
2341
+ if language == "html":
2342
+ preview_val = send_to_sandbox(final_content)
2343
+ elif language == "python" and is_streamlit_code(final_content):
2344
+ preview_val = send_streamlit_to_stlite(final_content)
2345
  yield {
2346
  code_output: final_content,
2347
  history: _history,
2348
+ sandbox: preview_val or "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>",
2349
  history_output: history_to_chatbot_messages(_history),
2350
  }
2351
  return
 
2451
  # Handle modification of existing content
2452
  if clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html"):
2453
  # Model returned a complete HTML file
2454
+ preview_val = None
2455
+ if language == "html":
2456
+ preview_val = send_to_sandbox(clean_code)
2457
+ elif language == "python" and is_streamlit_code(clean_code):
2458
+ preview_val = send_streamlit_to_stlite(clean_code)
2459
  yield {
2460
  code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
2461
  history_output: history_to_chatbot_messages(_history),
2462
+ sandbox: preview_val or "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>",
2463
  }
2464
  else:
2465
  # Model returned search/replace changes - apply them
2466
  last_content = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
2467
  modified_content = apply_search_replace_changes(last_content, clean_code)
2468
  clean_content = remove_code_block(modified_content)
2469
+ preview_val = None
2470
+ if language == "html":
2471
+ preview_val = send_to_sandbox(clean_content)
2472
+ elif language == "python" and is_streamlit_code(clean_content):
2473
+ preview_val = send_streamlit_to_stlite(clean_content)
2474
  yield {
2475
  code_output: gr.update(value=clean_content, language=get_gradio_language(language)),
2476
  history_output: history_to_chatbot_messages(_history),
2477
+ sandbox: preview_val or "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>",
2478
  }
2479
  else:
2480
+ preview_val = None
2481
+ if language == "html":
2482
+ preview_val = send_to_sandbox(clean_code)
2483
+ elif language == "python" and is_streamlit_code(clean_code):
2484
+ preview_val = send_streamlit_to_stlite(clean_code)
2485
  yield {
2486
  code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
2487
  history_output: history_to_chatbot_messages(_history),
2488
+ sandbox: preview_val or "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>",
2489
  }
2490
  # Skip chunks with empty choices (end of stream)
2491
  # Do not treat as error
 
2584
  yield {
2585
  code_output: clean_content,
2586
  history: _history,
2587
+ sandbox: (send_to_sandbox(clean_content) if language == "html" else (send_streamlit_to_stlite(clean_content) if (language == "python" and is_streamlit_code(clean_content)) else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>")),
2588
  history_output: history_to_chatbot_messages(_history),
2589
  }
2590
  else:
 
2603
  )
2604
 
2605
  _history.append([query, final_content])
2606
+ preview_val = None
2607
+ if language == "html":
2608
+ preview_val = send_to_sandbox(final_content)
2609
+ elif language == "python" and is_streamlit_code(final_content):
2610
+ preview_val = send_streamlit_to_stlite(final_content)
2611
  yield {
2612
  code_output: final_content,
2613
  history: _history,
2614
+ sandbox: preview_val or "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>",
2615
  history_output: history_to_chatbot_messages(_history),
2616
  }
2617
  except Exception as e:
 
3358
  lines=3,
3359
  visible=True
3360
  )
3361
+ # Language dropdown for code generation (add Streamlit as a first-class option)
3362
  language_choices = [
3363
+ "html", "streamlit", "python", "transformers.js", "svelte", "c", "cpp", "markdown", "latex", "json", "css", "javascript", "jinja2", "typescript", "yaml", "dockerfile", "shell", "r", "sql", "sql-msSQL", "sql-mySQL", "sql-mariaDB", "sql-sqlite", "sql-cassandra", "sql-plSQL", "sql-hive", "sql-pgSQL", "sql-gql", "sql-gpSQL", "sql-sparkSQL", "sql-esper"
3364
  ]
3365
  language_dropdown = gr.Dropdown(
3366
  choices=language_choices,
 
3527
  # Success - update the code output and show success message
3528
  # Also update history to include the loaded project
3529
  loaded_history = [[f"Loaded project from {url}", code]]
3530
+ # Determine preview based on content (HTML or Streamlit)
3531
+ if code and (code.strip().startswith('<!DOCTYPE html>') or code.strip().startswith('<html')):
3532
+ preview_html = send_to_sandbox(code)
3533
+ code_lang = "html"
3534
+ elif is_streamlit_code(code):
3535
+ preview_html = send_streamlit_to_stlite(code)
3536
+ code_lang = "python"
3537
+ else:
3538
+ preview_html = "<div style='padding:1em;color:#888;text-align:center;'>Preview not available for this file type.</div>"
3539
+ code_lang = "html"
3540
+
3541
  return [
3542
  gr.update(value=status, visible=True),
3543
+ gr.update(value=code, language=code_lang),
3544
+ gr.update(value=preview_html),
3545
  gr.update(value=""),
3546
  loaded_history,
3547
  history_to_chatbot_messages(loaded_history),
 
3572
  return gr.update(value="Svelte")
3573
  elif language == "html":
3574
  return gr.update(value="Static (HTML)")
3575
+ elif language == "streamlit":
3576
+ return gr.update(value="Streamlit (Python)")
3577
  else:
3578
  return gr.update(value="Gradio (Python)")
3579
 
 
3583
  def preview_logic(code, language):
3584
  if language == "html":
3585
  return send_to_sandbox(code)
3586
+ if language == "streamlit":
3587
+ return send_streamlit_to_stlite(code) if is_streamlit_code(code) else "<div style='padding:1em;color:#888;text-align:center;'>Add `import streamlit as st` to enable Streamlit preview.</div>"
3588
+ if language == "python" or is_streamlit_code(code):
3589
+ if is_streamlit_code(code):
3590
+ return send_streamlit_to_stlite(code)
3591
+ return "<div style='padding:1em;color:#888;text-align:center;'>Preview available only for Streamlit apps in Python. Add `import streamlit as st`.</div>"
3592
+ if language == "transformers.js":
3593
  files = parse_transformers_js_output(code)
3594
  if files['index.html']:
3595
  return send_to_sandbox(files['index.html'])
 
 
 
 
 
 
3596
  return "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>"
3597
+ if language == "svelte":
3598
+ return "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your Svelte code and deploy it to see the result.</div>"
3599
+ return "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML.</div>"
3600
 
3601
  def show_deploy_components(*args):
3602
  return [gr.Textbox(visible=True), gr.Dropdown(visible=True), gr.Button(visible=True)]