haraberget commited on
Commit
3f1841d
Β·
verified Β·
1 Parent(s): 1f1b856

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +143 -124
app.py CHANGED
@@ -1,7 +1,7 @@
1
  import gradio as gr
2
  import requests
3
  import os
4
- import json
5
  from datetime import datetime
6
 
7
  # Load Suno API key
@@ -9,148 +9,167 @@ SUNO_KEY = os.environ.get("SunoKey", "")
9
  if not SUNO_KEY:
10
  print("⚠️ Warning: SunoKey environment variable not set!")
11
 
12
- def test_all_endpoints():
13
- """Test all possible Suno API endpoints to find the right one"""
14
- results = ["# πŸ” Testing All Suno API Endpoints", ""]
15
-
16
- headers = {"Authorization": f"Bearer {SUNO_KEY}"}
17
-
18
- endpoints = [
19
- ("GET", "https://api.sunoapi.org/api/v1/lyrics", "Base lyrics endpoint"),
20
- ("GET", "https://api.sunoapi.org/api/v1/lyrics/record-info", "Record info endpoint"),
21
- ("GET", "https://api.sunoapi.org/api/v1/lyrics/details", "Details endpoint"),
22
- ("POST", "https://api.sunoapi.org/api/v1/lyrics", "Submit lyrics"),
23
- ]
24
-
25
- for method, url, description in endpoints:
26
- results.append(f"\n## πŸ”— {method} {url.split('/')[-1]}")
27
- results.append(f"**Description:** {description}")
28
-
29
- try:
30
- if method == "GET":
31
- response = requests.get(url, headers=headers, timeout=10)
32
- else: # POST
33
- # Try POST with minimal payload
34
- post_headers = headers.copy()
35
- post_headers["Content-Type"] = "application/json"
36
- payload = {
37
- "prompt": "Test endpoint",
38
- "callBackUrl": "http://test.com/callback"
39
- }
40
- response = requests.post(url, json=payload, headers=post_headers, timeout=10)
41
-
42
- results.append(f"**HTTP Status:** {response.status_code}")
43
-
44
- if response.status_code == 200:
45
- try:
46
- data = response.json()
47
- results.append(f"**Response:** ```json\n{json.dumps(data, indent=2)[:500]}...\n```")
48
- except:
49
- results.append(f"**Response:** {response.text[:200]}...")
50
- else:
51
- results.append(f"**Error:** {response.text[:200]}...")
52
-
53
- except Exception as e:
54
- results.append(f"**Exception:** {str(e)}")
55
-
56
- return "\n".join(results)
57
 
58
- def test_correct_workflow():
59
- """Test what SHOULD be the correct workflow based on your code"""
60
- results = ["# 🎯 Testing Correct Workflow", ""]
61
-
62
  if not SUNO_KEY:
63
- return "❌ No SunoKey configured"
64
 
65
- headers = {"Authorization": f"Bearer {SUNO_KEY}"}
 
66
 
67
- # Step 1: Submit lyrics (as per your original working code)
68
- results.append("## 1️⃣ Submit Lyrics")
 
 
69
  submit_url = "https://api.sunoapi.org/api/v1/lyrics"
70
- submit_headers = headers.copy()
71
- submit_headers["Content-Type"] = "application/json"
 
 
72
 
 
73
  payload = {
74
- "prompt": "Correct workflow test song",
75
- "callBackUrl": "http://correct-test.com/callback"
76
  }
77
 
78
  try:
79
- response = requests.post(submit_url, json=payload, headers=submit_headers, timeout=30)
80
- results.append(f"**Status:** {response.status_code}")
 
 
 
 
 
 
 
 
 
81
 
82
- if response.status_code == 200:
83
- data = response.json()
84
- results.append(f"**Code:** {data.get('code')}")
85
- results.append(f"**Message:** {data.get('msg', 'No message')}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
- if data.get("code") == 200 and "data" in data:
88
- task_id = data["data"]["taskId"]
89
- results.append(f"**Task ID:** `{task_id}`")
 
 
 
 
 
 
 
 
 
 
90
 
91
- # Step 2: Check using record-info endpoint (from your example)
92
- results.append("\n## 2️⃣ Check with /record-info")
93
- record_url = "https://api.sunoapi.org/api/v1/lyrics/record-info"
 
94
 
95
- # Try different query parameters
96
- test_params = [
97
- {"taskId": task_id},
98
- {"id": task_id},
99
- {"record_id": task_id},
100
- {}, # No params
101
- ]
 
 
 
 
 
 
 
 
102
 
103
- for params in test_params:
104
- results.append(f"\n**Trying params:** {params}")
105
- try:
106
- record_response = requests.get(
107
- record_url,
108
- headers=headers,
109
- params=params,
110
- timeout=30
111
- )
112
- results.append(f"Status: {record_response.status_code}")
113
-
114
- if record_response.status_code == 200:
115
- record_data = record_response.json()
116
- results.append(f"Response: ```json\n{json.dumps(record_data, indent=2)[:300]}...\n```")
117
- else:
118
- results.append(f"Error: {record_response.text[:100]}")
119
- except Exception as e:
120
- results.append(f"Exception: {str(e)}")
121
 
122
- # Step 3: Also try details endpoint for comparison
123
- results.append("\n## 3️⃣ Check with /details (for comparison)")
124
- details_url = f"https://api.sunoapi.org/api/v1/lyrics/details?taskId={task_id}"
125
- try:
126
- details_response = requests.get(details_url, headers=headers, timeout=30)
127
- results.append(f"Status: {details_response.status_code}")
128
- if details_response.status_code == 200:
129
- details_data = details_response.json()
130
- results.append(f"Response: ```json\n{json.dumps(details_data, indent=2)[:300]}...\n```")
131
- except Exception as e:
132
- results.append(f"Exception: {str(e)}")
133
 
 
 
 
 
 
 
 
 
134
  else:
135
- results.append("❌ No task ID in response")
136
- else:
137
- results.append(f"❌ Submission failed: {response.text[:200]}")
138
-
139
- except Exception as e:
140
- results.append(f"❌ Exception: {str(e)}")
 
 
 
 
 
 
141
 
142
- return "\n".join(results)
143
 
144
- def check_api_documentation():
145
- """Show what we know about Suno API"""
146
- return """# πŸ“š Suno API Documentation
 
 
 
 
 
 
147
 
148
- ## πŸ” What We Know:
149
 
150
- ### **Endpoints Found:**
151
- 1. `POST /api/v1/lyrics` - Submit lyrics generation
152
- ```json
153
- {
154
- "prompt": "song about...",
155
- "callBackUrl": "https://your-webhook.com/callback"
156
- }
 
1
  import gradio as gr
2
  import requests
3
  import os
4
+ import time
5
  from datetime import datetime
6
 
7
  # Load Suno API key
 
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}