Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -51,8 +51,10 @@ def export_file(data: typing.Dict[str, typing.Any]) -> typing.Optional[str]:
|
|
| 51 |
"""μν¬νλ‘μ°λ₯Ό JSON νμΌλ‘ λ΄λ³΄λ΄κΈ°"""
|
| 52 |
if not data:
|
| 53 |
return None
|
| 54 |
-
|
| 55 |
try:
|
|
|
|
|
|
|
| 56 |
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
| 57 |
json.dump(data, f, ensure_ascii=False, indent=2)
|
| 58 |
return path
|
|
@@ -848,6 +850,11 @@ CSS = """
|
|
| 848 |
display:grid;grid-template-columns:1fr 1fr;gap:0.5rem;
|
| 849 |
margin-top:0.5rem;
|
| 850 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 851 |
"""
|
| 852 |
|
| 853 |
# -------------------------------------------------------------------
|
|
@@ -878,6 +885,7 @@ with gr.Blocks(title="π MOUSE Workflow", theme=gr.themes.Soft(), css=CSS) as
|
|
| 878 |
**Libraries:**
|
| 879 |
- OpenAI: {'β
Installed' if OPENAI_AVAILABLE else 'β Not installed'}
|
| 880 |
- Requests: {'β
Installed' if REQUESTS_AVAILABLE else 'β Not installed'}
|
|
|
|
| 881 |
|
| 882 |
**Available Models:**
|
| 883 |
- OpenAI: gpt-4.1-mini (fixed)
|
|
@@ -957,7 +965,62 @@ with gr.Blocks(title="π MOUSE Workflow", theme=gr.themes.Soft(), css=CSS) as
|
|
| 957 |
)
|
| 958 |
with gr.Column(scale=1):
|
| 959 |
btn_preview = gr.Button("ποΈ Preview JSON", size="lg")
|
| 960 |
-
btn_download = gr.DownloadButton(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 961 |
|
| 962 |
# βββ UI Execution Section βββ
|
| 963 |
with gr.Column(elem_classes=["ui-execution-section"]):
|
|
@@ -1182,9 +1245,17 @@ with gr.Blocks(title="π MOUSE Workflow", theme=gr.themes.Soft(), css=CSS) as
|
|
| 1182 |
)
|
| 1183 |
|
| 1184 |
# Download workflow
|
| 1185 |
-
|
| 1186 |
-
|
| 1187 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1188 |
)
|
| 1189 |
|
| 1190 |
# Generate UI execution
|
|
@@ -1201,6 +1272,97 @@ with gr.Blocks(title="π MOUSE Workflow", theme=gr.themes.Soft(), css=CSS) as
|
|
| 1201 |
outputs=export_preview
|
| 1202 |
)
|
| 1203 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1204 |
|
| 1205 |
# -------------------------------------------------------------------
|
| 1206 |
# π μ€ν
|
|
|
|
| 51 |
"""μν¬νλ‘μ°λ₯Ό JSON νμΌλ‘ λ΄λ³΄λ΄κΈ°"""
|
| 52 |
if not data:
|
| 53 |
return None
|
| 54 |
+
|
| 55 |
try:
|
| 56 |
+
# μμ νμΌ μμ±
|
| 57 |
+
fd, path = tempfile.mkstemp(suffix=".json", prefix="workflow_", text=True)
|
| 58 |
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
| 59 |
json.dump(data, f, ensure_ascii=False, indent=2)
|
| 60 |
return path
|
|
|
|
| 850 |
display:grid;grid-template-columns:1fr 1fr;gap:0.5rem;
|
| 851 |
margin-top:0.5rem;
|
| 852 |
}
|
| 853 |
+
.deploy-section{
|
| 854 |
+
background:linear-gradient(135deg,#fef3c7 0%,#fde68a 100%);
|
| 855 |
+
padding:24px;border-radius:12px;margin:24px 0;
|
| 856 |
+
border:1px solid #fbbf24;
|
| 857 |
+
}
|
| 858 |
"""
|
| 859 |
|
| 860 |
# -------------------------------------------------------------------
|
|
|
|
| 885 |
**Libraries:**
|
| 886 |
- OpenAI: {'β
Installed' if OPENAI_AVAILABLE else 'β Not installed'}
|
| 887 |
- Requests: {'β
Installed' if REQUESTS_AVAILABLE else 'β Not installed'}
|
| 888 |
+
- Hugging Face Hub: {'β
Installed' if HF_HUB_AVAILABLE else 'β Not installed (needed for deployment)'}
|
| 889 |
|
| 890 |
**Available Models:**
|
| 891 |
- OpenAI: gpt-4.1-mini (fixed)
|
|
|
|
| 965 |
)
|
| 966 |
with gr.Column(scale=1):
|
| 967 |
btn_preview = gr.Button("ποΈ Preview JSON", size="lg")
|
| 968 |
+
btn_download = gr.DownloadButton(
|
| 969 |
+
"πΎ Download JSON",
|
| 970 |
+
size="lg",
|
| 971 |
+
visible=True
|
| 972 |
+
)
|
| 973 |
+
|
| 974 |
+
# βββ Deploy Section βββ
|
| 975 |
+
with gr.Accordion("π Deploy to Hugging Face Space", open=False, elem_classes=["deploy-section"]):
|
| 976 |
+
gr.Markdown("""
|
| 977 |
+
Deploy your workflow as an independent Hugging Face Space app.
|
| 978 |
+
This will create a standalone application that anyone can use without the workflow builder.
|
| 979 |
+
""")
|
| 980 |
+
|
| 981 |
+
with gr.Row():
|
| 982 |
+
with gr.Column(scale=2):
|
| 983 |
+
deploy_name = gr.Textbox(
|
| 984 |
+
label="App Name",
|
| 985 |
+
placeholder="My Awesome Workflow App",
|
| 986 |
+
value="My Workflow App"
|
| 987 |
+
)
|
| 988 |
+
deploy_description = gr.Textbox(
|
| 989 |
+
label="App Description",
|
| 990 |
+
placeholder="Describe what your workflow does...",
|
| 991 |
+
lines=3,
|
| 992 |
+
value="A workflow application created with MOUSE Workflow builder."
|
| 993 |
+
)
|
| 994 |
+
deploy_space_name = gr.Textbox(
|
| 995 |
+
label="Space Name (your-username/space-name)",
|
| 996 |
+
placeholder="username/my-workflow-app",
|
| 997 |
+
info="This will be the URL of your Space"
|
| 998 |
+
)
|
| 999 |
+
|
| 1000 |
+
with gr.Column(scale=1):
|
| 1001 |
+
deploy_token = gr.Textbox(
|
| 1002 |
+
label="Hugging Face Token",
|
| 1003 |
+
type="password",
|
| 1004 |
+
placeholder="hf_...",
|
| 1005 |
+
info="Get your token from huggingface.co/settings/tokens"
|
| 1006 |
+
)
|
| 1007 |
+
deploy_private = gr.Checkbox(
|
| 1008 |
+
label="Make Space Private",
|
| 1009 |
+
value=False
|
| 1010 |
+
)
|
| 1011 |
+
|
| 1012 |
+
btn_deploy = gr.Button("π Deploy to HF Space", variant="primary", size="lg")
|
| 1013 |
+
|
| 1014 |
+
# Deploy status
|
| 1015 |
+
deploy_status = gr.Markdown("")
|
| 1016 |
+
|
| 1017 |
+
# Preview generated code
|
| 1018 |
+
with gr.Accordion("π Preview Generated Code", open=False):
|
| 1019 |
+
generated_code_preview = gr.Code(
|
| 1020 |
+
language="python",
|
| 1021 |
+
label="app.py (This will be deployed)",
|
| 1022 |
+
lines=20
|
| 1023 |
+
)
|
| 1024 |
|
| 1025 |
# βββ UI Execution Section βββ
|
| 1026 |
with gr.Column(elem_classes=["ui-execution-section"]):
|
|
|
|
| 1245 |
)
|
| 1246 |
|
| 1247 |
# Download workflow
|
| 1248 |
+
def prepare_download(data):
|
| 1249 |
+
"""λ€μ΄λ‘λλ₯Ό μν νμΌ μ€λΉ"""
|
| 1250 |
+
if not data:
|
| 1251 |
+
return None
|
| 1252 |
+
return export_file(data)
|
| 1253 |
+
|
| 1254 |
+
# Download λ²νΌμ νμΌ μ°κ²°
|
| 1255 |
+
loaded_data.change(
|
| 1256 |
+
fn=prepare_download,
|
| 1257 |
+
inputs=loaded_data,
|
| 1258 |
+
outputs=btn_download
|
| 1259 |
)
|
| 1260 |
|
| 1261 |
# Generate UI execution
|
|
|
|
| 1272 |
outputs=export_preview
|
| 1273 |
)
|
| 1274 |
|
| 1275 |
+
# βββ Deploy Event Handlers βββ
|
| 1276 |
+
|
| 1277 |
+
# Preview generated code
|
| 1278 |
+
def preview_generated_code(workflow_data, app_name, app_description):
|
| 1279 |
+
if not workflow_data:
|
| 1280 |
+
return "No workflow loaded"
|
| 1281 |
+
|
| 1282 |
+
try:
|
| 1283 |
+
code = generate_standalone_app(workflow_data, app_name, app_description)
|
| 1284 |
+
return code
|
| 1285 |
+
except Exception as e:
|
| 1286 |
+
return f"Error generating code: {str(e)}"
|
| 1287 |
+
|
| 1288 |
+
# Update preview when inputs change
|
| 1289 |
+
deploy_name.change(
|
| 1290 |
+
fn=preview_generated_code,
|
| 1291 |
+
inputs=[loaded_data, deploy_name, deploy_description],
|
| 1292 |
+
outputs=generated_code_preview
|
| 1293 |
+
)
|
| 1294 |
+
|
| 1295 |
+
deploy_description.change(
|
| 1296 |
+
fn=preview_generated_code,
|
| 1297 |
+
inputs=[loaded_data, deploy_name, deploy_description],
|
| 1298 |
+
outputs=generated_code_preview
|
| 1299 |
+
)
|
| 1300 |
+
|
| 1301 |
+
loaded_data.change(
|
| 1302 |
+
fn=preview_generated_code,
|
| 1303 |
+
inputs=[loaded_data, deploy_name, deploy_description],
|
| 1304 |
+
outputs=generated_code_preview
|
| 1305 |
+
)
|
| 1306 |
+
|
| 1307 |
+
# Deploy handler
|
| 1308 |
+
def handle_deploy(workflow_data, app_name, app_description, hf_token, space_name, is_private):
|
| 1309 |
+
if not workflow_data:
|
| 1310 |
+
return "β No workflow loaded. Please load a workflow first."
|
| 1311 |
+
|
| 1312 |
+
if not hf_token:
|
| 1313 |
+
return "β Hugging Face token is required. Get yours at huggingface.co/settings/tokens"
|
| 1314 |
+
|
| 1315 |
+
if not space_name:
|
| 1316 |
+
return "β Space name is required. Format: username/space-name"
|
| 1317 |
+
|
| 1318 |
+
# Validate space name format
|
| 1319 |
+
if "/" not in space_name:
|
| 1320 |
+
return "β Invalid space name format. Use: username/space-name"
|
| 1321 |
+
|
| 1322 |
+
# Check if huggingface-hub is available
|
| 1323 |
+
if not HF_HUB_AVAILABLE:
|
| 1324 |
+
return "β huggingface-hub library not installed. Install with: pip install huggingface-hub"
|
| 1325 |
+
|
| 1326 |
+
# Show deploying status
|
| 1327 |
+
yield "π Deploying to Hugging Face Space..."
|
| 1328 |
+
|
| 1329 |
+
# Deploy
|
| 1330 |
+
result = deploy_to_huggingface(
|
| 1331 |
+
workflow_data=workflow_data,
|
| 1332 |
+
app_name=app_name,
|
| 1333 |
+
app_description=app_description,
|
| 1334 |
+
hf_token=hf_token,
|
| 1335 |
+
space_name=space_name,
|
| 1336 |
+
is_private=is_private
|
| 1337 |
+
)
|
| 1338 |
+
|
| 1339 |
+
if result["success"]:
|
| 1340 |
+
yield f"""β
**Deployment Successful!**
|
| 1341 |
+
|
| 1342 |
+
π Your workflow has been deployed to:
|
| 1343 |
+
[{result['space_url']}]({result['space_url']})
|
| 1344 |
+
|
| 1345 |
+
β±οΈ The Space will be ready in a few minutes. Building usually takes 2-5 minutes.
|
| 1346 |
+
|
| 1347 |
+
π **Next Steps:**
|
| 1348 |
+
1. Visit your Space URL
|
| 1349 |
+
2. Wait for the build to complete
|
| 1350 |
+
3. Share the URL with others
|
| 1351 |
+
4. You can edit the code directly on Hugging Face if needed
|
| 1352 |
+
|
| 1353 |
+
π‘ **Tip:** Set your API keys as secrets in the Space settings:
|
| 1354 |
+
- FRIENDLI_TOKEN (for VIDraft)
|
| 1355 |
+
- OPENAI_API_KEY (for OpenAI)
|
| 1356 |
+
"""
|
| 1357 |
+
else:
|
| 1358 |
+
yield f"β **Deployment Failed**\n\nError: {result['error']}"
|
| 1359 |
+
|
| 1360 |
+
btn_deploy.click(
|
| 1361 |
+
fn=handle_deploy,
|
| 1362 |
+
inputs=[loaded_data, deploy_name, deploy_description, deploy_token, deploy_space_name, deploy_private],
|
| 1363 |
+
outputs=deploy_status
|
| 1364 |
+
)
|
| 1365 |
+
|
| 1366 |
|
| 1367 |
# -------------------------------------------------------------------
|
| 1368 |
# π μ€ν
|