Spaces:
Running
Running
add streamit and dropdown and preview support
Browse files
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:
|
| 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:
|
| 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:
|
| 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:
|
| 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:
|
| 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
|
| 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:
|
| 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=
|
| 3462 |
-
gr.update(value=
|
| 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 |
-
|
| 3503 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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)]
|