Spaces:
Running
Running
update transformers js
Browse files
app.py
CHANGED
|
@@ -58,6 +58,71 @@ Always respond with code that can be executed or rendered directly.
|
|
| 58 |
|
| 59 |
Always output only the HTML code inside a ```html ... ``` code block, and do not include any explanations or extra text. Do NOT add the language name at the top of the code output."""
|
| 60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
GENERIC_SYSTEM_PROMPT = """You are an expert {language} developer. Write clean, idiomatic, and runnable {language} code for the user's request. If possible, include comments and best practices. Output ONLY the code inside a ``` code block, and do not include any explanations or extra text. If the user provides a file or other context, use it as a reference. If the code is for a script or app, make it as self-contained as possible. Do NOT add the language name at the top of the code output."""
|
| 62 |
|
| 63 |
# System prompt with search capability
|
|
@@ -222,6 +287,10 @@ DEMO_LIST = [
|
|
| 222 |
{
|
| 223 |
"title": "Search/Replace Example",
|
| 224 |
"description": "Generate HTML first, then ask: 'Change the title to My New Title' or 'Add a blue background to the body'"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
}
|
| 226 |
]
|
| 227 |
|
|
@@ -331,6 +400,47 @@ def remove_code_block(text):
|
|
| 331 |
return lines[1] if len(lines) > 1 else ''
|
| 332 |
return text.strip()
|
| 333 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
def history_render(history: History):
|
| 335 |
return gr.update(visible=True), history
|
| 336 |
|
|
@@ -980,6 +1090,8 @@ def generation_code(query: Optional[str], image: Optional[gr.Image], file: Optio
|
|
| 980 |
# Use language-specific prompt
|
| 981 |
if language == "html":
|
| 982 |
system_prompt = HTML_SYSTEM_PROMPT_WITH_SEARCH if enable_search else HTML_SYSTEM_PROMPT
|
|
|
|
|
|
|
| 983 |
else:
|
| 984 |
system_prompt = GENERIC_SYSTEM_PROMPT_WITH_SEARCH.format(language=language) if enable_search else GENERIC_SYSTEM_PROMPT.format(language=language)
|
| 985 |
|
|
@@ -1040,35 +1152,75 @@ This will help me create a better design for you."""
|
|
| 1040 |
chunk.choices[0].delta.content is not None
|
| 1041 |
):
|
| 1042 |
content += chunk.choices[0].delta.content
|
| 1043 |
-
clean_code = remove_code_block(content)
|
| 1044 |
search_status = " (with web search)" if enable_search and tavily_client else ""
|
| 1045 |
-
|
| 1046 |
-
|
| 1047 |
-
|
|
|
|
|
|
|
|
|
|
| 1048 |
yield {
|
| 1049 |
-
code_output: gr.update(value=
|
| 1050 |
history_output: history_to_chatbot_messages(_history),
|
| 1051 |
-
sandbox: send_to_sandbox(
|
| 1052 |
}
|
| 1053 |
else:
|
| 1054 |
-
|
| 1055 |
-
modified_html = apply_search_replace_changes(last_html, clean_code)
|
| 1056 |
-
clean_html = remove_code_block(modified_html)
|
| 1057 |
yield {
|
| 1058 |
-
code_output: gr.update(value=
|
| 1059 |
history_output: history_to_chatbot_messages(_history),
|
| 1060 |
-
sandbox:
|
| 1061 |
}
|
| 1062 |
else:
|
| 1063 |
-
|
| 1064 |
-
|
| 1065 |
-
|
| 1066 |
-
|
| 1067 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1068 |
# Skip chunks with empty choices (end of stream)
|
| 1069 |
# Do not treat as error
|
| 1070 |
# Handle response based on whether this is a modification or new generation
|
| 1071 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1072 |
# Fallback: If the model returns a full HTML file, use it directly
|
| 1073 |
final_code = remove_code_block(content)
|
| 1074 |
if final_code.strip().startswith("<!DOCTYPE html>") or final_code.strip().startswith("<html"):
|
|
@@ -1186,7 +1338,7 @@ with gr.Blocks(
|
|
| 1186 |
)
|
| 1187 |
# Language dropdown for code generation
|
| 1188 |
language_choices = [
|
| 1189 |
-
"html", "python", "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"
|
| 1190 |
]
|
| 1191 |
language_dropdown = gr.Dropdown(
|
| 1192 |
choices=language_choices,
|
|
@@ -1222,7 +1374,8 @@ with gr.Blocks(
|
|
| 1222 |
sdk_choices = [
|
| 1223 |
("Gradio (Python)", "gradio"),
|
| 1224 |
("Streamlit (Python)", "streamlit"),
|
| 1225 |
-
("Static (HTML)", "static")
|
|
|
|
| 1226 |
]
|
| 1227 |
sdk_dropdown = gr.Dropdown(
|
| 1228 |
choices=[x[0] for x in sdk_choices],
|
|
@@ -1293,11 +1446,27 @@ with gr.Blocks(
|
|
| 1293 |
def update_code_language(language):
|
| 1294 |
return gr.update(language=get_gradio_language(language))
|
| 1295 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1296 |
language_dropdown.change(update_code_language, inputs=language_dropdown, outputs=code_output)
|
|
|
|
| 1297 |
|
| 1298 |
def preview_logic(code, language):
|
| 1299 |
if language == "html":
|
| 1300 |
return send_to_sandbox(code)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1301 |
else:
|
| 1302 |
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>"
|
| 1303 |
|
|
@@ -1342,7 +1511,8 @@ with gr.Blocks(
|
|
| 1342 |
sdk_map = {
|
| 1343 |
"Gradio (Python)": "gradio",
|
| 1344 |
"Streamlit (Python)": "docker", # Use 'docker' for Streamlit Spaces
|
| 1345 |
-
"Static (HTML)": "static"
|
|
|
|
| 1346 |
}
|
| 1347 |
sdk = sdk_map.get(sdk_name, "gradio")
|
| 1348 |
api = HfApi(token=token.token)
|
|
@@ -1394,6 +1564,87 @@ with gr.Blocks(
|
|
| 1394 |
|
| 1395 |
except Exception as e:
|
| 1396 |
return gr.update(value=f"Error duplicating Streamlit space: {e}", visible=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1397 |
# Other SDKs (existing logic)
|
| 1398 |
if sdk == "static":
|
| 1399 |
file_name = "index.html"
|
|
|
|
| 58 |
|
| 59 |
Always output only the HTML code inside a ```html ... ``` code block, and do not include any explanations or extra text. Do NOT add the language name at the top of the code output."""
|
| 60 |
|
| 61 |
+
TRANSFORMERS_JS_SYSTEM_PROMPT = """You are an expert web developer creating a transformers.js application. You will generate THREE separate files: index.html, index.js, and style.css.
|
| 62 |
+
|
| 63 |
+
IMPORTANT: You MUST output ALL THREE files in the following format:
|
| 64 |
+
|
| 65 |
+
```html
|
| 66 |
+
<!-- index.html content here -->
|
| 67 |
+
```
|
| 68 |
+
|
| 69 |
+
```javascript
|
| 70 |
+
// index.js content here
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
```css
|
| 74 |
+
/* style.css content here */
|
| 75 |
+
```
|
| 76 |
+
|
| 77 |
+
Requirements:
|
| 78 |
+
1. Create a modern, responsive web application using transformers.js
|
| 79 |
+
2. Use the transformers.js library for AI/ML functionality
|
| 80 |
+
3. Create a clean, professional UI with good user experience
|
| 81 |
+
4. Make the application fully responsive for mobile devices
|
| 82 |
+
5. Use modern CSS practices and JavaScript ES6+ features
|
| 83 |
+
6. Include proper error handling and loading states
|
| 84 |
+
7. Follow accessibility best practices
|
| 85 |
+
|
| 86 |
+
The index.html should contain the basic HTML structure and link to the CSS and JS files.
|
| 87 |
+
The index.js should contain all the JavaScript logic including transformers.js integration.
|
| 88 |
+
The style.css should contain all the styling for the application.
|
| 89 |
+
|
| 90 |
+
Always output only the three code blocks as shown above, and do not include any explanations or extra text."""
|
| 91 |
+
|
| 92 |
+
TRANSFORMERS_JS_SYSTEM_PROMPT_WITH_SEARCH = """You are an expert web developer creating a transformers.js application. You have access to real-time web search. When needed, use web search to find the latest information, best practices, or specific technologies for transformers.js.
|
| 93 |
+
|
| 94 |
+
You will generate THREE separate files: index.html, index.js, and style.css.
|
| 95 |
+
|
| 96 |
+
IMPORTANT: You MUST output ALL THREE files in the following format:
|
| 97 |
+
|
| 98 |
+
```html
|
| 99 |
+
<!-- index.html content here -->
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
```javascript
|
| 103 |
+
// index.js content here
|
| 104 |
+
```
|
| 105 |
+
|
| 106 |
+
```css
|
| 107 |
+
/* style.css content here */
|
| 108 |
+
```
|
| 109 |
+
|
| 110 |
+
Requirements:
|
| 111 |
+
1. Create a modern, responsive web application using transformers.js
|
| 112 |
+
2. Use the transformers.js library for AI/ML functionality
|
| 113 |
+
3. Use web search to find current best practices and latest transformers.js features
|
| 114 |
+
4. Create a clean, professional UI with good user experience
|
| 115 |
+
5. Make the application fully responsive for mobile devices
|
| 116 |
+
6. Use modern CSS practices and JavaScript ES6+ features
|
| 117 |
+
7. Include proper error handling and loading states
|
| 118 |
+
8. Follow accessibility best practices
|
| 119 |
+
|
| 120 |
+
The index.html should contain the basic HTML structure and link to the CSS and JS files.
|
| 121 |
+
The index.js should contain all the JavaScript logic including transformers.js integration.
|
| 122 |
+
The style.css should contain all the styling for the application.
|
| 123 |
+
|
| 124 |
+
Always output only the three code blocks as shown above, and do not include any explanations or extra text."""
|
| 125 |
+
|
| 126 |
GENERIC_SYSTEM_PROMPT = """You are an expert {language} developer. Write clean, idiomatic, and runnable {language} code for the user's request. If possible, include comments and best practices. Output ONLY the code inside a ``` code block, and do not include any explanations or extra text. If the user provides a file or other context, use it as a reference. If the code is for a script or app, make it as self-contained as possible. Do NOT add the language name at the top of the code output."""
|
| 127 |
|
| 128 |
# System prompt with search capability
|
|
|
|
| 287 |
{
|
| 288 |
"title": "Search/Replace Example",
|
| 289 |
"description": "Generate HTML first, then ask: 'Change the title to My New Title' or 'Add a blue background to the body'"
|
| 290 |
+
},
|
| 291 |
+
{
|
| 292 |
+
"title": "Transformers.js App",
|
| 293 |
+
"description": "Create a transformers.js application with AI/ML functionality using the transformers.js library"
|
| 294 |
}
|
| 295 |
]
|
| 296 |
|
|
|
|
| 400 |
return lines[1] if len(lines) > 1 else ''
|
| 401 |
return text.strip()
|
| 402 |
|
| 403 |
+
def parse_transformers_js_output(text):
|
| 404 |
+
"""Parse transformers.js output and extract the three files (index.html, index.js, style.css)"""
|
| 405 |
+
files = {
|
| 406 |
+
'index.html': '',
|
| 407 |
+
'index.js': '',
|
| 408 |
+
'style.css': ''
|
| 409 |
+
}
|
| 410 |
+
|
| 411 |
+
# Patterns to match the three code blocks
|
| 412 |
+
html_pattern = r'```html\s*\n([\s\S]+?)\n```'
|
| 413 |
+
js_pattern = r'```javascript\s*\n([\s\S]+?)\n```'
|
| 414 |
+
css_pattern = r'```css\s*\n([\s\S]+?)\n```'
|
| 415 |
+
|
| 416 |
+
# Extract HTML content
|
| 417 |
+
html_match = re.search(html_pattern, text, re.IGNORECASE)
|
| 418 |
+
if html_match:
|
| 419 |
+
files['index.html'] = html_match.group(1).strip()
|
| 420 |
+
|
| 421 |
+
# Extract JavaScript content
|
| 422 |
+
js_match = re.search(js_pattern, text, re.IGNORECASE)
|
| 423 |
+
if js_match:
|
| 424 |
+
files['index.js'] = js_match.group(1).strip()
|
| 425 |
+
|
| 426 |
+
# Extract CSS content
|
| 427 |
+
css_match = re.search(css_pattern, text, re.IGNORECASE)
|
| 428 |
+
if css_match:
|
| 429 |
+
files['style.css'] = css_match.group(1).strip()
|
| 430 |
+
|
| 431 |
+
return files
|
| 432 |
+
|
| 433 |
+
def format_transformers_js_output(files):
|
| 434 |
+
"""Format the three files into a single display string"""
|
| 435 |
+
output = []
|
| 436 |
+
output.append("=== index.html ===")
|
| 437 |
+
output.append(files['index.html'])
|
| 438 |
+
output.append("\n=== index.js ===")
|
| 439 |
+
output.append(files['index.js'])
|
| 440 |
+
output.append("\n=== style.css ===")
|
| 441 |
+
output.append(files['style.css'])
|
| 442 |
+
return '\n'.join(output)
|
| 443 |
+
|
| 444 |
def history_render(history: History):
|
| 445 |
return gr.update(visible=True), history
|
| 446 |
|
|
|
|
| 1090 |
# Use language-specific prompt
|
| 1091 |
if language == "html":
|
| 1092 |
system_prompt = HTML_SYSTEM_PROMPT_WITH_SEARCH if enable_search else HTML_SYSTEM_PROMPT
|
| 1093 |
+
elif language == "transformers.js":
|
| 1094 |
+
system_prompt = TRANSFORMERS_JS_SYSTEM_PROMPT_WITH_SEARCH if enable_search else TRANSFORMERS_JS_SYSTEM_PROMPT
|
| 1095 |
else:
|
| 1096 |
system_prompt = GENERIC_SYSTEM_PROMPT_WITH_SEARCH.format(language=language) if enable_search else GENERIC_SYSTEM_PROMPT.format(language=language)
|
| 1097 |
|
|
|
|
| 1152 |
chunk.choices[0].delta.content is not None
|
| 1153 |
):
|
| 1154 |
content += chunk.choices[0].delta.content
|
|
|
|
| 1155 |
search_status = " (with web search)" if enable_search and tavily_client else ""
|
| 1156 |
+
|
| 1157 |
+
# Handle transformers.js output differently
|
| 1158 |
+
if language == "transformers.js":
|
| 1159 |
+
files = parse_transformers_js_output(content)
|
| 1160 |
+
if files['index.html'] and files['index.js'] and files['style.css']:
|
| 1161 |
+
formatted_output = format_transformers_js_output(files)
|
| 1162 |
yield {
|
| 1163 |
+
code_output: gr.update(value=formatted_output, language="html"),
|
| 1164 |
history_output: history_to_chatbot_messages(_history),
|
| 1165 |
+
sandbox: send_to_sandbox(files['index.html']) if files['index.html'] else "<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>",
|
| 1166 |
}
|
| 1167 |
else:
|
| 1168 |
+
# Still streaming, show partial content
|
|
|
|
|
|
|
| 1169 |
yield {
|
| 1170 |
+
code_output: gr.update(value=content, language="html"),
|
| 1171 |
history_output: history_to_chatbot_messages(_history),
|
| 1172 |
+
sandbox: "<div style='padding:1em;color:#888;text-align:center;'>Generating transformers.js app...</div>",
|
| 1173 |
}
|
| 1174 |
else:
|
| 1175 |
+
clean_code = remove_code_block(content)
|
| 1176 |
+
if has_existing_html:
|
| 1177 |
+
# Fallback: If the model returns a full HTML file, use it directly
|
| 1178 |
+
if clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html"):
|
| 1179 |
+
yield {
|
| 1180 |
+
code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
|
| 1181 |
+
history_output: history_to_chatbot_messages(_history),
|
| 1182 |
+
sandbox: send_to_sandbox(clean_code) if language == "html" else "<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>",
|
| 1183 |
+
}
|
| 1184 |
+
else:
|
| 1185 |
+
last_html = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
|
| 1186 |
+
modified_html = apply_search_replace_changes(last_html, clean_code)
|
| 1187 |
+
clean_html = remove_code_block(modified_html)
|
| 1188 |
+
yield {
|
| 1189 |
+
code_output: gr.update(value=clean_html, language=get_gradio_language(language)),
|
| 1190 |
+
history_output: history_to_chatbot_messages(_history),
|
| 1191 |
+
sandbox: send_to_sandbox(clean_html) if language == "html" else "<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>",
|
| 1192 |
+
}
|
| 1193 |
+
else:
|
| 1194 |
+
yield {
|
| 1195 |
+
code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
|
| 1196 |
+
history_output: history_to_chatbot_messages(_history),
|
| 1197 |
+
sandbox: send_to_sandbox(clean_code) if language == "html" else "<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>",
|
| 1198 |
+
}
|
| 1199 |
# Skip chunks with empty choices (end of stream)
|
| 1200 |
# Do not treat as error
|
| 1201 |
# Handle response based on whether this is a modification or new generation
|
| 1202 |
+
if language == "transformers.js":
|
| 1203 |
+
# Handle transformers.js output
|
| 1204 |
+
files = parse_transformers_js_output(content)
|
| 1205 |
+
if files['index.html'] and files['index.js'] and files['style.css']:
|
| 1206 |
+
formatted_output = format_transformers_js_output(files)
|
| 1207 |
+
_history.append([query, formatted_output])
|
| 1208 |
+
yield {
|
| 1209 |
+
code_output: formatted_output,
|
| 1210 |
+
history: _history,
|
| 1211 |
+
sandbox: send_to_sandbox(files['index.html']),
|
| 1212 |
+
history_output: history_to_chatbot_messages(_history),
|
| 1213 |
+
}
|
| 1214 |
+
else:
|
| 1215 |
+
# Fallback if parsing failed
|
| 1216 |
+
_history.append([query, content])
|
| 1217 |
+
yield {
|
| 1218 |
+
code_output: content,
|
| 1219 |
+
history: _history,
|
| 1220 |
+
sandbox: "<div style='padding:1em;color:#888;text-align:center;'>Error parsing transformers.js output. Please try again.</div>",
|
| 1221 |
+
history_output: history_to_chatbot_messages(_history),
|
| 1222 |
+
}
|
| 1223 |
+
elif has_existing_html:
|
| 1224 |
# Fallback: If the model returns a full HTML file, use it directly
|
| 1225 |
final_code = remove_code_block(content)
|
| 1226 |
if final_code.strip().startswith("<!DOCTYPE html>") or final_code.strip().startswith("<html"):
|
|
|
|
| 1338 |
)
|
| 1339 |
# Language dropdown for code generation
|
| 1340 |
language_choices = [
|
| 1341 |
+
"html", "python", "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", "transformers.js"
|
| 1342 |
]
|
| 1343 |
language_dropdown = gr.Dropdown(
|
| 1344 |
choices=language_choices,
|
|
|
|
| 1374 |
sdk_choices = [
|
| 1375 |
("Gradio (Python)", "gradio"),
|
| 1376 |
("Streamlit (Python)", "streamlit"),
|
| 1377 |
+
("Static (HTML)", "static"),
|
| 1378 |
+
("Transformers.js", "transformers.js")
|
| 1379 |
]
|
| 1380 |
sdk_dropdown = gr.Dropdown(
|
| 1381 |
choices=[x[0] for x in sdk_choices],
|
|
|
|
| 1446 |
def update_code_language(language):
|
| 1447 |
return gr.update(language=get_gradio_language(language))
|
| 1448 |
|
| 1449 |
+
def update_sdk_based_on_language(language):
|
| 1450 |
+
if language == "transformers.js":
|
| 1451 |
+
return gr.update(value="Transformers.js")
|
| 1452 |
+
elif language == "html":
|
| 1453 |
+
return gr.update(value="Static (HTML)")
|
| 1454 |
+
else:
|
| 1455 |
+
return gr.update(value="Gradio (Python)")
|
| 1456 |
+
|
| 1457 |
language_dropdown.change(update_code_language, inputs=language_dropdown, outputs=code_output)
|
| 1458 |
+
language_dropdown.change(update_sdk_based_on_language, inputs=language_dropdown, outputs=sdk_dropdown)
|
| 1459 |
|
| 1460 |
def preview_logic(code, language):
|
| 1461 |
if language == "html":
|
| 1462 |
return send_to_sandbox(code)
|
| 1463 |
+
elif language == "transformers.js":
|
| 1464 |
+
# For transformers.js, extract the HTML part for preview
|
| 1465 |
+
files = parse_transformers_js_output(code)
|
| 1466 |
+
if files['index.html']:
|
| 1467 |
+
return send_to_sandbox(files['index.html'])
|
| 1468 |
+
else:
|
| 1469 |
+
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>"
|
| 1470 |
else:
|
| 1471 |
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>"
|
| 1472 |
|
|
|
|
| 1511 |
sdk_map = {
|
| 1512 |
"Gradio (Python)": "gradio",
|
| 1513 |
"Streamlit (Python)": "docker", # Use 'docker' for Streamlit Spaces
|
| 1514 |
+
"Static (HTML)": "static",
|
| 1515 |
+
"Transformers.js": "static" # Transformers.js uses static SDK
|
| 1516 |
}
|
| 1517 |
sdk = sdk_map.get(sdk_name, "gradio")
|
| 1518 |
api = HfApi(token=token.token)
|
|
|
|
| 1564 |
|
| 1565 |
except Exception as e:
|
| 1566 |
return gr.update(value=f"Error duplicating Streamlit space: {e}", visible=True)
|
| 1567 |
+
# Transformers.js logic
|
| 1568 |
+
elif sdk_name == "Transformers.js":
|
| 1569 |
+
try:
|
| 1570 |
+
# Use duplicate_space to create a transformers.js template space
|
| 1571 |
+
from huggingface_hub import duplicate_space
|
| 1572 |
+
|
| 1573 |
+
# Duplicate the transformers.js template space
|
| 1574 |
+
duplicated_repo = duplicate_space(
|
| 1575 |
+
from_id="static-templates/transformers.js",
|
| 1576 |
+
to_id=space_name.strip(),
|
| 1577 |
+
token=token.token,
|
| 1578 |
+
exist_ok=True
|
| 1579 |
+
)
|
| 1580 |
+
|
| 1581 |
+
# Parse the transformers.js output to get the three files
|
| 1582 |
+
files = parse_transformers_js_output(code)
|
| 1583 |
+
|
| 1584 |
+
if not files['index.html'] or not files['index.js'] or not files['style.css']:
|
| 1585 |
+
return gr.update(value="Error: Could not parse transformers.js output. Please regenerate the code.", visible=True)
|
| 1586 |
+
|
| 1587 |
+
# Upload the three files to the duplicated space
|
| 1588 |
+
import tempfile
|
| 1589 |
+
|
| 1590 |
+
# Upload index.html
|
| 1591 |
+
with tempfile.NamedTemporaryFile("w", suffix=".html", delete=False) as f:
|
| 1592 |
+
f.write(files['index.html'])
|
| 1593 |
+
temp_path = f.name
|
| 1594 |
+
|
| 1595 |
+
try:
|
| 1596 |
+
api.upload_file(
|
| 1597 |
+
path_or_fileobj=temp_path,
|
| 1598 |
+
path_in_repo="index.html",
|
| 1599 |
+
repo_id=repo_id,
|
| 1600 |
+
repo_type="space"
|
| 1601 |
+
)
|
| 1602 |
+
except Exception as e:
|
| 1603 |
+
return gr.update(value=f"Error uploading index.html: {e}", visible=True)
|
| 1604 |
+
finally:
|
| 1605 |
+
import os
|
| 1606 |
+
os.unlink(temp_path)
|
| 1607 |
+
|
| 1608 |
+
# Upload index.js
|
| 1609 |
+
with tempfile.NamedTemporaryFile("w", suffix=".js", delete=False) as f:
|
| 1610 |
+
f.write(files['index.js'])
|
| 1611 |
+
temp_path = f.name
|
| 1612 |
+
|
| 1613 |
+
try:
|
| 1614 |
+
api.upload_file(
|
| 1615 |
+
path_or_fileobj=temp_path,
|
| 1616 |
+
path_in_repo="index.js",
|
| 1617 |
+
repo_id=repo_id,
|
| 1618 |
+
repo_type="space"
|
| 1619 |
+
)
|
| 1620 |
+
except Exception as e:
|
| 1621 |
+
return gr.update(value=f"Error uploading index.js: {e}", visible=True)
|
| 1622 |
+
finally:
|
| 1623 |
+
import os
|
| 1624 |
+
os.unlink(temp_path)
|
| 1625 |
+
|
| 1626 |
+
# Upload style.css
|
| 1627 |
+
with tempfile.NamedTemporaryFile("w", suffix=".css", delete=False) as f:
|
| 1628 |
+
f.write(files['style.css'])
|
| 1629 |
+
temp_path = f.name
|
| 1630 |
+
|
| 1631 |
+
try:
|
| 1632 |
+
api.upload_file(
|
| 1633 |
+
path_or_fileobj=temp_path,
|
| 1634 |
+
path_in_repo="style.css",
|
| 1635 |
+
repo_id=repo_id,
|
| 1636 |
+
repo_type="space"
|
| 1637 |
+
)
|
| 1638 |
+
space_url = f"https://huggingface.co/spaces/{repo_id}"
|
| 1639 |
+
return gr.update(value=f"✅ Deployed! [Open your Transformers.js Space here]({space_url})", visible=True)
|
| 1640 |
+
except Exception as e:
|
| 1641 |
+
return gr.update(value=f"Error uploading style.css: {e}", visible=True)
|
| 1642 |
+
finally:
|
| 1643 |
+
import os
|
| 1644 |
+
os.unlink(temp_path)
|
| 1645 |
+
|
| 1646 |
+
except Exception as e:
|
| 1647 |
+
return gr.update(value=f"Error duplicating Transformers.js space: {e}", visible=True)
|
| 1648 |
# Other SDKs (existing logic)
|
| 1649 |
if sdk == "static":
|
| 1650 |
file_name = "index.html"
|