MySafeCode commited on
Commit
1df9cee
·
verified ·
1 Parent(s): ddba688

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +234 -20
app.py CHANGED
@@ -89,14 +89,19 @@ def generate_lyrics(prompt):
89
  output += "---\n\n"
90
 
91
  output += f"⏱️ Generated in about {(attempt + 1) * 5} seconds"
92
- yield output
 
 
 
 
 
93
  else:
94
- yield "✅ Completed but no lyrics found in response"
95
  return
96
 
97
  elif status == "FAILED":
98
  error = check_data["data"].get("errorMessage", "Unknown error")
99
- yield f"❌ Task failed: {error}"
100
  return
101
 
102
  else:
@@ -104,50 +109,239 @@ def generate_lyrics(prompt):
104
  yield (f"⏳ Status: {status}\n"
105
  f"Attempt: {attempt + 1}/30\n"
106
  f"Task ID: `{task_id}`\n\n"
107
- f"Still processing... (Usually takes 30-90 seconds)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  else:
109
  yield f"⚠️ Check error: HTTP {check.status_code}"
110
 
111
  except Exception as e:
112
  yield f"⚠️ Error checking status: {str(e)}"
113
 
114
- yield "⏰ Timeout after 150 seconds. Try checking again later."
115
 
116
  except Exception as e:
117
- yield f"❌ Error: {str(e)}"
118
 
119
  # Create the app
120
- with gr.Blocks(title="Suno Lyrics Generator", theme="soft") as app:
121
- gr.Markdown("# 🎵 Suno Lyrics Generator")
122
- gr.Markdown("Generate song lyrics using Suno AI")
 
 
 
123
 
124
  with gr.Row():
125
  with gr.Column(scale=1):
 
 
126
  prompt = gr.Textbox(
127
  label="Lyrics Prompt",
128
  placeholder="Example: A happy song about sunshine and rainbows",
129
  lines=3
130
  )
131
- btn = gr.Button("🎵 Generate Lyrics", variant="primary", scale=1)
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  gr.Markdown("""
134
  **How it works:**
135
- 1. Enter your lyrics idea
136
- 2. Click Generate
137
- 3. Wait 30-90 seconds
138
- 4. Get 2 lyric variants
 
 
 
139
 
140
  **Status messages:**
141
  - ✅ Submitted = Task accepted
142
- - ⏳ PENDING/PROCESSING = Generating
143
- - 🎵 Success = Lyrics ready!
144
  """)
145
 
146
  with gr.Column(scale=2):
147
  output = gr.Markdown(
148
  label="Results",
149
- value="Your generated lyrics will appear here..."
150
  )
 
151
  gr.Markdown("---")
152
  gr.Markdown(
153
  """
@@ -155,15 +349,35 @@ with gr.Blocks(title="Suno Lyrics Generator", theme="soft") as app:
155
  <p>Powered by <a href="https://suno.ai" target="_blank">Suno AI</a> •
156
  <a href="https://sunoapi.org" target="_blank">Suno API Docs</a> •
157
  <a href="https://github.com" target="_blank">GitHub</a></p>
158
- <p><small>This app uses the Suno API to generate AI-powered lyrics.</small></p>
159
  </div>
160
  """,
161
  elem_id="footer"
162
  )
163
 
164
- btn.click(generate_lyrics, prompt, output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
  if __name__ == "__main__":
167
- print("🚀 Starting Suno Lyrics Generator")
168
  print(f"🔑 SunoKey: {'✅ Set' if SUNO_KEY else '❌ Not set'}")
169
  app.launch(server_name="0.0.0.0", server_port=7860, share=False)
 
89
  output += "---\n\n"
90
 
91
  output += f"⏱️ Generated in about {(attempt + 1) * 5} seconds"
92
+ # Store lyrics for potential song generation
93
+ lyrics_info = {
94
+ "lyrics_list": lyrics_list,
95
+ "original_prompt": prompt
96
+ }
97
+ yield output, lyrics_info
98
  else:
99
+ yield "✅ Completed but no lyrics found in response", None
100
  return
101
 
102
  elif status == "FAILED":
103
  error = check_data["data"].get("errorMessage", "Unknown error")
104
+ yield f"❌ Task failed: {error}", None
105
  return
106
 
107
  else:
 
109
  yield (f"⏳ Status: {status}\n"
110
  f"Attempt: {attempt + 1}/30\n"
111
  f"Task ID: `{task_id}`\n\n"
112
+ f"Still processing... (Usually takes 30-90 seconds)"), None
113
+ else:
114
+ yield f"⚠️ Check error: HTTP {check.status_code}", None
115
+
116
+ except Exception as e:
117
+ yield f"⚠️ Error checking status: {str(e)}", None
118
+
119
+ yield "⏰ Timeout after 150 seconds. Try checking again later.", None
120
+
121
+ except Exception as e:
122
+ yield f"❌ Error: {str(e)}", None
123
+
124
+ def generate_song(lyrics_info, variant_choice, style, title, instrumental, model, custom_mode):
125
+ """Generate a song from lyrics"""
126
+ if not SUNO_KEY:
127
+ return "❌ Error: SunoKey not configured in environment variables"
128
+
129
+ if lyrics_info is None:
130
+ return "❌ Error: No lyrics available. Please generate lyrics first."
131
+
132
+ if not lyrics_info.get("lyrics_list"):
133
+ return "❌ Error: No lyrics found in the provided data."
134
+
135
+ try:
136
+ # Get selected lyrics variant
137
+ variant_idx = int(variant_choice.split(":")[0]) - 1 # Convert "1: Title" to 0-index
138
+ lyrics_list = lyrics_info["lyrics_list"]
139
+
140
+ if variant_idx >= len(lyrics_list):
141
+ return f"❌ Error: Invalid variant selection. Only {len(lyrics_list)} variants available."
142
+
143
+ selected_lyric = lyrics_list[variant_idx]
144
+ lyrics_text = selected_lyric.get('text', '')
145
+ lyrics_title = selected_lyric.get('title', f'Variant {variant_idx + 1}')
146
+
147
+ if not lyrics_text.strip():
148
+ return "❌ Error: Selected lyrics variant has no text content."
149
+
150
+ # Prepare request data based on custom mode
151
+ request_data = {
152
+ "customMode": custom_mode,
153
+ "instrumental": instrumental,
154
+ "model": model,
155
+ "callBackUrl": "http://dummy.com/callback", # Required but not used
156
+ }
157
+
158
+ if custom_mode:
159
+ # Custom mode requires style and title
160
+ if not style.strip():
161
+ return "❌ Error: Style is required in Custom Mode"
162
+ if not title.strip():
163
+ return "❌ Error: Title is required in Custom Mode"
164
+
165
+ request_data["style"] = style
166
+ request_data["title"] = title
167
+
168
+ if not instrumental:
169
+ # Non-instrumental requires lyrics as prompt
170
+ if len(lyrics_text) > 5000 and model in ["V4_5", "V4_5PLUS", "V4_5ALL", "V5"]:
171
+ lyrics_text = lyrics_text[:5000]
172
+ elif len(lyrics_text) > 3000 and model == "V4":
173
+ lyrics_text = lyrics_text[:3000]
174
+ request_data["prompt"] = lyrics_text
175
+ else:
176
+ # Non-custom mode only requires prompt (max 500 chars)
177
+ if len(lyrics_text) > 500:
178
+ lyrics_text = lyrics_text[:497] + "..."
179
+ request_data["prompt"] = lyrics_text
180
+ # Clear other fields for non-custom mode
181
+ request_data["style"] = ""
182
+ request_data["title"] = ""
183
+
184
+ # Submit generation request
185
+ resp = requests.post(
186
+ "https://api.sunoapi.org/api/v1/generate",
187
+ json=request_data,
188
+ headers={
189
+ "Authorization": f"Bearer {SUNO_KEY}",
190
+ "Content-Type": "application/json"
191
+ },
192
+ timeout=30
193
+ )
194
+
195
+ if resp.status_code != 200:
196
+ return f"❌ Submission failed: HTTP {resp.status_code}"
197
+
198
+ data = resp.json()
199
+ if data.get("code") != 200:
200
+ return f"❌ API error: {data.get('msg', 'Unknown')}"
201
+
202
+ task_id = data["data"]["taskId"]
203
+
204
+ # Poll for results
205
+ for attempt in range(60): # 60 attempts * 5 seconds = 300 seconds max (5 minutes)
206
+ time.sleep(5)
207
+
208
+ try:
209
+ check = requests.get(
210
+ "https://api.sunoapi.org/api/v1/music-info",
211
+ headers={"Authorization": f"Bearer {SUNO_KEY}"},
212
+ params={"taskId": task_id},
213
+ timeout=30
214
+ )
215
+
216
+ if check.status_code == 200:
217
+ check_data = check.json()
218
+ status = check_data["data"].get("status", "PENDING")
219
+
220
+ if status == "COMPLETE":
221
+ # Success! Extract song URLs
222
+ songs = check_data["data"].get("songs", [])
223
+ if songs:
224
+ output = "🎶 **Song Generation Complete!**\n\n"
225
+ for i, song in enumerate(songs, 1):
226
+ song_title = song.get('title', f'Song {i}')
227
+ stream_url = song.get('streamUrl', 'No URL')
228
+ download_url = song.get('downloadUrl', 'No URL')
229
+
230
+ output += f"## Song {i}: {song_title}\n"
231
+ output += f"**Stream URL:** {stream_url}\n\n"
232
+ output += f"**Download URL:** {download_url}\n\n"
233
+ output += f"**Listen Now:** [Click to Stream]({stream_url})\n\n"
234
+ output += "---\n\n"
235
+
236
+ output += f"⏱️ Generated in about {(attempt + 1) * 5} seconds\n\n"
237
+ output += "⚠️ **Note:** Files are retained for 15 days"
238
+ return output
239
+ else:
240
+ return "✅ Completed but no songs found in response"
241
+
242
+ elif status == "FAILED":
243
+ error = check_data["data"].get("errorMessage", "Unknown error")
244
+ return f"❌ Task failed: {error}"
245
+
246
+ else:
247
+ # Still processing
248
+ if attempt % 6 == 0: # Update every 30 seconds
249
+ yield f"⏳ Status: {status}\nAttempt: {attempt + 1}/60\nTask ID: `{task_id}`\n\nStill processing... (Usually takes 30-180 seconds)"
250
  else:
251
  yield f"⚠️ Check error: HTTP {check.status_code}"
252
 
253
  except Exception as e:
254
  yield f"⚠️ Error checking status: {str(e)}"
255
 
256
+ return "⏰ Timeout after 300 seconds. Try checking again later."
257
 
258
  except Exception as e:
259
+ return f"❌ Error: {str(e)}"
260
 
261
  # Create the app
262
+ with gr.Blocks(title="Suno Lyrics & Song Generator", theme="soft") as app:
263
+ gr.Markdown("# 🎵 Suno Lyrics & Song Generator")
264
+ gr.Markdown("Generate song lyrics and turn them into full songs using Suno AI")
265
+
266
+ # Store lyrics between steps
267
+ lyrics_state = gr.State()
268
 
269
  with gr.Row():
270
  with gr.Column(scale=1):
271
+ # Lyrics Generation Section
272
+ gr.Markdown("### Step 1: Generate Lyrics")
273
  prompt = gr.Textbox(
274
  label="Lyrics Prompt",
275
  placeholder="Example: A happy song about sunshine and rainbows",
276
  lines=3
277
  )
278
+ lyrics_btn = gr.Button("🎵 Generate Lyrics", variant="primary")
279
 
280
+ # Song Generation Section (initially hidden)
281
+ gr.Markdown("### Step 2: Create Song")
282
+ with gr.Group():
283
+ variant_choice = gr.Dropdown(
284
+ label="Select Lyrics Variant",
285
+ choices=[],
286
+ interactive=True
287
+ )
288
+
289
+ with gr.Row():
290
+ custom_mode = gr.Checkbox(
291
+ label="Custom Mode (Advanced Settings)",
292
+ value=False,
293
+ interactive=True
294
+ )
295
+ instrumental = gr.Checkbox(
296
+ label="Instrumental (No Vocals)",
297
+ value=False,
298
+ interactive=True
299
+ )
300
+
301
+ with gr.Row():
302
+ style = gr.Textbox(
303
+ label="Music Style (Required for Custom Mode)",
304
+ placeholder="Example: Pop, Rock, Jazz, Classical",
305
+ interactive=True
306
+ )
307
+ title = gr.Textbox(
308
+ label="Song Title (Required for Custom Mode)",
309
+ placeholder="Example: My Awesome Song",
310
+ interactive=True
311
+ )
312
+
313
+ model = gr.Dropdown(
314
+ label="Model Version",
315
+ choices=["V5", "V4_5PLUS", "V4_5ALL", "V4_5", "V4"],
316
+ value="V4_5ALL",
317
+ interactive=True
318
+ )
319
+
320
+ song_btn = gr.Button("🎶 Generate Song", variant="secondary")
321
+
322
+ # Instructions
323
  gr.Markdown("""
324
  **How it works:**
325
+ 1. Enter your lyrics idea and generate
326
+ 2. Select a lyrics variant from results
327
+ 3. Choose song settings (or use defaults)
328
+ 4. Generate a full song with music!
329
+
330
+ **Custom Mode:** Enable for advanced control
331
+ **Instrumental:** Check for music only (no singing)
332
 
333
  **Status messages:**
334
  - ✅ Submitted = Task accepted
335
+ - ⏳ PROCESSING = Generating
336
+ - 🎶 Complete = Song ready!
337
  """)
338
 
339
  with gr.Column(scale=2):
340
  output = gr.Markdown(
341
  label="Results",
342
+ value="Your generated lyrics and songs will appear here..."
343
  )
344
+
345
  gr.Markdown("---")
346
  gr.Markdown(
347
  """
 
349
  <p>Powered by <a href="https://suno.ai" target="_blank">Suno AI</a> •
350
  <a href="https://sunoapi.org" target="_blank">Suno API Docs</a> •
351
  <a href="https://github.com" target="_blank">GitHub</a></p>
352
+ <p><small>This app uses the Suno API to generate AI-powered lyrics and music.</small></p>
353
  </div>
354
  """,
355
  elem_id="footer"
356
  )
357
 
358
+ # Lyrics generation
359
+ lyrics_btn.click(
360
+ generate_lyrics,
361
+ inputs=prompt,
362
+ outputs=[output, lyrics_state]
363
+ ).then(
364
+ lambda lyrics_info: gr.Dropdown(
365
+ choices=[f"{i+1}: {lyric.get('title', f'Variant {i+1}')}"
366
+ for i, lyric in enumerate(lyrics_info.get("lyrics_list", []))]
367
+ if lyrics_info and lyrics_info.get("lyrics_list") else []
368
+ ),
369
+ inputs=lyrics_state,
370
+ outputs=variant_choice
371
+ )
372
+
373
+ # Song generation
374
+ song_btn.click(
375
+ generate_song,
376
+ inputs=[lyrics_state, variant_choice, style, title, instrumental, model, custom_mode],
377
+ outputs=output
378
+ )
379
 
380
  if __name__ == "__main__":
381
+ print("🚀 Starting Suno Lyrics & Song Generator")
382
  print(f"🔑 SunoKey: {'✅ Set' if SUNO_KEY else '❌ Not set'}")
383
  app.launch(server_name="0.0.0.0", server_port=7860, share=False)