MySafeCode commited on
Commit
ee2e3a0
·
verified ·
1 Parent(s): c85a928

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -533
app.py CHANGED
@@ -1,150 +1,44 @@
1
  import gradio as gr
2
  import requests
3
  import os
4
-
5
  import json
6
 
7
  # Suno API key
 
8
  if not SUNO_KEY:
9
  print("⚠️ SunoKey not set!")
10
 
11
  def submit_song_generation(lyrics_text, style, title, instrumental, model):
12
- """Submit song generation request - IMMEDIATE RESPONSE WITH TASK ID"""
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
  if not SUNO_KEY:
124
- return "❌ Error: SunoKey not configured", ""
125
-
126
 
127
  if not lyrics_text.strip() and not instrumental:
128
- return "❌ Error: Please provide lyrics or select instrumental", ""
129
-
130
 
131
  if not style.strip():
132
- return "❌ Error: Please provide a music style", ""
133
-
134
 
135
  if not title.strip():
136
- return "❌ Error: Please provide a song title", ""
137
-
138
 
139
  try:
140
  # Prepare request data
 
 
 
 
 
 
 
 
 
 
141
  # Apply character limits
142
  if model == "V4" and len(lyrics_text) > 3000:
143
  lyrics_text = lyrics_text[:3000]
144
-
145
  elif model in ["V4_5", "V4_5PLUS", "V4_5ALL", "V5"] and len(lyrics_text) > 5000:
146
  lyrics_text = lyrics_text[:5000]
147
-
148
 
149
  request_data["prompt"] = lyrics_text
150
  else:
@@ -161,426 +55,39 @@ def submit_song_generation(lyrics_text, style, title, instrumental, model):
161
  timeout=30
162
  )
163
 
 
 
 
164
  if resp.status_code != 200:
165
- return f"❌ Submission failed: HTTP {resp.status_code}\n\n{resp.text}", ""
166
-
167
-
168
-
169
-
170
-
171
 
172
  data = resp.json()
173
-
174
 
175
- # Extract task ID - IMMEDIATELY
176
  task_id = None
177
-
178
-
179
-
180
-
181
-
182
-
183
-
184
- # Try different response formats
185
  if "taskId" in data:
186
  task_id = data["taskId"]
 
 
187
  elif "data" in data and "taskId" in data["data"]:
188
  task_id = data["data"]["taskId"]
 
 
189
  elif data.get("data") and "taskId" in data.get("data", {}):
190
  task_id = data["data"]["taskId"]
191
-
192
- if not task_id:
193
- return f"❌ Could not extract Task ID\n\n**Raw:**\n```json\n{json.dumps(data, indent=2)}\n```", ""
194
-
195
- # RETURN TASK ID IMMEDIATELY
196
- output = f"## ✅ TASK SUBMITTED!\n\n"
197
- output += f"**🎯 YOUR TASK ID:** `{task_id}`\n\n"
198
- output += f"**📋 Details:**\n"
199
- output += f"- **Title:** {title}\n"
200
- output += f"- **Style:** {style}\n"
201
- output += f"- **Model:** {model}\n"
202
- output += f"- **Instrumental:** {'Yes' if instrumental else 'No'}\n\n"
203
-
204
- output += f"**🚀 Next Steps:**\n"
205
- output += f"1. **Copy this Task ID:** `{task_id}`\n"
206
- output += f"2. **Switch to 'Check Status' tab**\n"
207
- output += f"3. **Paste the Task ID**\n"
208
- output += f"4. **Click 'Check Status'** for results\n\n"
209
-
210
- output += f"**⏱️ Processing time:** 1-3 minutes\n"
211
- output += f"**📞 Callback URL:** https://1hit.no/callback.php\n"
212
-
213
- return output, task_id
214
-
215
- except Exception as e:
216
- return f"❌ Error: {str(e)}", ""
217
-
218
- def check_song_status(task_id, show_raw=False):
219
- """Check song generation status - RETURNS DOWNLOAD LINKS"""
220
- if not task_id:
221
- return "❌ Please enter a Task ID", ""
222
-
223
- try:
224
- resp = requests.get(
225
- "https://api.sunoapi.org/api/v1/generate/record-info",
226
- headers={"Authorization": f"Bearer {SUNO_KEY}"},
227
- params={"taskId": task_id},
228
- timeout=30
229
- )
230
-
231
- if resp.status_code != 200:
232
- return f"❌ HTTP Error {resp.status_code}\n\n{resp.text}", ""
233
-
234
- data = resp.json()
235
-
236
- # RAW JSON for debugging (always stored, shown if requested)
237
- raw_json = f"```json\n{json.dumps(data, indent=2)}\n```"
238
-
239
- if data.get("code") != 200:
240
- return f"❌ API Error: {data.get('msg', 'Unknown')}", raw_json
241
-
242
- task_data = data.get("data", {})
243
- status = task_data.get("status", "UNKNOWN")
244
-
245
- # Format main output
246
- output = f"## 🔍 Status Check: `{task_id}`\n\n"
247
- output += f"**Status:** {status}\n"
248
-
249
- if status == "TEXT_SUCCESS":
250
- # This is the key status! Songs are ready!
251
- response_data = task_data.get("response", {})
252
- songs = response_data.get("sunoData", [])
253
-
254
- if not songs:
255
- output += f"\n**⚠️ Status TEXT_SUCCESS but no songs found**\n"
256
- output += f"Raw data available in dropdown below\n"
257
- return output, raw_json
258
-
259
- output += f"## 🎵 SONGS READY! ({len(songs)} tracks)\n\n"
260
-
261
-
262
-
263
- for i, song in enumerate(songs, 1):
264
- output += f"### Track {i}\n"
265
- output += f"**Title:** {song.get('title', 'Untitled')}\n"
266
-
267
- # Get all possible URLs
268
- audio_url = song.get('audioUrl')
269
- stream_url = song.get('streamAudioUrl') or song.get('streamAudioURL') or song.get('stream_url')
270
- source_stream = song.get('sourceStreamAudioUrl')
271
- source_audio = song.get('sourceAudioUrl')
272
-
273
- # Image URL
274
- image_url = song.get('imageUrl') or song.get('sourceImageUrl')
275
-
276
- # Best URL for listening
277
- best_url = audio_url or stream_url or source_stream or source_audio
278
-
279
- if best_url:
280
- output += f"**🎧 Listen Now:** [Click to Play]({best_url})\n"
281
- # Audio player
282
- output += f"""<audio controls style="width: 100%; margin: 10px 0;">
283
- <source src="{best_url}" type="audio/mpeg">
284
- Your browser does not support audio.
285
- </audio>\n"""
286
-
287
- # Download button
288
- if audio_url:
289
- output += f"**💾 Download:** [MP3 File]({audio_url})\n"
290
- elif stream_url:
291
- output += f"**💾 Download:** [Stream MP3]({stream_url})\n"
292
-
293
- if image_url:
294
- output += f"**🖼️ Cover Art:** [View Image]({image_url})\n"
295
-
296
- output += f"**ID:** `{song.get('id', 'N/A')}`\n"
297
- output += f"**Model:** {song.get('modelName', 'N/A')}\n"
298
- output += f"**Tags:** {song.get('tags', 'N/A')}\n"
299
- if song.get('duration'):
300
- output += f"**Duration:** {song.get('duration')}s\n"
301
-
302
- # Show first 200 chars of prompt
303
- prompt = song.get('prompt', '')
304
- if prompt:
305
- output += f"**Preview:** {prompt[:200]}...\n"
306
-
307
- output += "\n---\n\n"
308
-
309
- # Summary
310
- output += f"**✅ Generation complete!**\n\n"
311
- output += "**To save your songs:**\n"
312
- output += "1. Right-click 'Listen Now' links → 'Save link as...'\n"
313
- output += "2. Or use the download links above\n"
314
- output += "3. Note the Track IDs for reference\n"
315
-
316
- elif status in ["PENDING", "PROCESSING", "RUNNING"]:
317
- output += f"\n**⏳ Song is still being generated...**\n"
318
- output += "Check again in 30-60 seconds\n"
319
- output += f"This usually takes 1-3 minutes total\n"
320
-
321
-
322
-
323
-
324
-
325
-
326
-
327
-
328
-
329
-
330
-
331
-
332
-
333
-
334
-
335
-
336
- elif status == "SUCCESS":
337
- output += f"\n**✅ Generation succeeded!**\n"
338
- output += "Check raw data below for song URLs\n"
339
-
340
- elif status == "FAILED":
341
- error_msg = task_data.get("errorMessage", "Unknown error")
342
- output += f"\n**❌ Generation failed:** {error_msg}\n"
343
-
344
-
345
  else:
346
- output += f"\n**⚠️ Unknown status:** {status}\n"
347
- output += "Check raw data below\n"
348
-
349
- # Always show premium info
350
- output += f"\n**💡 Tip:** Songs may take 2-3 minutes to fully process\n"
351
- output += f"**📞 Callback sent to:** https://1hit.no/callback.php\n"
352
- output += f"**🔗 Viewer:** [https://1hit.no/viewer.php?task_id={task_id}](https://1hit.no/viewer.php?task_id={task_id})\n"
353
-
354
- return output, raw_json
355
-
356
- except Exception as e:
357
- return f" Error checking task: {str(e)}", ""
358
-
359
- # Create the app
360
- with gr.Blocks() as app:
361
- gr.Markdown("# 🎵 Suno Song Generator")
362
-
363
- # Store current task ID
364
- current_task_id = gr.State(value="")
365
-
366
- with gr.Tab("🎶 Generate Song"):
367
- with gr.Row():
368
- with gr.Column(scale=1):
369
- # Inputs
370
-
371
-
372
- lyrics_text = gr.Textbox(
373
- label="Lyrics (leave empty for instrumental)",
374
- placeholder="[Verse 1]\nType your lyrics here...",
375
- lines=8
376
-
377
- )
378
-
379
-
380
-
381
-
382
- style = gr.Textbox(
383
- label="Music Style",
384
-
385
- value="Pop",
386
- placeholder="e.g., Rock, Jazz, Electronic"
387
- )
388
-
389
- title = gr.Textbox(
390
- label="Song Title",
391
- value="My Song"
392
-
393
-
394
- )
395
-
396
- with gr.Row():
397
- instrumental = gr.Checkbox(label="Instrumental Only")
398
-
399
-
400
-
401
-
402
- model = gr.Dropdown(
403
-
404
- choices=["V5", "V4_5PLUS", "V4_5ALL", "V4_5", "V4"],
405
- value="V4_5ALL",
406
- label="Model"
407
- )
408
-
409
- submit_btn = gr.Button("🚀 Generate Song", variant="primary")
410
-
411
-
412
-
413
-
414
- gr.Markdown("""
415
- **Instructions:**
416
- 1. Enter lyrics (or blank for instrumental)
417
- 2. Set style & title
418
- 3. Click Generate
419
- 4. **Copy the Task ID**
420
- 5. Check status in next tab
421
-
422
-
423
-
424
-
425
-
426
- """)
427
-
428
- with gr.Column(scale=2):
429
- # Submission output
430
- submission_output = gr.Markdown(
431
- value="### Ready to generate!\n\nFill in the form and click 'Generate Song'"
432
- )
433
-
434
- with gr.Tab("🔍 Check Status"):
435
- with gr.Row():
436
- with gr.Column(scale=1):
437
- gr.Markdown("### Check Song Status")
438
-
439
-
440
- # Task ID input (auto-fills from generation)
441
- status_task_id = gr.Textbox(
442
- label="Task ID",
443
- placeholder="Paste your Task ID here",
444
- info="Will auto-fill from generated task"
445
- )
446
-
447
- check_btn = gr.Button("🔍 Check Status Now", variant="primary")
448
- auto_check = gr.Checkbox(label="Auto-check every 30s", value=False)
449
-
450
- gr.Markdown("""
451
- **What to expect:**
452
- - **TEXT_SUCCESS**: Songs ready! Listen/download
453
- - **PENDING/PROCESSING**: Still generating
454
- - Check every 30s until ready
455
- """)
456
-
457
- with gr.Column(scale=2):
458
- # Status output
459
- status_output = gr.Markdown(
460
- value="### Enter a Task ID to check status"
461
- )
462
-
463
- # Raw data in accordion
464
- with gr.Accordion("📊 Raw API Response (Debug)", open=False):
465
- raw_output = gr.Markdown(
466
- value="*Raw JSON will appear here when you check status*"
467
- )
468
-
469
- with gr.Tab("📋 Instructions"):
470
- gr.Markdown("""
471
- ## 🎵 Complete Workflow
472
-
473
-
474
-
475
-
476
-
477
-
478
-
479
-
480
-
481
-
482
-
483
-
484
-
485
-
486
-
487
-
488
-
489
-
490
-
491
-
492
-
493
- ### 1. Generate Song
494
- - Enter lyrics & settings
495
- - Click **Generate Song**
496
- - **IMMEDIATELY get a Task ID**
497
- - Copy the Task ID
498
-
499
- ### 2. Check Status
500
- - Switch to **Check Status** tab
501
- - Task ID auto-fills
502
- - Click **Check Status Now**
503
- - Wait for **TEXT_SUCCESS** status
504
-
505
- ### 3. Download Songs
506
- - When **TEXT_SUCCESS** appears:
507
- - **Listen Now** links with audio players
508
- - **Download** links for MP3 files
509
- - Cover art images
510
- - Track IDs for reference
511
-
512
- ### 4. Tips
513
- - Processing: **1-3 minutes**
514
- - Check every **30 seconds**
515
- - Use **Auto-check** for convenience
516
- - Raw data available for debugging
517
-
518
- ### 5. Status Meanings
519
- - **TEXT_SUCCESS**: ✅ Songs ready!
520
- - **PENDING/PROCESSING**: ⏳ Still working
521
- - **SUCCESS**: Check raw data
522
- - **FAILED**: Try again
523
-
524
- ### 6. Callback System
525
- - Results also sent to: https://1hit.no/callback.php
526
- - View all results: https://1hit.no/viewer.php
527
-
528
- """)
529
-
530
- # Auto-fill status tab with task ID
531
- def update_status_field(task_id):
532
- return task_id
533
-
534
-
535
-
536
-
537
-
538
-
539
-
540
-
541
-
542
-
543
-
544
-
545
-
546
- current_task_id.change(
547
- fn=update_status_field,
548
- inputs=[current_task_id],
549
- outputs=[status_task_id]
550
- )
551
-
552
- # Generate song
553
- def on_generate(lyrics, style, title, instrumental, model):
554
- output, task_id = submit_song_generation(lyrics, style, title, instrumental, model)
555
- if task_id:
556
- return output, task_id, task_id # Also updates status_task_id
557
- return output, "", "" # Clear if error
558
-
559
- submit_btn.click(
560
- fn=on_generate,
561
- inputs=[lyrics_text, style, title, instrumental, model],
562
- outputs=[submission_output, current_task_id, status_task_id]
563
- )
564
-
565
- # Check status
566
- def on_check(task_id, show_raw):
567
- output, raw = check_song_status(task_id, show_raw)
568
- return output, raw
569
-
570
-
571
-
572
-
573
-
574
- check_btn.click(
575
- fn=on_check,
576
- inputs=[status_task_id, gr.State(True)], # Always show raw
577
- outputs=[status_output, raw_output]
578
- )
579
-
580
-
581
- if __name__ == "__main__":
582
- print("🚀 Starting Suno Song Generator")
583
- print(f"🔑 SunoKey: {'✅ Set' if SUNO_KEY else '❌ Not set'}")
584
- print("🌐 Open your browser to: http://localhost:7860")
585
-
586
- app.launch(server_name="0.0.0.0", server_port=7860, share=False)
 
1
  import gradio as gr
2
  import requests
3
  import os
 
4
  import json
5
 
6
  # Suno API key
7
+ SUNO_KEY = os.environ.get("SunoKey", "")
8
  if not SUNO_KEY:
9
  print("⚠️ SunoKey not set!")
10
 
11
  def submit_song_generation(lyrics_text, style, title, instrumental, model):
12
+ """Submit song generation request and return Task ID immediately"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  if not SUNO_KEY:
14
+ return "❌ Error: SunoKey not configured in environment variables"
 
15
 
16
  if not lyrics_text.strip() and not instrumental:
17
+ return "❌ Error: Please provide lyrics or select instrumental"
 
18
 
19
  if not style.strip():
20
+ return "❌ Error: Please provide a music style"
 
21
 
22
  if not title.strip():
23
+ return "❌ Error: Please provide a song title"
 
24
 
25
  try:
26
  # Prepare request data
27
+ request_data = {
28
+ "customMode": True,
29
+ "instrumental": instrumental,
30
+ "model": model,
31
+ "callBackUrl": "https://1hit.no/callback.php",
32
+ "style": style,
33
+ "title": title,
34
+ }
35
+
36
+ if not instrumental:
37
  # Apply character limits
38
  if model == "V4" and len(lyrics_text) > 3000:
39
  lyrics_text = lyrics_text[:3000]
 
40
  elif model in ["V4_5", "V4_5PLUS", "V4_5ALL", "V5"] and len(lyrics_text) > 5000:
41
  lyrics_text = lyrics_text[:5000]
 
42
 
43
  request_data["prompt"] = lyrics_text
44
  else:
 
55
  timeout=30
56
  )
57
 
58
+ print(f"Submission response: {resp.status_code}")
59
+ print(f"Response: {resp.text}")
60
+
61
  if resp.status_code != 200:
62
+ return f"❌ Submission failed: HTTP {resp.status_code}\n\n{resp.text}"
 
 
 
 
 
63
 
64
  data = resp.json()
65
+ print(f"Parsed data: {data}")
66
 
67
+ # Extract task ID from response
68
  task_id = None
 
 
 
 
 
 
 
 
69
  if "taskId" in data:
70
  task_id = data["taskId"]
71
+ output = f"## ✅ TASK SUBMITTED SUCCESSFULLY!\n\n"
72
+ output += f"**🎯 Your Task ID:** `{task_id}`\n\n"
73
  elif "data" in data and "taskId" in data["data"]:
74
  task_id = data["data"]["taskId"]
75
+ output = f"## ✅ TASK SUBMITTED SUCCESSFULLY!\n\n"
76
+ output += f"**🎯 Your Task ID:** `{task_id}`\n\n"
77
  elif data.get("data") and "taskId" in data.get("data", {}):
78
  task_id = data["data"]["taskId"]
79
+ output = f"## ✅ TASK SUBMITTED SUCCESSFULLY!\n\n"
80
+ output += f"**🎯 Your Task ID:** `{task_id}`\n\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  else:
82
+ return f"❌ Could not extract Task ID from response\n\n**Raw Response:**\n```json\n{json.dumps(data, indent=2)}\n```"
83
+
84
+ output += f"**📱 What to do with this Task ID:**\n\n"
85
+ output += "1. **Copy this Task ID:** `" + task_id + "`\n"
86
+ output += "2. **Switch to the 'Check Any Task' tab**\n"
87
+ output += "3. **Paste the Task ID** in the input field\n"
88
+ output += "4. **Click 'Check Status'** to see your song results\n\n"
89
+
90
+ output += "**⏱️ What happens now:**\n"
91
+ output += "- Suno AI is generating your song (1-3 minutes)\n"
92
+ output += "- You can check status anytime with the Task ID\n"
93
+ output += "- When ready, you'll see audio URLs