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)]
|