| | """ |
| | Gradio user interface for AnyCoder. |
| | Defines the main UI layout, components, and event handlers. |
| | """ |
| | import os |
| | import gradio as gr |
| | from typing import Dict, Optional |
| | from huggingface_hub import HfApi |
| | import httpx |
| |
|
| | |
| | |
| | _original_client_init = httpx.AsyncClient.__init__ |
| |
|
| | def _patched_client_init(self, *args, **kwargs): |
| | |
| | if 'timeout' not in kwargs: |
| | kwargs['timeout'] = httpx.Timeout( |
| | connect=30.0, |
| | read=60.0, |
| | write=30.0, |
| | pool=30.0 |
| | ) |
| | return _original_client_init(self, *args, **kwargs) |
| |
|
| | httpx.AsyncClient.__init__ = _patched_client_init |
| |
|
| | from .config import ( |
| | AVAILABLE_MODELS, DEFAULT_MODEL, DEFAULT_MODEL_NAME, |
| | LANGUAGE_CHOICES, get_gradio_language |
| | ) |
| | from .themes import THEME_CONFIGS, get_saved_theme, current_theme |
| | from .prompts import HTML_SYSTEM_PROMPT |
| | from .models import history_to_chatbot_messages |
| | from .parsers import ( |
| | history_render, clear_history, create_multimodal_message, |
| | parse_multipage_html_output, parse_transformers_js_output, |
| | parse_react_output, format_transformers_js_output, |
| | validate_and_autofix_files, parse_multi_file_python_output, |
| | is_streamlit_code, is_gradio_code |
| | ) |
| | from .deploy import ( |
| | check_authentication, update_ui_for_auth_status, |
| | generation_code, deploy_to_spaces, add_anycoder_tag_to_readme, |
| | _parse_repo_or_model_url, load_project_from_url, check_hf_space_url, |
| | import_repo_to_app, extract_import_statements, |
| | generate_requirements_txt_with_llm, prettify_comfyui_json_for_html, |
| | get_trending_models, import_model_from_hf, get_trending_spaces, import_space_from_hf, |
| | switch_model_code_type |
| | ) |
| | from .agent import ( |
| | agent_generate_with_questions, agent_process_answers_and_generate |
| | ) |
| |
|
| | |
| | with gr.Blocks( |
| | title="AnyCoder - AI Code Generator", |
| | theme=current_theme, |
| | css=""" |
| | .theme-info { font-size: 0.9em; opacity: 0.8; } |
| | .theme-description { padding: 8px 0; } |
| | .theme-status { |
| | padding: 10px; |
| | border-radius: 8px; |
| | background: rgba(34, 197, 94, 0.1); |
| | border: 1px solid rgba(34, 197, 94, 0.2); |
| | margin: 8px 0; |
| | } |
| | .restart-needed { |
| | padding: 12px; |
| | border-radius: 8px; |
| | background: rgba(255, 193, 7, 0.1); |
| | border: 1px solid rgba(255, 193, 7, 0.3); |
| | margin: 8px 0; |
| | text-align: center; |
| | } |
| | /* Authentication status styling */ |
| | .auth-status { |
| | padding: 8px 12px; |
| | border-radius: 6px; |
| | margin: 8px 0; |
| | font-weight: 500; |
| | text-align: center; |
| | } |
| | .auth-status:has-text("🔒") { |
| | background: rgba(231, 76, 60, 0.1); |
| | border: 1px solid rgba(231, 76, 60, 0.3); |
| | color: #e74c3c; |
| | } |
| | .auth-status:has-text("✅") { |
| | background: rgba(46, 204, 113, 0.1); |
| | border: 1px solid rgba(46, 204, 113, 0.3); |
| | color: #2ecc71; |
| | } |
| | /* App link styling (visible on all devices) */ |
| | .app-link { |
| | display: block; |
| | padding: 12px; |
| | border-radius: 8px; |
| | background: rgba(59, 130, 246, 0.1); |
| | border: 1px solid rgba(59, 130, 246, 0.3); |
| | margin: 12px 0; |
| | text-align: center; |
| | } |
| | """ |
| | ) as demo: |
| | history = gr.State([]) |
| | setting = gr.State({ |
| | "system": HTML_SYSTEM_PROMPT, |
| | }) |
| | current_model = gr.State(DEFAULT_MODEL) |
| | open_panel = gr.State(None) |
| | last_login_state = gr.State(None) |
| | models_first_change = gr.State(True) |
| | spaces_first_change = gr.State(True) |
| | agent_mode_enabled = gr.State(False) |
| | current_trending_model_id = gr.State("") |
| | agent_conversation_state = gr.State({ |
| | "stage": "initial", |
| | "original_query": "", |
| | "questions": "" |
| | }) |
| |
|
| | with gr.Sidebar() as sidebar: |
| | login_button = gr.LoginButton() |
| | |
| | |
| | mobile_link = gr.HTML( |
| | """ |
| | <div class="app-link"> |
| | 📱 <strong>Using Mobile?</strong><br/> |
| | <a href="https://akhaliq-anycoder.hf.space" target="_blank" style="color: #007bff; text-decoration: underline;"> |
| | Use the app here |
| | </a> |
| | </div> |
| | """, |
| | visible=True |
| | ) |
| |
|
| |
|
| | |
| | import_header_md = gr.Markdown("📥 Import Project (Space, GitHub, or Model)", visible=False) |
| | load_project_url = gr.Textbox( |
| | label="Project URL", |
| | placeholder="https://huggingface.co/spaces/user/space OR https://huggingface.co/user/model OR https://github.com/owner/repo", |
| | lines=1 |
| | , visible=False) |
| | load_project_btn = gr.Button("📥 Import Project", variant="secondary", size="sm", visible=True) |
| | load_project_status = gr.Markdown(visible=False) |
| | |
| | |
| | trending_models_dropdown = gr.Dropdown( |
| | label="🔥 Trending HuggingFace Models", |
| | choices=[], |
| | value=None, |
| | interactive=True, |
| | visible=True |
| | ) |
| | trending_models_status = gr.Markdown(visible=False) |
| | switch_model_code_btn = gr.Button("🔄 Switch Code Type", visible=False, size="sm", variant="secondary") |
| | |
| | |
| | trending_spaces_dropdown = gr.Dropdown( |
| | label="🚀 Trending HuggingFace Spaces", |
| | choices=[], |
| | value=None, |
| | interactive=True, |
| | visible=True |
| | ) |
| | trending_spaces_status = gr.Markdown(visible=False) |
| | |
| | |
| | chat_history = gr.Chatbot( |
| | label="Conversation History", |
| | type="messages", |
| | height=300, |
| | show_copy_button=True, |
| | visible=True |
| | ) |
| | |
| | |
| | input = gr.Textbox( |
| | label="What would you like to build?", |
| | placeholder="🔒 Please log in with Hugging Face to use AnyCoder...", |
| | lines=2, |
| | visible=True, |
| | interactive=False |
| | ) |
| | |
| | language_choices = [ |
| | "html", "gradio", "transformers.js", "streamlit", "comfyui", "react" |
| | ] |
| | language_dropdown = gr.Dropdown( |
| | choices=language_choices, |
| | value="html", |
| | label="Code Language", |
| | visible=True |
| | ) |
| | |
| | |
| | agent_mode_checkbox = gr.Checkbox( |
| | label="🤖 Enable Agent Mode", |
| | value=False, |
| | info="Agent will ask follow-up questions and create a task list before coding", |
| | visible=True |
| | ) |
| | |
| | |
| | with gr.Row(): |
| | btn = gr.Button("Generate", variant="secondary", size="lg", scale=2, visible=True, interactive=False) |
| | clear_btn = gr.Button("Clear", variant="secondary", size="sm", scale=1, visible=True) |
| | |
| | deploy_header_md = gr.Markdown("", visible=False) |
| | deploy_btn = gr.Button("Publish", variant="primary", visible=True) |
| | deploy_status = gr.Markdown(visible=False, label="Deploy status") |
| | |
| | |
| |
|
| | |
| | model_dropdown = gr.Dropdown( |
| | choices=[model['name'] for model in AVAILABLE_MODELS], |
| | value=DEFAULT_MODEL_NAME, |
| | label="Model", |
| | visible=True |
| | ) |
| | provider_state = gr.State("auto") |
| | |
| | def on_model_change(model_name): |
| | for m in AVAILABLE_MODELS: |
| | if m['name'] == model_name: |
| | return m |
| | return AVAILABLE_MODELS[0] |
| | def save_prompt(input): |
| | return {setting: {"system": input}} |
| | model_dropdown.change( |
| | lambda model_name: on_model_change(model_name), |
| | inputs=model_dropdown, |
| | outputs=[current_model] |
| | ) |
| | |
| | |
| |
|
| | with gr.Column() as main_column: |
| | with gr.Tabs(): |
| | with gr.Tab("Code"): |
| | code_output = gr.Code( |
| | language="html", |
| | lines=25, |
| | interactive=True, |
| | label="Generated code" |
| | ) |
| | |
| | |
| | |
| | |
| | with gr.Group(visible=False) as tjs_group: |
| | with gr.Tabs(): |
| | with gr.Tab("index.html"): |
| | tjs_html_code = gr.Code(language="html", lines=20, interactive=True, label="index.html") |
| | with gr.Tab("index.js"): |
| | tjs_js_code = gr.Code(language="javascript", lines=20, interactive=True, label="index.js") |
| | with gr.Tab("style.css"): |
| | tjs_css_code = gr.Code(language="css", lines=20, interactive=True, label="style.css") |
| |
|
| | |
| | with gr.Group(visible=False) as python_group_2: |
| | with gr.Tabs(): |
| | with gr.Tab("app.py") as python_tab_2_1: |
| | python_code_2_1 = gr.Code(language="python", lines=20, interactive=True, label="app.py") |
| | with gr.Tab("file 2") as python_tab_2_2: |
| | python_code_2_2 = gr.Code(language="python", lines=18, interactive=True, label="file 2") |
| | |
| | with gr.Group(visible=False) as python_group_3: |
| | with gr.Tabs(): |
| | with gr.Tab("app.py") as python_tab_3_1: |
| | python_code_3_1 = gr.Code(language="python", lines=20, interactive=True, label="app.py") |
| | with gr.Tab("file 2") as python_tab_3_2: |
| | python_code_3_2 = gr.Code(language="python", lines=18, interactive=True, label="file 2") |
| | with gr.Tab("file 3") as python_tab_3_3: |
| | python_code_3_3 = gr.Code(language="python", lines=18, interactive=True, label="file 3") |
| | |
| | with gr.Group(visible=False) as python_group_4: |
| | with gr.Tabs(): |
| | with gr.Tab("app.py") as python_tab_4_1: |
| | python_code_4_1 = gr.Code(language="python", lines=20, interactive=True, label="app.py") |
| | with gr.Tab("file 2") as python_tab_4_2: |
| | python_code_4_2 = gr.Code(language="python", lines=18, interactive=True, label="file 2") |
| | with gr.Tab("file 3") as python_tab_4_3: |
| | python_code_4_3 = gr.Code(language="python", lines=18, interactive=True, label="file 3") |
| | with gr.Tab("file 4") as python_tab_4_4: |
| | python_code_4_4 = gr.Code(language="python", lines=18, interactive=True, label="file 4") |
| | |
| | with gr.Group(visible=False) as python_group_5plus: |
| | with gr.Tabs(): |
| | with gr.Tab("app.py") as python_tab_5_1: |
| | python_code_5_1 = gr.Code(language="python", lines=20, interactive=True, label="app.py") |
| | with gr.Tab("file 2") as python_tab_5_2: |
| | python_code_5_2 = gr.Code(language="python", lines=18, interactive=True, label="file 2") |
| | with gr.Tab("file 3") as python_tab_5_3: |
| | python_code_5_3 = gr.Code(language="python", lines=18, interactive=True, label="file 3") |
| | with gr.Tab("file 4") as python_tab_5_4: |
| | python_code_5_4 = gr.Code(language="python", lines=18, interactive=True, label="file 4") |
| | with gr.Tab("file 5") as python_tab_5_5: |
| | python_code_5_5 = gr.Code(language="python", lines=18, interactive=True, label="file 5") |
| | |
| | |
| | with gr.Group(visible=False) as static_group_2: |
| | with gr.Tabs(): |
| | with gr.Tab("index.html") as static_tab_2_1: |
| | static_code_2_1 = gr.Code(language="html", lines=20, interactive=True, label="index.html") |
| | with gr.Tab("file 2") as static_tab_2_2: |
| | static_code_2_2 = gr.Code(language="html", lines=18, interactive=True, label="file 2") |
| | |
| | with gr.Group(visible=False) as static_group_3: |
| | with gr.Tabs(): |
| | with gr.Tab("index.html") as static_tab_3_1: |
| | static_code_3_1 = gr.Code(language="html", lines=20, interactive=True, label="index.html") |
| | with gr.Tab("file 2") as static_tab_3_2: |
| | static_code_3_2 = gr.Code(language="html", lines=18, interactive=True, label="file 2") |
| | with gr.Tab("file 3") as static_tab_3_3: |
| | static_code_3_3 = gr.Code(language="html", lines=18, interactive=True, label="file 3") |
| | |
| | with gr.Group(visible=False) as static_group_4: |
| | with gr.Tabs(): |
| | with gr.Tab("index.html") as static_tab_4_1: |
| | static_code_4_1 = gr.Code(language="html", lines=20, interactive=True, label="index.html") |
| | with gr.Tab("file 2") as static_tab_4_2: |
| | static_code_4_2 = gr.Code(language="html", lines=18, interactive=True, label="file 2") |
| | with gr.Tab("file 3") as static_tab_4_3: |
| | static_code_4_3 = gr.Code(language="html", lines=18, interactive=True, label="file 3") |
| | with gr.Tab("file 4") as static_tab_4_4: |
| | static_code_4_4 = gr.Code(language="html", lines=18, interactive=True, label="file 4") |
| | |
| | with gr.Group(visible=False) as static_group_5plus: |
| | with gr.Tabs(): |
| | with gr.Tab("index.html") as static_tab_5_1: |
| | static_code_5_1 = gr.Code(language="html", lines=20, interactive=True, label="index.html") |
| | with gr.Tab("file 2") as static_tab_5_2: |
| | static_code_5_2 = gr.Code(language="html", lines=18, interactive=True, label="file 2") |
| | with gr.Tab("file 3") as static_tab_5_3: |
| | static_code_5_3 = gr.Code(language="html", lines=18, interactive=True, label="file 3") |
| | with gr.Tab("file 4") as static_tab_5_4: |
| | static_code_5_4 = gr.Code(language="html", lines=18, interactive=True, label="file 4") |
| | with gr.Tab("file 5") as static_tab_5_5: |
| | static_code_5_5 = gr.Code(language="html", lines=18, interactive=True, label="file 5") |
| | |
| | with gr.Group(visible=False) as react_group: |
| | with gr.Tabs(): |
| | with gr.Tab("Dockerfile"): |
| | react_code_dockerfile = gr.Code(language="dockerfile", lines=15, interactive=True, label="Dockerfile") |
| | with gr.Tab("package.json"): |
| | react_code_package_json = gr.Code(language="json", lines=20, interactive=True, label="package.json") |
| | with gr.Tab("next.config.js"): |
| | react_code_next_config = gr.Code(language="javascript", lines=15, interactive=True, label="next.config.js") |
| | with gr.Tab("postcss.config.js"): |
| | react_code_postcss_config = gr.Code(language="javascript", lines=10, interactive=True, label="postcss.config.js") |
| | with gr.Tab("tailwind.config.js"): |
| | react_code_tailwind_config = gr.Code(language="javascript", lines=15, interactive=True, label="tailwind.config.js") |
| | with gr.Tab("pages/_app.js"): |
| | react_code_pages_app = gr.Code(language="javascript", lines=15, interactive=True, label="pages/_app.js") |
| | with gr.Tab("pages/index.js"): |
| | react_code_pages_index = gr.Code(language="javascript", lines=20, interactive=True, label="pages/index.js") |
| | with gr.Tab("components/ChatApp.jsx"): |
| | react_code_components = gr.Code(language="javascript", lines=25, interactive=True, label="components/ChatApp.jsx") |
| | with gr.Tab("styles/globals.css"): |
| | react_code_styles = gr.Code(language="css", lines=20, interactive=True, label="styles/globals.css") |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | history_output = gr.Chatbot(show_label=False, height=400, type="messages", visible=False) |
| |
|
| | |
| | generating_status = gr.Markdown("", visible=False) |
| |
|
| | |
| | def handle_import_project(url): |
| | if not url.strip(): |
| | return [ |
| | gr.update(value="Please enter a URL.", visible=True), |
| | gr.update(), |
| | gr.update(), |
| | [], |
| | [], |
| | gr.update(value="Publish", visible=False), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | [] |
| | ] |
| |
|
| | kind, meta = _parse_repo_or_model_url(url) |
| | if kind == "hf_space": |
| | status, code = load_project_from_url(url) |
| | |
| | is_valid, username, project_name = check_hf_space_url(url) |
| | space_name = f"{username}/{project_name}" if is_valid else "" |
| | loaded_history = [[f"Imported Space from {url}", code]] |
| | |
| | |
| | code_lang = "html" |
| | framework_type = "html" |
| | |
| | |
| | if is_streamlit_code(code): |
| | code_lang = "python" |
| | framework_type = "streamlit" |
| | elif is_gradio_code(code): |
| | code_lang = "python" |
| | framework_type = "gradio" |
| | elif "=== index.html ===" in code and "=== index.js ===" in code and "=== style.css ===" in code: |
| | |
| | code_lang = "html" |
| | framework_type = "transformers.js" |
| | elif ("import " in code or "def " in code) and not ("<!DOCTYPE html>" in code or "<html" in code): |
| | |
| | |
| | code_lang = "python" |
| | framework_type = "gradio" |
| | |
| | |
| | return [ |
| | gr.update(value=status, visible=True), |
| | gr.update(value=code, language=code_lang), |
| | gr.update(value="", visible=False), |
| | loaded_history, |
| | history_to_chatbot_messages(loaded_history), |
| | gr.update(value="Publish", visible=True), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(value=framework_type), |
| | history_to_chatbot_messages(loaded_history) |
| | ] |
| | else: |
| | |
| | status, code, _ = import_repo_to_app(url) |
| | loaded_history = [[f"Imported Repo/Model from {url}", code]] |
| | code_lang = "python" |
| | framework_type = "gradio" |
| | lower = (code or "").lower() |
| | if code.strip().startswith("<!doctype html>") or code.strip().startswith("<html"): |
| | code_lang = "html" |
| | framework_type = "html" |
| | elif "```json" in lower: |
| | code_lang = "json" |
| | framework_type = "json" |
| | return [ |
| | gr.update(value=status, visible=True), |
| | gr.update(value=code, language=code_lang), |
| | gr.update(value="", visible=False), |
| | loaded_history, |
| | history_to_chatbot_messages(loaded_history), |
| | gr.update(value="Publish", visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(value=framework_type), |
| | history_to_chatbot_messages(loaded_history) |
| | ] |
| |
|
| | |
| | def handle_import_repo(url, framework): |
| | status, code, preview = import_repo_to_app(url, framework) |
| | |
| | code_lang = "python" |
| | lowered = (code or "").lower() |
| | if code.strip().startswith("<!doctype html>") or code.strip().startswith("<html"): |
| | code_lang = "html" |
| | elif "import gradio" in lowered or "from gradio" in lowered: |
| | code_lang = "python" |
| | elif "streamlit as st" in lowered or "import streamlit" in lowered: |
| | code_lang = "python" |
| | elif "from transformers" in lowered or "import transformers" in lowered: |
| | code_lang = "python" |
| | elif "from diffusers" in lowered or "import diffusers" in lowered: |
| | code_lang = "python" |
| | return [ |
| | gr.update(value=status, visible=True), |
| | gr.update(value=code, language=code_lang), |
| | gr.update(value=""), |
| | gr.update(value=f"URL: {url}\n\n{status}"), |
| | ] |
| |
|
| | |
| | def update_code_language(language): |
| | return gr.update(language=get_gradio_language(language)) |
| |
|
| |
|
| | language_dropdown.change(update_code_language, inputs=language_dropdown, outputs=code_output) |
| |
|
| | |
| | def toggle_editors(language, code_text): |
| | if language == "transformers.js": |
| | files = parse_transformers_js_output(code_text or "") |
| | |
| | editors_visible = True if (files.get('index.html') and files.get('index.js') and files.get('style.css')) else False |
| | return [ |
| | gr.update(visible=not editors_visible), |
| | gr.update(visible=editors_visible), |
| | gr.update(value=files.get('index.html', '')), |
| | gr.update(value=files.get('index.js', '')), |
| | gr.update(value=files.get('style.css', '')), |
| | |
| | gr.update(visible=False), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | ] |
| | elif language == "react": |
| | files = parse_react_output(code_text or "") |
| | |
| | editors_visible = True if files else False |
| | if editors_visible: |
| | return [ |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | |
| | gr.update(visible=editors_visible), |
| | gr.update(value=files.get('Dockerfile', '')), |
| | gr.update(value=files.get('package.json', '')), |
| | gr.update(value=files.get('next.config.js', '')), |
| | gr.update(value=files.get('postcss.config.js', '')), |
| | gr.update(value=files.get('tailwind.config.js', '')), |
| | gr.update(value=files.get('pages/_app.js', '')), |
| | gr.update(value=files.get('pages/index.js', '')), |
| | gr.update(value=files.get('components/ChatApp.jsx', '')), |
| | gr.update(value=files.get('styles/globals.css', '')), |
| | ] |
| | else: |
| | return [ |
| | gr.update(visible=True), |
| | gr.update(visible=False), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | |
| | gr.update(visible=False), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | ] |
| | else: |
| | return [ |
| | gr.update(visible=True), |
| | gr.update(visible=False), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | |
| | gr.update(visible=False), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | ] |
| |
|
| | language_dropdown.change( |
| | toggle_editors, |
| | inputs=[language_dropdown, code_output], |
| | outputs=[code_output, tjs_group, tjs_html_code, tjs_js_code, tjs_css_code, react_group, react_code_dockerfile, react_code_package_json, react_code_next_config, react_code_postcss_config, react_code_tailwind_config, react_code_pages_app, react_code_pages_index, react_code_components, react_code_styles], |
| | ) |
| | |
| | def toggle_python_editors(language, code_text): |
| | if language not in ["gradio", "streamlit"]: |
| | return [ |
| | gr.update(visible=True), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update() |
| | ] |
| |
|
| | files = parse_multi_file_python_output(code_text or "") |
| |
|
| | if not isinstance(files, dict) or len(files) <= 1: |
| | |
| | return [ |
| | gr.update(visible=True), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update() |
| | ] |
| |
|
| | |
| | |
| | ordered_paths = [] |
| | main_files = ['app.py', 'streamlit_app.py', 'main.py'] |
| | for main_file in main_files: |
| | if main_file in files: |
| | ordered_paths.append(main_file) |
| | break |
| | |
| | for p in sorted(files.keys()): |
| | if p not in ordered_paths: |
| | ordered_paths.append(p) |
| |
|
| | num_files = len(ordered_paths) |
| | |
| | |
| | updates = [gr.update(visible=False)] |
| | |
| | if num_files == 2: |
| | updates.extend([ |
| | gr.update(visible=True), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | ]) |
| | |
| | path1, path2 = ordered_paths[0], ordered_paths[1] |
| | updates.extend([ |
| | gr.update(label=path1), gr.update(value=files.get(path1, ''), label=path1, language="python"), |
| | gr.update(label=path2), gr.update(value=files.get(path2, ''), label=path2, language="python"), |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update() |
| | ]) |
| | elif num_files == 3: |
| | updates.extend([ |
| | gr.update(visible=False), |
| | gr.update(visible=True), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | ]) |
| | |
| | path1, path2, path3 = ordered_paths[0], ordered_paths[1], ordered_paths[2] |
| | updates.extend([ |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), |
| | |
| | gr.update(label=path1), gr.update(value=files.get(path1, ''), label=path1, language="python"), |
| | gr.update(label=path2), gr.update(value=files.get(path2, ''), label=path2, language="python"), |
| | gr.update(label=path3), gr.update(value=files.get(path3, ''), label=path3, language="python"), |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update() |
| | ]) |
| | elif num_files == 4: |
| | updates.extend([ |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=True), |
| | gr.update(visible=False), |
| | ]) |
| | |
| | paths = ordered_paths[:4] |
| | updates.extend([ |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | |
| | gr.update(label=paths[0]), gr.update(value=files.get(paths[0], ''), label=paths[0], language="python"), |
| | gr.update(label=paths[1]), gr.update(value=files.get(paths[1], ''), label=paths[1], language="python"), |
| | gr.update(label=paths[2]), gr.update(value=files.get(paths[2], ''), label=paths[2], language="python"), |
| | gr.update(label=paths[3]), gr.update(value=files.get(paths[3], ''), label=paths[3], language="python"), |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update() |
| | ]) |
| | else: |
| | updates.extend([ |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=True), |
| | ]) |
| | |
| | paths = ordered_paths[:5] |
| | updates.extend([ |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | |
| | gr.update(label=paths[0]), gr.update(value=files.get(paths[0], ''), label=paths[0], language="python"), |
| | gr.update(label=paths[1]), gr.update(value=files.get(paths[1], ''), label=paths[1], language="python"), |
| | gr.update(label=paths[2]), gr.update(value=files.get(paths[2], ''), label=paths[2], language="python"), |
| | gr.update(label=paths[3]), gr.update(value=files.get(paths[3], ''), label=paths[3], language="python"), |
| | gr.update(label=paths[4]), gr.update(value=files.get(paths[4], ''), label=paths[4], language="python"), |
| | ]) |
| |
|
| | return updates |
| |
|
| | language_dropdown.change( |
| | toggle_python_editors, |
| | inputs=[language_dropdown, code_output], |
| | outputs=[ |
| | code_output, python_group_2, python_group_3, python_group_4, python_group_5plus, |
| | python_tab_2_1, python_code_2_1, python_tab_2_2, python_code_2_2, |
| | python_tab_3_1, python_code_3_1, python_tab_3_2, python_code_3_2, python_tab_3_3, python_code_3_3, |
| | python_tab_4_1, python_code_4_1, python_tab_4_2, python_code_4_2, python_tab_4_3, python_code_4_3, python_tab_4_4, python_code_4_4, |
| | python_tab_5_1, python_code_5_1, python_tab_5_2, python_code_5_2, python_tab_5_3, python_code_5_3, python_tab_5_4, python_code_5_4, python_tab_5_5, python_code_5_5 |
| | ], |
| | ) |
| |
|
| | |
| | def toggle_static_editors(language, code_text): |
| | |
| | if language != "html": |
| | return [ |
| | gr.update(visible=True), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update() |
| | ] |
| |
|
| | |
| | original_files = parse_multipage_html_output(code_text or "") |
| | |
| | |
| | |
| | if not isinstance(original_files, dict) or len(original_files) <= 1: |
| | |
| | return [ |
| | gr.update(visible=True), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update() |
| | ] |
| | |
| | |
| | files = validate_and_autofix_files(original_files) |
| |
|
| | |
| | |
| | ordered_paths = [] |
| | if 'index.html' in files: |
| | ordered_paths.append('index.html') |
| | for p in sorted(files.keys()): |
| | if p == 'index.html': |
| | continue |
| | ordered_paths.append(p) |
| |
|
| | |
| | def _lang_for(path: str): |
| | p = (path or '').lower() |
| | if p.endswith('.html'): |
| | return 'html' |
| | if p.endswith('.css'): |
| | return 'css' |
| | if p.endswith('.js'): |
| | return 'javascript' |
| | if p.endswith('.json'): |
| | return 'json' |
| | if p.endswith('.md') or p.endswith('.markdown'): |
| | return 'markdown' |
| | return 'html' |
| |
|
| | num_files = len(ordered_paths) |
| | |
| | |
| | |
| | |
| | updates = [ |
| | gr.update(visible=True), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | gr.update(visible=False), |
| | ] |
| | |
| | |
| | updates.extend([ |
| | |
| | gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), |
| | gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update() |
| | ]) |
| | |
| | return updates |
| |
|
| | |
| | language_dropdown.change( |
| | toggle_static_editors, |
| | inputs=[language_dropdown, code_output], |
| | outputs=[ |
| | code_output, |
| | static_group_2, static_group_3, static_group_4, static_group_5plus, |
| | static_tab_2_1, static_code_2_1, static_tab_2_2, static_code_2_2, |
| | static_tab_3_1, static_code_3_1, static_tab_3_2, static_code_3_2, static_tab_3_3, static_code_3_3, |
| | static_tab_4_1, static_code_4_1, static_tab_4_2, static_code_4_2, static_tab_4_3, static_code_4_3, static_tab_4_4, static_code_4_4, |
| | static_tab_5_1, static_code_5_1, static_tab_5_2, static_code_5_2, static_tab_5_3, static_code_5_3, static_tab_5_4, static_code_5_4, static_tab_5_5, static_code_5_5, |
| | ], |
| | ) |
| |
|
| | def sync_tjs_from_code(code_text, language): |
| | if language != "transformers.js": |
| | return [gr.update(), gr.update(), gr.update(), gr.update()] |
| | files = parse_transformers_js_output(code_text or "") |
| | |
| | editors_visible = True if (files.get('index.html') and files.get('index.js') and files.get('style.css')) else None |
| | return [ |
| | gr.update(value=files.get('index.html', '')), |
| | gr.update(value=files.get('index.js', '')), |
| | gr.update(value=files.get('style.css', '')), |
| | gr.update(visible=editors_visible) if editors_visible is not None else gr.update(), |
| | ] |
| |
|
| | |
| | code_output.change( |
| | sync_tjs_from_code, |
| | inputs=[code_output, language_dropdown], |
| | outputs=[tjs_html_code, tjs_js_code, tjs_css_code, tjs_group], |
| | ) |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | def show_tjs_deployment_message(*args): |
| | return """ |
| | <div style='padding: 1.5em; text-align: center; background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%); color: white; border-radius: 10px;'> |
| | <h3 style='margin-top: 0; color: white;'>🚀 Transformers.js App Ready!</h3> |
| | <p style='margin: 0.5em 0; opacity: 0.9;'>Your multi-file Transformers.js application is ready for deployment.</p> |
| | <p style='margin: 0.5em 0; font-weight: bold;'>👉 Use the Deploy button in the sidebar to publish your app!</p> |
| | </div> |
| | """ |
| | |
| |
|
| | def show_deploy_components(*args): |
| | return gr.Button(visible=True) |
| |
|
| | def hide_deploy_components(*args): |
| | return gr.Button(visible=True) |
| | |
| | |
| | def toggle_import_textbox(url_visible): |
| | |
| | |
| | return gr.update(visible=True) |
| | |
| | load_project_btn.click( |
| | fn=toggle_import_textbox, |
| | inputs=[load_project_url], |
| | outputs=[load_project_url] |
| | ).then( |
| | handle_import_project, |
| | inputs=[load_project_url], |
| | outputs=[ |
| | load_project_status, |
| | code_output, |
| | load_project_url, |
| | history, |
| | history_output, |
| | deploy_btn, |
| | import_header_md, |
| | load_project_btn, |
| | language_dropdown, |
| | chat_history, |
| | ], |
| | ) |
| |
|
| |
|
| |
|
| |
|
| |
|
| | def begin_generation_ui(agent_enabled): |
| | |
| | |
| | if agent_enabled: |
| | return [gr.update(), gr.update(visible=False)] |
| | else: |
| | |
| | return [gr.update(open=False), gr.update(visible=False)] |
| |
|
| | def end_generation_ui(): |
| | |
| | return [gr.update(open=True), gr.update(visible=False)] |
| | |
| | def close_sidebar_for_coding(): |
| | |
| | return gr.update(open=False) |
| |
|
| | def generation_code_wrapper(inp, sett, hist, model, lang, prov, agent_enabled, agent_state, profile: Optional[gr.OAuthProfile] = None, token: Optional[gr.OAuthToken] = None): |
| | """Wrapper to call generation_code or agent mode based on settings""" |
| | |
| | |
| | if agent_enabled and agent_state["stage"] == "initial": |
| | |
| | |
| | for updated_hist, chatbot_msgs in agent_generate_with_questions( |
| | inp, sett, hist, model, lang, prov, profile, token |
| | ): |
| | |
| | new_agent_state = { |
| | "stage": "waiting_for_answers", |
| | "original_query": inp, |
| | "questions": updated_hist[-1][1] if updated_hist else "" |
| | } |
| | |
| | yield "", updated_hist, chatbot_msgs, chatbot_msgs, new_agent_state, gr.update() |
| | return |
| | |
| | elif agent_enabled and agent_state["stage"] == "waiting_for_answers": |
| | |
| | original_query = agent_state.get("original_query", "") |
| | questions = agent_state.get("questions", "") |
| | |
| | |
| | started_code_generation = False |
| | |
| | |
| | for result in agent_process_answers_and_generate( |
| | inp, original_query, questions, sett, hist, model, lang, prov, |
| | profile, token, code_output, history_output, history |
| | ): |
| | |
| | code_val = result.get(code_output, "") |
| | hist_val = result.get(history, hist) |
| | history_output_val = result.get(history_output, []) |
| | |
| | |
| | reset_agent_state = { |
| | "stage": "initial", |
| | "original_query": "", |
| | "questions": "" |
| | } |
| | |
| | |
| | if code_val and not started_code_generation: |
| | sidebar_update = gr.update(open=False) |
| | started_code_generation = True |
| | else: |
| | sidebar_update = gr.update() |
| | |
| | |
| | yield code_val, hist_val, history_output_val, history_output_val, reset_agent_state, sidebar_update |
| | return |
| | |
| | else: |
| | |
| | |
| | for result in generation_code(inp, sett, hist, model, lang, prov, profile, token, code_output, history_output, history): |
| | |
| | |
| | code_val = result.get(code_output, "") |
| | hist_val = result.get(history, hist) |
| | history_output_val = result.get(history_output, []) |
| | |
| | yield code_val, hist_val, history_output_val, history_output_val, agent_state, gr.update() |
| |
|
| | |
| | agent_mode_checkbox.change( |
| | lambda enabled: enabled, |
| | inputs=[agent_mode_checkbox], |
| | outputs=[agent_mode_enabled] |
| | ) |
| | |
| | btn.click( |
| | begin_generation_ui, |
| | inputs=[agent_mode_enabled], |
| | outputs=[sidebar, generating_status], |
| | show_progress="hidden", |
| | ).then( |
| | generation_code_wrapper, |
| | inputs=[input, setting, history, current_model, language_dropdown, provider_state, agent_mode_enabled, agent_conversation_state], |
| | outputs=[code_output, history, history_output, chat_history, agent_conversation_state, sidebar] |
| | ).then( |
| | end_generation_ui, |
| | inputs=None, |
| | outputs=[sidebar, generating_status] |
| | ).then( |
| | |
| | toggle_editors, |
| | inputs=[language_dropdown, code_output], |
| | outputs=[code_output, tjs_group, tjs_html_code, tjs_js_code, tjs_css_code, react_group, react_code_dockerfile, react_code_package_json, react_code_next_config, react_code_postcss_config, react_code_tailwind_config, react_code_pages_app, react_code_pages_index, react_code_components, react_code_styles] |
| | ).then( |
| | |
| | toggle_static_editors, |
| | inputs=[language_dropdown, code_output], |
| | outputs=[ |
| | code_output, |
| | static_group_2, static_group_3, static_group_4, static_group_5plus, |
| | static_tab_2_1, static_code_2_1, static_tab_2_2, static_code_2_2, |
| | static_tab_3_1, static_code_3_1, static_tab_3_2, static_code_3_2, static_tab_3_3, static_code_3_3, |
| | static_tab_4_1, static_code_4_1, static_tab_4_2, static_code_4_2, static_tab_4_3, static_code_4_3, static_tab_4_4, static_code_4_4, |
| | static_tab_5_1, static_code_5_1, static_tab_5_2, static_code_5_2, static_tab_5_3, static_code_5_3, static_tab_5_4, static_code_5_4, static_tab_5_5, static_code_5_5, |
| | ] |
| | ).then( |
| | |
| | toggle_python_editors, |
| | inputs=[language_dropdown, code_output], |
| | outputs=[ |
| | code_output, python_group_2, python_group_3, python_group_4, python_group_5plus, |
| | python_tab_2_1, python_code_2_1, python_tab_2_2, python_code_2_2, |
| | python_tab_3_1, python_code_3_1, python_tab_3_2, python_code_3_2, python_tab_3_3, python_code_3_3, |
| | python_tab_4_1, python_code_4_1, python_tab_4_2, python_code_4_2, python_tab_4_3, python_code_4_3, python_tab_4_4, python_code_4_4, |
| | python_tab_5_1, python_code_5_1, python_tab_5_2, python_code_5_2, python_tab_5_3, python_code_5_3, python_tab_5_4, python_code_5_4, python_tab_5_5, python_code_5_5 |
| | ] |
| | ).then( |
| | show_deploy_components, |
| | None, |
| | [deploy_btn] |
| | ) |
| |
|
| | |
| | input.submit( |
| | begin_generation_ui, |
| | inputs=[agent_mode_enabled], |
| | outputs=[sidebar, generating_status], |
| | show_progress="hidden", |
| | ).then( |
| | generation_code_wrapper, |
| | inputs=[input, setting, history, current_model, language_dropdown, provider_state, agent_mode_enabled, agent_conversation_state], |
| | outputs=[code_output, history, history_output, chat_history, agent_conversation_state, sidebar] |
| | ).then( |
| | end_generation_ui, |
| | inputs=None, |
| | outputs=[sidebar, generating_status] |
| | ).then( |
| | |
| | toggle_editors, |
| | inputs=[language_dropdown, code_output], |
| | outputs=[code_output, tjs_group, tjs_html_code, tjs_js_code, tjs_css_code, react_group, react_code_dockerfile, react_code_package_json, react_code_next_config, react_code_postcss_config, react_code_tailwind_config, react_code_pages_app, react_code_pages_index, react_code_components, react_code_styles] |
| | ).then( |
| | |
| | toggle_static_editors, |
| | inputs=[language_dropdown, code_output], |
| | outputs=[ |
| | code_output, |
| | static_group_2, static_group_3, static_group_4, static_group_5plus, |
| | static_tab_2_1, static_code_2_1, static_tab_2_2, static_code_2_2, |
| | static_tab_3_1, static_code_3_1, static_tab_3_2, static_code_3_2, static_tab_3_3, static_code_3_3, |
| | static_tab_4_1, static_code_4_1, static_tab_4_2, static_code_4_2, static_tab_4_3, static_code_4_3, static_tab_4_4, static_code_4_4, |
| | static_tab_5_1, static_code_5_1, static_tab_5_2, static_code_5_2, static_tab_5_3, static_code_5_3, static_tab_5_4, static_code_5_4, static_tab_5_5, static_code_5_5, |
| | ] |
| | ).then( |
| | |
| | toggle_python_editors, |
| | inputs=[language_dropdown, code_output], |
| | outputs=[ |
| | code_output, python_group_2, python_group_3, python_group_4, python_group_5plus, |
| | python_tab_2_1, python_code_2_1, python_tab_2_2, python_code_2_2, |
| | python_tab_3_1, python_code_3_1, python_tab_3_2, python_code_3_2, python_tab_3_3, python_code_3_3, |
| | python_tab_4_1, python_code_4_1, python_tab_4_2, python_code_4_2, python_tab_4_3, python_code_4_3, python_tab_4_4, python_code_4_4, |
| | python_tab_5_1, python_code_5_1, python_tab_5_2, python_code_5_2, python_tab_5_3, python_code_5_3, python_tab_5_4, python_code_5_4, python_tab_5_5, python_code_5_5 |
| | ] |
| | ).then( |
| | show_deploy_components, |
| | None, |
| | [deploy_btn] |
| | ) |
| |
|
| | |
| | def _find_model_by_name(name: str): |
| | for m in AVAILABLE_MODELS: |
| | if m["name"].lower() == name.lower(): |
| | return m |
| | return None |
| |
|
| | def _extract_url(text: str) -> Optional[str]: |
| | import re |
| | match = re.search(r"https?://[^\s]+", text or "") |
| | return match.group(0) if match else None |
| |
|
| |
|
| | |
| | def show_deployment_message(code, language, *args): |
| | if not code or not code.strip(): |
| | return "<div style='padding:1em;color:#888;text-align:center;'>Generate some code to see deployment options.</div>" |
| | return f""" |
| | <div style='padding: 1.5em; text-align: center; background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%); color: white; border-radius: 10px;'> |
| | <h3 style='margin-top: 0; color: white;'>Ready to Deploy!</h3> |
| | <p style='margin: 0.5em 0; opacity: 0.9;'>Your {language.upper()} code is ready for deployment.</p> |
| | <p style='margin: 0.5em 0; font-weight: bold;'>👉 Use the Deploy button in the sidebar to publish your app!</p> |
| | </div> |
| | """ |
| | |
| | def reset_agent_state(): |
| | """Reset agent conversation state when clearing history""" |
| | return { |
| | "stage": "initial", |
| | "original_query": "", |
| | "questions": "" |
| | } |
| | |
| | clear_btn.click(clear_history, outputs=[history, history_output, chat_history]) |
| | clear_btn.click(hide_deploy_components, None, [deploy_btn]) |
| | clear_btn.click(reset_agent_state, outputs=[agent_conversation_state]) |
| | |
| | clear_btn.click( |
| | lambda: gr.update(value="Publish"), |
| | outputs=[deploy_btn] |
| | ) |
| |
|
| | |
| | |
| | def generate_random_app_name(): |
| | """Generate a random app name that's unlikely to clash with existing apps""" |
| | import random |
| | import string |
| | |
| | |
| | prefixes = ["my", "cool", "awesome", "smart", "quick", "super", "mini", "auto", "fast", "easy"] |
| | |
| | suffixes = ["app", "tool", "hub", "space", "demo", "ai", "gen", "bot", "lab", "studio"] |
| | |
| | adjectives = ["blue", "red", "green", "bright", "dark", "light", "swift", "bold", "clean", "fresh"] |
| | |
| | |
| | patterns = [ |
| | lambda: f"{random.choice(prefixes)}-{random.choice(suffixes)}-{random.randint(100, 999)}", |
| | lambda: f"{random.choice(adjectives)}-{random.choice(suffixes)}-{random.randint(10, 99)}", |
| | lambda: f"{random.choice(prefixes)}-{random.choice(adjectives)}-{random.choice(suffixes)}", |
| | lambda: f"app-{''.join(random.choices(string.ascii_lowercase, k=6))}-{random.randint(10, 99)}", |
| | lambda: f"{random.choice(suffixes)}-{''.join(random.choices(string.ascii_lowercase + string.digits, k=8))}" |
| | ] |
| | |
| | return random.choice(patterns)() |
| |
|
| | def deploy_with_history_tracking( |
| | code, |
| | language, |
| | history, |
| | profile: Optional[gr.OAuthProfile] = None, |
| | token: Optional[gr.OAuthToken] = None |
| | ): |
| | """Wrapper function that handles history tracking for deployments""" |
| | |
| | username = profile.username if profile else None |
| | existing_space = None |
| | |
| | |
| | if history and username: |
| | for user_msg, assistant_msg in history: |
| | if assistant_msg and "✅ Deployed!" in assistant_msg: |
| | import re |
| | |
| | match = re.search(r'huggingface\.co/spaces/([^/\s\)]+/[^/\s\)]+)', assistant_msg) |
| | if match: |
| | existing_space = match.group(1) |
| | break |
| | elif assistant_msg and "✅ Updated!" in assistant_msg: |
| | import re |
| | |
| | match = re.search(r'huggingface\.co/spaces/([^/\s\)]+/[^/\s\)]+)', assistant_msg) |
| | if match: |
| | existing_space = match.group(1) |
| | break |
| | elif user_msg and user_msg.startswith("Imported Space from"): |
| | import re |
| | |
| | match = re.search(r'huggingface\.co/spaces/([^/\s\)]+/[^/\s\)]+)', user_msg) |
| | if match: |
| | imported_space = match.group(1) |
| | |
| | if imported_space.startswith(f"{username}/"): |
| | existing_space = imported_space |
| | break |
| | |
| | |
| | |
| | |
| | status = deploy_to_user_space_original(code, language, existing_space, profile, token) |
| | |
| | |
| | updated_history = history |
| | if isinstance(status, dict) and "value" in status and "✅" in status["value"]: |
| | action_type = "Deploy" if "Deployed!" in status["value"] else "Update" |
| | if existing_space: |
| | updated_history = history + [[f"{action_type} {language} app to {existing_space}", status["value"]]] |
| | else: |
| | updated_history = history + [[f"{action_type} {language} app", status["value"]]] |
| | |
| | return [status, updated_history] |
| |
|
| | def deploy_to_user_space_original( |
| | code, |
| | language, |
| | existing_space_name=None, |
| | profile: Optional[gr.OAuthProfile] = None, |
| | token: Optional[gr.OAuthToken] = None |
| | ): |
| | import shutil |
| | if not code or not code.strip(): |
| | return gr.update(value="No code to deploy.", visible=True) |
| | if profile is None or token is None: |
| | return gr.update(value="Please log in with your Hugging Face account to deploy to your own Space. Otherwise, use the default deploy (opens in new tab).", visible=True) |
| | |
| | |
| | if not token.token or token.token == "hf_": |
| | return gr.update(value="Error: Invalid token. Please log in again with your Hugging Face account to get a valid write token.", visible=True) |
| | |
| | |
| | username = profile.username |
| | if existing_space_name and existing_space_name.startswith(f"{username}/"): |
| | |
| | repo_id = existing_space_name |
| | space_name = existing_space_name.split('/')[-1] |
| | is_update = True |
| | else: |
| | |
| | space_name = generate_random_app_name() |
| | repo_id = f"{username}/{space_name}" |
| | is_update = False |
| | |
| | language_to_sdk_map = { |
| | "gradio": "gradio", |
| | "streamlit": "docker", |
| | "react": "docker", |
| | "html": "static", |
| | "transformers.js": "static", |
| | "comfyui": "static" |
| | } |
| | sdk = language_to_sdk_map.get(language, "gradio") |
| | |
| | |
| | api = HfApi(token=token.token) |
| | |
| | if not is_update and sdk != "docker" and language not in ["transformers.js"]: |
| | try: |
| | api.create_repo( |
| | repo_id=repo_id, |
| | repo_type="space", |
| | space_sdk=sdk, |
| | exist_ok=True |
| | ) |
| | except Exception as e: |
| | return gr.update(value=f"Error creating Space: {e}", visible=True) |
| | |
| | if sdk == "docker" and language in ["streamlit", "react"]: |
| | try: |
| | |
| | if not is_update: |
| | |
| | from huggingface_hub import create_repo |
| | |
| | if language == "react": |
| | |
| | created_repo = create_repo( |
| | repo_id=repo_id, |
| | repo_type="space", |
| | space_sdk="docker", |
| | token=token.token, |
| | exist_ok=True |
| | ) |
| | else: |
| | |
| | created_repo = create_repo( |
| | repo_id=repo_id, |
| | repo_type="space", |
| | space_sdk="docker", |
| | token=token.token, |
| | exist_ok=True |
| | ) |
| | |
| | |
| | if language == "react": |
| | |
| | files = parse_react_output(code) |
| | if not files: |
| | return gr.update(value="Error: Could not parse React output. Please regenerate the code.", visible=True) |
| | |
| | |
| | if 'Dockerfile' not in files: |
| | files['Dockerfile'] = """FROM node:18-slim |
| | |
| | # Use the existing node user (UID 1000) |
| | USER node |
| | |
| | # Set environment variables |
| | ENV HOME=/home/node \\ |
| | PATH=/home/node/.local/bin:$PATH |
| | |
| | # Set working directory |
| | WORKDIR /home/node/app |
| | |
| | # Copy package files with proper ownership |
| | COPY --chown=node:node package*.json ./ |
| | |
| | # Install dependencies |
| | RUN npm install |
| | |
| | # Copy rest of the application with proper ownership |
| | COPY --chown=node:node . . |
| | |
| | # Build the Next.js app |
| | RUN npm run build |
| | |
| | # Expose port 7860 |
| | EXPOSE 7860 |
| | |
| | # Start the application on port 7860 |
| | CMD ["npm", "start", "--", "-p", "7860"] |
| | """ |
| | |
| | |
| | import tempfile |
| | import time |
| | |
| | for file_name, file_content in files.items(): |
| | if not file_content: |
| | continue |
| | |
| | success = False |
| | last_error = None |
| | max_attempts = 3 |
| | |
| | for attempt in range(max_attempts): |
| | try: |
| | |
| | if file_name == 'Dockerfile': |
| | suffix = '' |
| | else: |
| | suffix = f".{file_name.split('.')[-1]}" |
| | |
| | with tempfile.NamedTemporaryFile("w", suffix=suffix, delete=False) as f: |
| | f.write(file_content) |
| | temp_path = f.name |
| | |
| | api.upload_file( |
| | path_or_fileobj=temp_path, |
| | path_in_repo=file_name, |
| | repo_id=repo_id, |
| | repo_type="space" |
| | ) |
| | success = True |
| | break |
| | |
| | except Exception as e: |
| | last_error = e |
| | error_msg = str(e) |
| | if "403 Forbidden" in error_msg and "write token" in error_msg: |
| | return gr.update(value=f"Error: Permission denied. Please ensure you have write access to {repo_id} and your token has the correct permissions.", visible=True) |
| | |
| | if attempt < max_attempts - 1: |
| | time.sleep(2) |
| | finally: |
| | import os |
| | if 'temp_path' in locals(): |
| | os.unlink(temp_path) |
| | |
| | if not success: |
| | return gr.update(value=f"Error uploading {file_name}: {last_error}", visible=True) |
| | |
| | |
| | add_anycoder_tag_to_readme(api, repo_id, app_port=7860) |
| | |
| | space_url = f"https://huggingface.co/spaces/{repo_id}" |
| | action_text = "Updated" if is_update else "Deployed" |
| | return gr.update(value=f"✅ {action_text}! [Open your React Space here]({space_url})", visible=True) |
| | |
| | |
| | files = parse_multi_file_python_output(code) |
| | if not files: |
| | return gr.update(value="Error: Could not parse Streamlit output. Please regenerate the code.", visible=True) |
| | |
| | |
| | has_streamlit_app = 'streamlit_app.py' in files or 'app.py' in files |
| | has_requirements = 'requirements.txt' in files |
| | has_dockerfile = 'Dockerfile' in files |
| | |
| | if not has_streamlit_app: |
| | return gr.update(value="Error: Missing streamlit_app.py. Please regenerate the code.", visible=True) |
| | |
| | |
| | if not has_dockerfile: |
| | |
| | files['Dockerfile'] = """FROM python:3.11-slim |
| | |
| | # Set up user with ID 1000 |
| | RUN useradd -m -u 1000 user |
| | USER user |
| | ENV HOME=/home/user \\ |
| | PATH=/home/user/.local/bin:$PATH |
| | |
| | # Set working directory |
| | WORKDIR $HOME/app |
| | |
| | # Copy requirements file with proper ownership |
| | COPY --chown=user requirements.txt . |
| | |
| | # Install dependencies |
| | RUN pip install --no-cache-dir -r requirements.txt |
| | |
| | # Copy application files with proper ownership |
| | COPY --chown=user . . |
| | |
| | # Expose port 7860 |
| | EXPOSE 7860 |
| | |
| | # Start Streamlit app |
| | CMD ["streamlit", "run", "streamlit_app.py", "--server.port=7860", "--server.address=0.0.0.0"] |
| | """ |
| | |
| | if not has_requirements: |
| | |
| | main_app = files.get('streamlit_app.py') or files.get('app.py', '') |
| | import_statements = extract_import_statements(main_app) |
| | files['requirements.txt'] = generate_requirements_txt_with_llm(import_statements) |
| | |
| | |
| | import tempfile |
| | import time |
| | |
| | for file_name, file_content in files.items(): |
| | if not file_content: |
| | continue |
| | |
| | success = False |
| | last_error = None |
| | max_attempts = 3 |
| | |
| | for attempt in range(max_attempts): |
| | try: |
| | |
| | if file_name == 'Dockerfile': |
| | suffix = '' |
| | else: |
| | suffix = f".{file_name.split('.')[-1]}" |
| | |
| | with tempfile.NamedTemporaryFile("w", suffix=suffix, delete=False) as f: |
| | f.write(file_content) |
| | temp_path = f.name |
| | |
| | api.upload_file( |
| | path_or_fileobj=temp_path, |
| | path_in_repo=file_name, |
| | repo_id=repo_id, |
| | repo_type="space" |
| | ) |
| | success = True |
| | break |
| | |
| | except Exception as e: |
| | last_error = e |
| | error_msg = str(e) |
| | if "403 Forbidden" in error_msg and "write token" in error_msg: |
| | return gr.update(value=f"Error: Permission denied. Please ensure you have write access to {repo_id} and your token has the correct permissions.", visible=True) |
| | |
| | if attempt < max_attempts - 1: |
| | time.sleep(2) |
| | finally: |
| | import os |
| | if 'temp_path' in locals(): |
| | os.unlink(temp_path) |
| | |
| | if not success: |
| | return gr.update(value=f"Error uploading {file_name}: {last_error}", visible=True) |
| | |
| | |
| | add_anycoder_tag_to_readme(api, repo_id, app_port=7860) |
| | |
| | space_url = f"https://huggingface.co/spaces/{repo_id}" |
| | action_text = "Updated" if is_update else "Deployed" |
| | return gr.update(value=f"✅ {action_text}! [Open your Streamlit Space here]({space_url})", visible=True) |
| | |
| | except Exception as e: |
| | error_prefix = "Error duplicating Streamlit space" if not is_update else "Error updating Streamlit space" |
| | return gr.update(value=f"{error_prefix}: {e}", visible=True) |
| | |
| | elif language == "transformers.js": |
| | try: |
| | |
| | if not is_update: |
| | |
| | from huggingface_hub import duplicate_space |
| | |
| | |
| | duplicated_repo = duplicate_space( |
| | from_id="static-templates/transformers.js", |
| | to_id=space_name.strip(), |
| | token=token.token, |
| | exist_ok=True |
| | ) |
| | print("Duplicated repo result:", duplicated_repo, type(duplicated_repo)) |
| | else: |
| | |
| | try: |
| | space_info = api.space_info(repo_id) |
| | if not space_info: |
| | return gr.update(value=f"Error: Could not access space {repo_id} for update.", visible=True) |
| | except Exception as e: |
| | return gr.update(value=f"Error: Cannot update space {repo_id}. {str(e)}", visible=True) |
| | |
| | files = parse_transformers_js_output(code) |
| | |
| | if not files['index.html'] or not files['index.js'] or not files['style.css']: |
| | return gr.update(value="Error: Could not parse transformers.js output. Please regenerate the code.", visible=True) |
| | |
| | |
| | import tempfile |
| | import time |
| | |
| | |
| | files_to_upload = [ |
| | ("index.html", files['index.html']), |
| | ("index.js", files['index.js']), |
| | ("style.css", files['style.css']) |
| | ] |
| | |
| | |
| | max_attempts = 3 |
| | for file_name, file_content in files_to_upload: |
| | success = False |
| | last_error = None |
| | |
| | for attempt in range(max_attempts): |
| | try: |
| | with tempfile.NamedTemporaryFile("w", suffix=f".{file_name.split('.')[-1]}", delete=False) as f: |
| | f.write(file_content) |
| | temp_path = f.name |
| | |
| | api.upload_file( |
| | path_or_fileobj=temp_path, |
| | path_in_repo=file_name, |
| | repo_id=repo_id, |
| | repo_type="space" |
| | ) |
| | success = True |
| | break |
| | |
| | except Exception as e: |
| | last_error = e |
| | error_msg = str(e) |
| | if "403 Forbidden" in error_msg and "write token" in error_msg: |
| | |
| | return gr.update(value=f"Error: Permission denied. Please ensure you have write access to {repo_id} and your token has the correct permissions.", visible=True) |
| | |
| | if attempt < max_attempts - 1: |
| | time.sleep(2) |
| | finally: |
| | import os |
| | if 'temp_path' in locals(): |
| | os.unlink(temp_path) |
| | |
| | if not success: |
| | return gr.update(value=f"Error uploading {file_name}: {last_error}", visible=True) |
| | |
| | |
| | add_anycoder_tag_to_readme(api, repo_id) |
| | |
| | |
| | if is_update: |
| | try: |
| | api.restart_space(repo_id=repo_id) |
| | except Exception as restart_error: |
| | |
| | print(f"Note: Could not restart space after update: {restart_error}") |
| | |
| | space_url = f"https://huggingface.co/spaces/{repo_id}" |
| | action_text = "Updated" if is_update else "Deployed" |
| | return gr.update(value=f"✅ {action_text}! [Open your Transformers.js Space here]({space_url})", visible=True) |
| | |
| | except Exception as e: |
| | |
| | error_msg = str(e) |
| | if "'url'" in error_msg or "RepoUrl" in error_msg: |
| | |
| | try: |
| | |
| | space_url = f"https://huggingface.co/spaces/{repo_id}" |
| | test_api = HfApi(token=token.token) |
| | space_exists = test_api.space_info(repo_id) |
| | |
| | if space_exists and not is_update: |
| | |
| | return gr.update(value=f"✅ Deployed! Space was created successfully despite a technical error. [Open your Transformers.js Space here]({space_url})", visible=True) |
| | elif space_exists and is_update: |
| | |
| | return gr.update(value=f"✅ Updated! Space was updated successfully despite a technical error. [Open your Transformers.js Space here]({space_url})", visible=True) |
| | else: |
| | |
| | return gr.update(value=f"Error: Could not create/update space. Please try again manually at https://huggingface.co/new-space", visible=True) |
| | except: |
| | |
| | repo_url = f"https://huggingface.co/spaces/{repo_id}" |
| | return gr.update(value=f"Error: Could not properly handle space creation response. Space may have been created successfully. Check: {repo_url}", visible=True) |
| | |
| | |
| | action_verb = "updating" if is_update else "duplicating" |
| | return gr.update(value=f"Error {action_verb} Transformers.js space: {error_msg}", visible=True) |
| | |
| | if sdk == "static": |
| | import time |
| | |
| | |
| | add_anycoder_tag_to_readme(api, repo_id) |
| | |
| | |
| | files = {} |
| | parse_error = None |
| | try: |
| | files = parse_multipage_html_output(code) |
| | print(f"[Deploy] Parsed files: {list(files.keys())}") |
| | files = validate_and_autofix_files(files) |
| | print(f"[Deploy] After validation: {list(files.keys())}") |
| | except Exception as e: |
| | parse_error = str(e) |
| | print(f"[Deploy] Parse error: {parse_error}") |
| | files = {} |
| | |
| | |
| | if isinstance(files, dict) and len(files) > 0 and files.get('index.html'): |
| | import tempfile |
| | import os |
| | |
| | try: |
| | with tempfile.TemporaryDirectory() as tmpdir: |
| | |
| | for rel_path, content in files.items(): |
| | safe_rel_path = rel_path.strip().lstrip('/') |
| | abs_path = os.path.join(tmpdir, safe_rel_path) |
| | os.makedirs(os.path.dirname(abs_path), exist_ok=True) |
| | with open(abs_path, 'w') as fh: |
| | fh.write(content) |
| | |
| | |
| | api.upload_folder( |
| | folder_path=tmpdir, |
| | repo_id=repo_id, |
| | repo_type="space" |
| | ) |
| | space_url = f"https://huggingface.co/spaces/{repo_id}" |
| | action_text = "Updated" if is_update else "Deployed" |
| | return gr.update(value=f"✅ {action_text}! [Open your Space here]({space_url})", visible=True) |
| | except Exception as e: |
| | error_msg = str(e) |
| | if "403 Forbidden" in error_msg and "write token" in error_msg: |
| | return gr.update(value=f"Error: Permission denied. Please ensure you have write access to {repo_id} and your token has the correct permissions.", visible=True) |
| | else: |
| | return gr.update(value=f"Error uploading static app folder: {e}", visible=True) |
| | |
| | |
| | file_name = "index.html" |
| | |
| | |
| | if language == "comfyui": |
| | print("[Deploy] Converting ComfyUI JSON to prettified HTML display") |
| | code = prettify_comfyui_json_for_html(code) |
| | |
| | max_attempts = 3 |
| | for attempt in range(max_attempts): |
| | import tempfile |
| | with tempfile.NamedTemporaryFile("w", suffix=".html", delete=False) as f: |
| | f.write(code) |
| | temp_path = f.name |
| | try: |
| | api.upload_file( |
| | path_or_fileobj=temp_path, |
| | path_in_repo=file_name, |
| | repo_id=repo_id, |
| | repo_type="space" |
| | ) |
| | space_url = f"https://huggingface.co/spaces/{repo_id}" |
| | action_text = "Updated" if is_update else "Deployed" |
| | return gr.update(value=f"✅ {action_text}! [Open your Space here]({space_url})", visible=True) |
| | except Exception as e: |
| | error_msg = str(e) |
| | if "403 Forbidden" in error_msg and "write token" in error_msg: |
| | return gr.update(value=f"Error: Permission denied. Please ensure you have write access to {repo_id} and your token has the correct permissions.", visible=True) |
| | elif attempt < max_attempts - 1: |
| | time.sleep(2) |
| | else: |
| | return gr.update(value=f"Error uploading file after {max_attempts} attempts: {e}. Please check your permissions and try again.", visible=True) |
| | finally: |
| | import os |
| | os.unlink(temp_path) |
| | else: |
| | |
| | import_statements = extract_import_statements(code) |
| | requirements_content = generate_requirements_txt_with_llm(import_statements) |
| | |
| | import tempfile |
| | |
| | |
| | should_upload_requirements = True |
| | if is_update: |
| | try: |
| | |
| | existing_requirements = api.hf_hub_download( |
| | repo_id=repo_id, |
| | filename="requirements.txt", |
| | repo_type="space" |
| | ) |
| | with open(existing_requirements, 'r') as f: |
| | existing_content = f.read().strip() |
| | |
| | |
| | if existing_content == requirements_content.strip(): |
| | should_upload_requirements = False |
| | |
| | except Exception: |
| | |
| | should_upload_requirements = True |
| | |
| | |
| | |
| | |
| | |
| | add_anycoder_tag_to_readme(api, repo_id) |
| | |
| | |
| | if ('=== app.py ===' in code or '=== requirements.txt ===' in code): |
| | |
| | files = parse_multi_file_python_output(code) |
| | if files: |
| | |
| | if 'app.py' in files and 'requirements.txt' not in files: |
| | import_statements = extract_import_statements(files['app.py']) |
| | requirements_content = generate_requirements_txt_with_llm(import_statements) |
| | files['requirements.txt'] = requirements_content |
| | try: |
| | from huggingface_hub import CommitOperationAdd |
| | operations = [] |
| | temp_files = [] |
| | |
| | |
| | for filename, content in files.items(): |
| | |
| | cleaned_content = content |
| | if filename.endswith('.txt') or filename.endswith('.py'): |
| | |
| | lines = cleaned_content.split('\n') |
| | clean_lines = [] |
| | for line in lines: |
| | stripped = line.strip() |
| | |
| | if stripped == '```' or (stripped.startswith('```') and len(stripped) <= 10): |
| | continue |
| | clean_lines.append(line) |
| | cleaned_content = '\n'.join(clean_lines) |
| | |
| | |
| | with tempfile.NamedTemporaryFile("w", suffix=f".{filename.split('.')[-1]}", delete=False) as f: |
| | f.write(cleaned_content) |
| | temp_path = f.name |
| | temp_files.append(temp_path) |
| | |
| | |
| | operations.append(CommitOperationAdd( |
| | path_in_repo=filename, |
| | path_or_fileobj=temp_path |
| | )) |
| | |
| | |
| | api.create_commit( |
| | repo_id=repo_id, |
| | operations=operations, |
| | commit_message=f"{'Update' if is_update else 'Deploy'} Gradio app with multiple files", |
| | repo_type="space" |
| | ) |
| | |
| | |
| | for temp_path in temp_files: |
| | try: |
| | os.unlink(temp_path) |
| | except Exception: |
| | pass |
| | |
| | space_url = f"https://huggingface.co/spaces/{repo_id}" |
| | action_text = "Updated" if is_update else "Deployed" |
| | return gr.update(value=f"✅ {action_text}! [Open your Space here]({space_url})", visible=True) |
| | |
| | except Exception as e: |
| | |
| | for temp_path in temp_files: |
| | try: |
| | os.unlink(temp_path) |
| | except Exception: |
| | pass |
| | |
| | error_msg = str(e) |
| | if "403 Forbidden" in error_msg and "write token" in error_msg: |
| | return gr.update(value=f"Error: Permission denied. Please ensure you have write access to {repo_id} and your token has the correct permissions.", visible=True) |
| | else: |
| | return gr.update(value=f"Error uploading multi-file app: {e}", visible=True) |
| | else: |
| | |
| | pass |
| | |
| | |
| | file_name = "app.py" |
| | with tempfile.NamedTemporaryFile("w", suffix=f".{file_name.split('.')[-1]}", delete=False) as f: |
| | f.write(code) |
| | temp_path = f.name |
| | try: |
| | api.upload_file( |
| | path_or_fileobj=temp_path, |
| | path_in_repo=file_name, |
| | repo_id=repo_id, |
| | repo_type="space" |
| | ) |
| | space_url = f"https://huggingface.co/spaces/{repo_id}" |
| | action_text = "Updated" if is_update else "Deployed" |
| | return gr.update(value=f"✅ {action_text}! [Open your Space here]({space_url})", visible=True) |
| | except Exception as e: |
| | error_msg = str(e) |
| | if "403 Forbidden" in error_msg and "write token" in error_msg: |
| | return gr.update(value=f"Error: Permission denied. Please ensure you have write access to {repo_id} and your token has the correct permissions.", visible=True) |
| | else: |
| | return gr.update(value=f"Error uploading file: {e}", visible=True) |
| | finally: |
| | import os |
| | os.unlink(temp_path) |
| |
|
| | |
| | def gather_code_for_deploy(code_text, language, html_part, js_part, css_part): |
| | |
| | if language == "transformers.js": |
| | |
| | files = { |
| | 'index.html': html_part or '', |
| | 'index.js': js_part or '', |
| | 'style.css': css_part or '', |
| | } |
| | if files['index.html'] and files['index.js'] and files['style.css']: |
| | return format_transformers_js_output(files) |
| | return code_text |
| | deploy_btn.click( |
| | gather_code_for_deploy, |
| | inputs=[code_output, language_dropdown, tjs_html_code, tjs_js_code, tjs_css_code], |
| | outputs=[code_output], |
| | queue=False, |
| | ).then( |
| | deploy_with_history_tracking, |
| | inputs=[code_output, language_dropdown, history], |
| | outputs=[deploy_status, history] |
| | ).then( |
| | lambda hist: history_to_chatbot_messages(hist), |
| | inputs=[history], |
| | outputs=[chat_history] |
| | ) |
| | |
| | |
| | |
| | |
| | |
| | def handle_auth_update(profile: Optional[gr.OAuthProfile] = None, token: Optional[gr.OAuthToken] = None): |
| | return update_ui_for_auth_status(profile, token) |
| | |
| | |
| | login_button.click( |
| | handle_auth_update, |
| | inputs=[], |
| | outputs=[input, btn], |
| | queue=False |
| | ) |
| | |
| | |
| | demo.load( |
| | handle_auth_update, |
| | inputs=[], |
| | outputs=[input, btn], |
| | queue=False |
| | ) |
| | |
| | |
| | def load_trending_models(): |
| | """Load trending models from HuggingFace Hub""" |
| | models = get_trending_models(limit=10) |
| | |
| | choices = [(display, model_id) for display, model_id in models] |
| | |
| | default_value = models[0][1] if models and len(models) > 0 and models[0][1] != "" else None |
| | return gr.update(choices=choices, value=default_value) |
| | |
| | demo.load( |
| | load_trending_models, |
| | inputs=[], |
| | outputs=[trending_models_dropdown], |
| | queue=False |
| | ) |
| | |
| | |
| | def load_trending_spaces(): |
| | """Load trending spaces from HuggingFace Hub""" |
| | spaces = get_trending_spaces(limit=10) |
| | |
| | choices = [(display, space_id) for display, space_id in spaces] |
| | |
| | default_value = spaces[0][1] if spaces and len(spaces) > 0 and spaces[0][1] != "" else None |
| | return gr.update(choices=choices, value=default_value) |
| | |
| | demo.load( |
| | load_trending_spaces, |
| | inputs=[], |
| | outputs=[trending_spaces_dropdown], |
| | queue=False |
| | ) |
| | |
| | |
| | def handle_trending_model_selection(model_id, hist, is_first): |
| | """Handle when user selects a trending model""" |
| | |
| | if is_first: |
| | return [ |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | hist, |
| | history_to_chatbot_messages(hist), |
| | history_to_chatbot_messages(hist), |
| | False, |
| | gr.update(visible=False), |
| | "" |
| | ] |
| | |
| | if not model_id or model_id == "": |
| | return [ |
| | gr.update(value="Please select a model.", visible=True), |
| | gr.update(), |
| | gr.update(), |
| | hist, |
| | history_to_chatbot_messages(hist), |
| | history_to_chatbot_messages(hist), |
| | False, |
| | gr.update(visible=False), |
| | "" |
| | ] |
| | |
| | |
| | status, code, language, model_url = import_model_from_hf(model_id) |
| | |
| | |
| | loaded_history = hist + [[f"Imported model: {model_id}", code]] |
| | |
| | |
| | code_lang = "python" |
| | |
| | |
| | show_switch_btn = "Found multiple code options" in status |
| | |
| | return [ |
| | gr.update(value=status, visible=True), |
| | gr.update(value=code, language=code_lang), |
| | gr.update(value=language), |
| | loaded_history, |
| | history_to_chatbot_messages(loaded_history), |
| | history_to_chatbot_messages(loaded_history), |
| | False, |
| | gr.update(visible=show_switch_btn), |
| | model_id |
| | ] |
| | |
| | trending_models_dropdown.change( |
| | handle_trending_model_selection, |
| | inputs=[trending_models_dropdown, history, models_first_change], |
| | outputs=[ |
| | trending_models_status, |
| | code_output, |
| | language_dropdown, |
| | history, |
| | history_output, |
| | chat_history, |
| | models_first_change, |
| | switch_model_code_btn, |
| | current_trending_model_id |
| | ] |
| | ) |
| | |
| | |
| | def handle_switch_model_code(model_id, current_code, hist): |
| | """Switch between inference provider and local transformers/diffusers code""" |
| | if not model_id: |
| | return [ |
| | gr.update(), |
| | gr.update(), |
| | hist, |
| | history_to_chatbot_messages(hist), |
| | history_to_chatbot_messages(hist) |
| | ] |
| | |
| | status_msg, new_code = switch_model_code_type(model_id, current_code) |
| | |
| | |
| | switch_history = hist + [[f"Switched code type for {model_id}", new_code]] |
| | |
| | return [ |
| | gr.update(value=status_msg, visible=True), |
| | gr.update(value=new_code, language="python"), |
| | switch_history, |
| | history_to_chatbot_messages(switch_history), |
| | history_to_chatbot_messages(switch_history) |
| | ] |
| | |
| | switch_model_code_btn.click( |
| | handle_switch_model_code, |
| | inputs=[current_trending_model_id, code_output, history], |
| | outputs=[ |
| | trending_models_status, |
| | code_output, |
| | history, |
| | history_output, |
| | chat_history |
| | ] |
| | ) |
| | |
| | |
| | def handle_trending_space_selection(space_id, hist, is_first): |
| | """Handle when user selects a trending space""" |
| | |
| | if is_first: |
| | return [ |
| | gr.update(), |
| | gr.update(), |
| | gr.update(), |
| | hist, |
| | history_to_chatbot_messages(hist), |
| | history_to_chatbot_messages(hist), |
| | gr.update(), |
| | False |
| | ] |
| | |
| | if not space_id or space_id == "": |
| | return [ |
| | gr.update(value="Please select a space.", visible=True), |
| | gr.update(), |
| | gr.update(), |
| | hist, |
| | history_to_chatbot_messages(hist), |
| | history_to_chatbot_messages(hist), |
| | gr.update(visible=True), |
| | False |
| | ] |
| | |
| | |
| | status, code, language, space_url = import_space_from_hf(space_id) |
| | |
| | |
| | loaded_history = hist + [[f"Imported space: {space_id}", code]] |
| | |
| | |
| | if language == "gradio" or language == "streamlit": |
| | code_lang = "python" |
| | elif language == "transformers.js": |
| | code_lang = "html" |
| | else: |
| | code_lang = "html" |
| | |
| | return [ |
| | gr.update(value=status, visible=True), |
| | gr.update(value=code, language=code_lang), |
| | gr.update(value=language), |
| | loaded_history, |
| | history_to_chatbot_messages(loaded_history), |
| | history_to_chatbot_messages(loaded_history), |
| | gr.update(value="Publish", visible=True), |
| | False |
| | ] |
| | |
| | trending_spaces_dropdown.change( |
| | handle_trending_space_selection, |
| | inputs=[trending_spaces_dropdown, history, spaces_first_change], |
| | outputs=[ |
| | trending_spaces_status, |
| | code_output, |
| | language_dropdown, |
| | history, |
| | history_output, |
| | chat_history, |
| | deploy_btn, |
| | spaces_first_change |
| | ] |
| | ) |
| |
|
| |
|