haraberget commited on
Commit
57067e1
·
verified ·
1 Parent(s): 3f1841d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +129 -147
app.py CHANGED
@@ -2,174 +2,156 @@ import gradio as gr
2
  import requests
3
  import os
4
  import time
5
- from datetime import datetime
6
 
7
- # Load Suno API key
8
  SUNO_KEY = os.environ.get("SunoKey", "")
9
  if not SUNO_KEY:
10
- print("⚠️ Warning: SunoKey environment variable not set!")
11
 
12
- # Simple task storage
13
- tasks = {}
14
-
15
- def generate_lyrics_simple(prompt):
16
- """Simple lyrics generation using correct endpoints"""
17
  if not SUNO_KEY:
18
- return "❌ Error: SunoKey not configured"
 
19
 
20
  if not prompt.strip():
21
- return "❌ Please enter a prompt"
22
-
23
- # Generate simple task ID for our tracking
24
- task_id = str(int(time.time()))[-6:]
25
-
26
- # Submit to Suno API
27
- submit_url = "https://api.sunoapi.org/api/v1/lyrics"
28
- headers = {
29
- "Authorization": f"Bearer {SUNO_KEY}",
30
- "Content-Type": "application/json"
31
- }
32
-
33
- # Use a dummy callback URL (required by API)
34
- payload = {
35
- "prompt": prompt,
36
- "callBackUrl": "http://dummy.callback/not-used"
37
- }
38
 
 
39
  try:
40
- # Step 1: Submit the task
41
- print(f"📤 Submitting: {prompt[:50]}...")
42
- response = requests.post(submit_url, json=payload, headers=headers, timeout=30)
 
 
 
 
 
 
 
 
 
43
 
44
- if response.status_code != 200:
45
- return f"❌ Submission failed: HTTP {response.status_code}"
46
-
47
- data = response.json()
48
 
 
49
  if data.get("code") != 200:
50
- return f"❌ API error: {data.get('msg', 'Unknown error')}"
51
-
52
- # Get Suno's task ID
53
- suno_task_id = data["data"]["taskId"]
54
- print(f"✅ Submitted! Suno Task ID: {suno_task_id}")
55
 
56
- # Store task
57
- tasks[task_id] = {
58
- "suno_id": suno_task_id,
59
- "prompt": prompt,
60
- "status": "submitted",
61
- "start_time": datetime.now(),
62
- "checks": 0
63
- }
64
 
65
- # Step 2: Wait a bit then check using /record-info endpoint
66
- time.sleep(2) # Give it a moment
67
-
68
- # Step 3: Poll using the CORRECT endpoint
69
- return poll_for_results(task_id, suno_task_id)
70
-
71
- except Exception as e:
72
- return f"❌ Error: {str(e)}"
73
-
74
- def poll_for_results(task_id, suno_task_id, max_attempts=12):
75
- """Poll for results using /record-info endpoint"""
76
- headers = {"Authorization": f"Bearer {SUNO_KEY}"}
77
-
78
- # Use the CORRECT endpoint: /record-info
79
- poll_url = f"https://api.sunoapi.org/api/v1/lyrics/record-info"
80
-
81
- for attempt in range(max_attempts):
82
- try:
83
- # Try different parameter names
84
- params_list = [
85
- {"taskId": suno_task_id},
86
- {"id": suno_task_id},
87
- {"record_id": suno_task_id},
88
- ]
89
 
90
- response_data = None
91
- for params in params_list:
92
- try:
93
- response = requests.get(poll_url, headers=headers, params=params, timeout=30)
94
- if response.status_code == 200:
95
- response_data = response.json()
96
- if response_data.get("code") == 200:
97
- break
98
- except:
99
- continue
100
-
101
- if response_data and response_data.get("code") == 200:
102
- task_info = response_data["data"]
103
-
104
- # Update status (might be in different field names)
105
- status = task_info.get("status") or task_info.get("state") or "unknown"
106
- tasks[task_id]["status"] = status
107
- tasks[task_id]["checks"] = attempt + 1
108
 
109
- # Check if completed
110
- if status == "completed":
111
- # Try to get lyrics from different possible field names
112
- lyrics = (
113
- task_info.get("lyrics") or
114
- task_info.get("data") or
115
- task_info.get("result") or
116
- []
117
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
- if lyrics:
120
- elapsed = int((datetime.now() - tasks[task_id]["start_time"]).total_seconds())
121
- return format_success(lyrics, task_id, elapsed)
122
- else:
123
- return "✅ Completed but no lyrics data found"
124
-
125
- elif status == "failed":
126
- error = task_info.get("error", "Unknown error")
127
- return f"❌ Task failed: {error}"
128
-
129
- elif status == "processing":
130
- # Still processing
131
- elapsed = int((datetime.now() - tasks[task_id]["start_time"]).total_seconds())
132
- if attempt < max_attempts - 1:
133
- time.sleep(5) # Wait 5 seconds before next check
134
- continue
135
- else:
136
- return f"⏳ Still processing after {elapsed} seconds. Try checking again later."
137
-
138
- else: # submitted or unknown
139
- elapsed = int((datetime.now() - tasks[task_id]["start_time"]).total_seconds())
140
- if attempt < max_attempts - 1:
141
- time.sleep(5)
142
- continue
143
  else:
144
- return f"📥 Still submitted after {elapsed} seconds. Suno API might be slow."
145
-
146
- else:
147
- # If we can't get status, show what we got
148
- if response_data:
149
- return f"⚠️ Status check error: {response_data.get('msg', 'Unknown')}"
150
  else:
151
- return "⚠️ Could not check status - no response from API"
 
 
 
152
 
153
- except Exception as e:
154
- if attempt < max_attempts - 1:
155
- time.sleep(5)
156
- continue
157
- else:
158
- return f"⚠️ Error checking status: {str(e)}"
159
 
160
- return "⏰ Timeout after multiple attempts"
 
161
 
162
- def format_success(lyrics_data, task_id, elapsed_time):
163
- """Format successful lyrics"""
164
- # Handle different data structures
165
- if isinstance(lyrics_data, dict):
166
- # If it's a dict, try to extract lyrics
167
- lyrics_text = lyrics_data.get('text') or lyrics_data.get('lyrics') or str(lyrics_data)
168
- title = lyrics_data.get('title', 'Generated Lyrics')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
- output = f"""# 🎵 {title} (Task: {task_id})
171
-
172
- **Generated in:** {elapsed_time} seconds
 
 
 
 
173
 
174
- ```text
175
- {lyrics_text}
 
 
 
2
  import requests
3
  import os
4
  import time
5
+ import json
6
 
7
+ # Suno API key
8
  SUNO_KEY = os.environ.get("SunoKey", "")
9
  if not SUNO_KEY:
10
+ print("⚠️ SunoKey not set!")
11
 
12
+ def generate_lyrics(prompt):
13
+ """Final working lyrics generator"""
 
 
 
14
  if not SUNO_KEY:
15
+ yield "❌ Error: SunoKey not configured in environment variables"
16
+ return
17
 
18
  if not prompt.strip():
19
+ yield "❌ Error: Please enter a prompt"
20
+ return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ # Submit task
23
  try:
24
+ resp = requests.post(
25
+ "https://api.sunoapi.org/api/v1/lyrics",
26
+ json={
27
+ "prompt": prompt,
28
+ "callBackUrl": "http://dummy.com/callback" # Required but not used
29
+ },
30
+ headers={
31
+ "Authorization": f"Bearer {SUNO_KEY}",
32
+ "Content-Type": "application/json"
33
+ },
34
+ timeout=30
35
+ )
36
 
37
+ if resp.status_code != 200:
38
+ yield f"❌ Submission failed: HTTP {resp.status_code}"
39
+ return
 
40
 
41
+ data = resp.json()
42
  if data.get("code") != 200:
43
+ yield f"❌ API error: {data.get('msg', 'Unknown')}"
44
+ return
 
 
 
45
 
46
+ task_id = data["data"]["taskId"]
47
+ yield f"✅ **Submitted!**\nTask ID: `{task_id}`\n\n⏳ Waiting for lyrics...\n"
 
 
 
 
 
 
48
 
49
+ # Poll for results
50
+ for attempt in range(30): # 30 attempts * 5 seconds = 150 seconds max
51
+ time.sleep(5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
+ try:
54
+ check = requests.get(
55
+ "https://api.sunoapi.org/api/v1/lyrics/record-info",
56
+ headers={"Authorization": f"Bearer {SUNO_KEY}"},
57
+ params={"taskId": task_id},
58
+ timeout=30
59
+ )
 
 
 
 
 
 
 
 
 
 
 
60
 
61
+ if check.status_code == 200:
62
+ check_data = check.json()
63
+ status = check_data["data"].get("status", "PENDING")
64
+
65
+ if status == "SUCCESS":
66
+ # Success! Extract lyrics
67
+ response_data = check_data["data"].get("response", {})
68
+
69
+ if isinstance(response_data, str):
70
+ # Sometimes response is a JSON string
71
+ try:
72
+ response_data = json.loads(response_data.replace('null', 'None'))
73
+ except:
74
+ response_data = {"data": []}
75
+
76
+ lyrics_list = response_data.get("data", [])
77
+
78
+ if lyrics_list:
79
+ output = "🎵 **Lyrics Generated Successfully!**\n\n"
80
+
81
+ for i, lyric in enumerate(lyrics_list, 1):
82
+ title = lyric.get('title', f'Variant {i}')
83
+ text = lyric.get('text', 'No lyrics')
84
+
85
+ output += f"## Variant {i}: {title}\n"
86
+ output += "```\n"
87
+ output += text
88
+ output += "\n```\n"
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:
103
+ # PENDING or PROCESSING
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
+
152
+ btn.click(generate_lyrics, prompt, output)
153
 
154
+ if __name__ == "__main__":
155
+ print("🚀 Starting Suno Lyrics Generator")
156
+ print(f"🔑 SunoKey: {'✅ Set' if SUNO_KEY else '❌ Not set'}")
157
+ app.launch(server_name="0.0.0.0", server_port=7860, share=False)