builder / app.py
mgbam's picture
Update app.py
9b8ec81 verified
raw
history blame
6.9 kB
# /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, MULTIMODAL_MODELS
from core import generate_code
from deployment import deploy_to_hf_space
from utils import get_gradio_language, history_to_chatbot_messages # <--- FIX: Import new helper
# --- 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:
safe_code = code.replace('"', '"')
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
):
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_to_chatbot_messages(history) # <--- FIX: Use new helper
}
return
model_config = next((m for m in AVAILABLE_MODELS if m['name'] == model_name), AVAILABLE_MODELS[0])
for response in generate_code(query, image, file.name if file else None, website_url, history, model_config, enable_search, language):
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"]
# <--- FIX: Use the helper function to format history for the chatbot
ui_update[history_output] = history_to_chatbot_messages(response["history"])
yield ui_update
def on_model_change(model_name: str):
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):
return gr.update(language=get_gradio_language(language))
# <--- FIX: Modified function to accept the auth token from the button
def on_deploy_click(code: str, space_name: str, sdk_name: str, auth_token: gr.OAuthToken | None):
"""Handler for the deploy button."""
hf_token = auth_token.token if auth_token else None
if not hf_token:
return gr.update(value="⚠️ Please log in with your Hugging Face account to deploy.", visible=True)
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() # <--- FIX: No longer needed
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):
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)
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)
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):
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"):
# <--- FIX: Update Chatbot component to modern standards
history_output = gr.Chatbot(
label="Conversation History",
type="messages",
height=500
)
# --- 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]
)
# <--- FIX: Update clear button to output correctly formatted empty list for chatbot
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)
# <--- FIX: REMOVED the incorrect .login() event handler
# <--- FIX: Correct way to handle deployment click
deploy_btn.click(
on_deploy_click,
inputs=[code_output, space_name_input, sdk_dropdown, login_button], # Pass the button itself as input
outputs=deploy_status
)
if __name__ == "__main__":
demo.queue().launch()