File size: 6,645 Bytes
4ad460d 0a9c605 227495f 0a9c605 227495f 4ad460d 227495f 4ad460d 227495f 4ad460d 227495f 4ad460d 227495f 4ad460d 227495f 46c562f 227495f 46c562f 227495f 46c562f 227495f 46c562f 227495f 46c562f 227495f d5ca822 4ad460d 227495f 46c562f 0a9c605 227495f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# /app.py (Corrected)
"""
Main Gradio application for AnyCoder.
This file defines the user interface, handles user interactions, and orchestrates
the calls to the backend logic in other modules.
"""
import gradio as gr
from config import AVAILABLE_MODELS, DEMO_LIST, MULTIMODAL_MODELS
from core import generate_code
from deployment import deploy_to_hf_space
from utils import get_gradio_language
# --- UI Helper Functions ---
def send_to_sandbox(code: str, language: str) -> str:
"""Generates an iframe for the preview tab, safely handling quotes."""
if language == "html" and code:
# First, replace all double quotes in the HTML code with the " entity.
# This prevents the srcdoc attribute from breaking.
safe_code = code.replace('"', '"')
# Now, inject the safe code into the iframe.
return f'<iframe srcdoc="{safe_code}" width="100%" height="920px" style="border:0;"></iframe>'
return "<div style='padding:1em;color:#888;text-align:center;'>Preview is only for HTML.</div>"
# --- Event Handlers ---
def on_generate_click(
query: str, image: gr.Image, file: gr.File, website_url: str,
history: list, model_name: str, enable_search: bool, language: str
):
"""Handler for the 'Generate' button click event."""
if not query and not image and not file and not website_url:
yield {
code_output: gr.update(value="Please provide a prompt, image, file, or URL.", language="text"),
history_output: history
}
return
model_config = next((m for m in AVAILABLE_MODELS if m['name'] == model_name), AVAILABLE_MODELS[0])
# Stream the response
for response in generate_code(query, image, file.name if file else None, website_url, history, model_config, enable_search, language):
# Determine the code to be used for the sandbox preview
preview_code = response.get("code_output", "")
ui_update = {
code_output: gr.update(value=preview_code, language=get_gradio_language(language)),
sandbox: send_to_sandbox(preview_code, language)
}
if "history" in response:
ui_update[history_state] = response["history"]
ui_update[history_output] = response["history"]
yield ui_update
def on_model_change(model_name: str):
"""Updates UI elements when the model selection changes."""
model_id = next((m['id'] for m in AVAILABLE_MODELS if m['name'] == model_name), None)
return gr.update(visible=model_id in MULTIMODAL_MODELS)
def on_language_change(language: str):
"""Updates the code output and preview when language changes."""
return gr.update(language=get_gradio_language(language))
def on_deploy_click(code: str, space_name: str, sdk_name: str, hf_token: str):
"""Handler for the deploy button."""
sdk_map = {"Static (HTML)": "static", "Gradio (Python)": "gradio"}
sdk = sdk_map.get(sdk_name, "static")
return gr.update(value=deploy_to_hf_space(code, space_name, sdk, hf_token), visible=True)
# --- Gradio UI Layout ---
with gr.Blocks(theme=gr.themes.Default(primary_hue="blue"), title="AnyCoder") as demo:
history_state = gr.State([])
hf_token_state = gr.State()
gr.Markdown("# 🤖 AnyCoder - AI Code Generator")
gr.Markdown("Describe what you want to build, upload a design, or provide a URL to redesign. The AI will generate the code for you.")
with gr.Row():
with gr.Column(scale=1):
# --- Inputs ---
input_prompt = gr.Textbox(label="Prompt", placeholder="e.g., a login form with a blue button", lines=3)
language_dropdown = gr.Dropdown(choices=["html", "python", "javascript", "css"], value="html", label="Language")
website_url_input = gr.Textbox(label="URL to Redesign", placeholder="https://example.com")
file_input = gr.File(label="Reference File (PDF, TXT, DOCX, image)")
image_input = gr.Image(label="UI Design Image", type="numpy", visible=False)
# --- Controls ---
with gr.Accordion("Settings", open=False):
model_dropdown = gr.Dropdown(choices=[m['name'] for m in AVAILABLE_MODELS], value=AVAILABLE_MODELS[0]['name'], label="Model")
search_toggle = gr.Checkbox(label="Enable Web Search", value=False)
with gr.Row():
clear_btn = gr.Button("Clear")
generate_btn = gr.Button("Generate", variant="primary", scale=2)
# --- Deployment ---
with gr.Accordion("🚀 Deploy to Hugging Face", open=False):
login_button = gr.LoginButton()
space_name_input = gr.Textbox(label="New App Name", placeholder="my-cool-app")
sdk_dropdown = gr.Dropdown(choices=["Static (HTML)", "Gradio (Python)"], value="Static (HTML)", label="App Type")
deploy_btn = gr.Button("Deploy")
deploy_status = gr.Markdown(visible=False)
with gr.Column(scale=2):
# --- Outputs ---
with gr.Tabs():
with gr.Tab("Preview"):
sandbox = gr.HTML(label="Live Preview", elem_id="sandbox-preview")
with gr.Tab("Code"):
code_output = gr.Code(label="Generated Code", language="html", interactive=True)
with gr.Tab("History"):
history_output = gr.Chatbot(label="Conversation History", bubble_full_width=False)
# --- Event Wiring ---
generate_btn.click(
fn=on_generate_click,
inputs=[input_prompt, image_input, file_input, website_url_input, history_state, model_dropdown, search_toggle, language_dropdown],
outputs=[code_output, sandbox, history_state, history_output]
)
clear_btn.click(lambda: ([], [], None, None, None, "", ""), outputs=[history_state, history_output, input_prompt, image_input, file_input, website_url_input, code_output])
model_dropdown.change(on_model_change, inputs=model_dropdown, outputs=image_input)
language_dropdown.change(on_language_change, inputs=language_dropdown, outputs=code_output)
language_dropdown.change(lambda code, lang: send_to_sandbox(code, lang), inputs=[code_output, language_dropdown], outputs=sandbox)
login_button.login(lambda token: gr.update(value=token.token if token else None), outputs=hf_token_state)
deploy_btn.click(
on_deploy_click,
inputs=[code_output, space_name_input, sdk_dropdown, hf_token_state],
outputs=deploy_status
)
if __name__ == "__main__":
demo.queue().launch() |