MySafeCode commited on
Commit
23fcaac
·
verified ·
1 Parent(s): 3c06a67

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +274 -0
app.py ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import json
4
+ import os
5
+ from datetime import datetime
6
+
7
+ # Page configuration
8
+ st.set_page_config(
9
+ page_title="🎵 Suno AI Audio Generator",
10
+ page_icon="🎵",
11
+ layout="wide",
12
+ initial_sidebar_state="expanded"
13
+ )
14
+
15
+ # Custom CSS
16
+ st.markdown("""
17
+ <style>
18
+ .stApp {
19
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
20
+ }
21
+ .api-card {
22
+ background: rgba(255, 255, 255, 0.95);
23
+ backdrop-filter: blur(10px);
24
+ border: 1px solid rgba(255, 255, 255, 0.2);
25
+ box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
26
+ }
27
+ .secret-mask {
28
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
29
+ background: #f3f4f6;
30
+ padding: 2px 6px;
31
+ border-radius: 4px;
32
+ font-size: 12px;
33
+ color: #374151;
34
+ }
35
+ .success-badge {
36
+ background: #d1fae5;
37
+ color: #065f46;
38
+ border-radius: 9999px;
39
+ padding: 4px 12px;
40
+ display: inline-flex;
41
+ align-items: center;
42
+ font-size: 12px;
43
+ margin: 4px;
44
+ }
45
+ .error-badge {
46
+ background: #fee2e2;
47
+ color: #7c2d1a;
48
+ border-radius: 9999px;
49
+ padding: 4px 12px;
50
+ display: inline-flex;
51
+ align-items: center;
52
+ font-size: 12px;
53
+ margin: 4px;
54
+ }
55
+ </style>
56
+ """, unsafe_allow_html=True)
57
+
58
+ # Main App
59
+ def main():
60
+ # Header
61
+ st.title("🎵 Suno AI Audio Generator")
62
+ st.markdown("Generate audio using Suno API with secure secret management")
63
+
64
+ # Initialize session state
65
+ if 'secrets_loaded' not in st.session_state:
66
+ st.session_state.secrets_loaded = False
67
+ st.session_state.suno_api_key = None
68
+ st.session_state.callback_url = None
69
+ st.session_state.last_api_response = None
70
+
71
+ # Sidebar for configuration
72
+ with st.sidebar:
73
+ st.header("⚙️ Configuration")
74
+ st.markdown("---")
75
+
76
+ # Secret Loading Section
77
+ st.subheader("🔐 Load Secrets")
78
+
79
+ # Load secrets from environment variables
80
+ suno_api_key = st.secrets.get("SUNO_API_KEY", "").strip() or os.environ.get("SUNO_API_KEY", "")
81
+ callback_url = st.secrets.get("CALLBACK_URL", "").strip() or os.environ.get("CALLBACK_URL", "")
82
+
83
+ # Show loaded secrets status
84
+ if suno_api_key and callback_url:
85
+ st.success("Secrets loaded!")
86
+
87
+ # Display masked secrets
88
+ with st.expander("🔐 Loaded Secrets", expanded=True):
89
+ st.markdown(f"""
90
+ **API Key Status:** ✅ Loaded
91
+ **Callback URL:** ✅ Loaded
92
+
93
+ **Usage:** API calls will automatically use these secrets.
94
+ """)
95
+
96
+ st.session_state.suno_api_key = suno_api_key
97
+ st.session_state.callback_url = callback_url
98
+ st.session_state.secrets_loaded = True
99
+ else:
100
+ st.warning("Secrets not configured")
101
+ st.markdown("""
102
+ **To configure:**
103
+ 1. Set **SUNO_API_KEY** in `.streamlit/secrets.toml`
104
+ 2. Set **CALLBACK_URL** in `.streamlit/secrets.toml`
105
+ """)
106
+
107
+ st.markdown("---")
108
+
109
+ # Manual input for testing
110
+ st.subheader("🔧 Manual Override (Testing)")
111
+ manual_api_key = st.text_input("Enter API Key:", type="password")
112
+ manual_callback_url = st.text_input("Enter Callback URL:", value=callback_url if callback_url else "")
113
+
114
+ if st.button("🔧 Use Manual Credentials"):
115
+ if manual_api_key and manual_callback_url:
116
+ st.session_state.suno_api_key = manual_api_key
117
+ st.session_state.callback_url = manual_callback_url
118
+ st.session_state.secrets_loaded = True
119
+ st.success("Using manual credentials")
120
+ st.rerun()
121
+
122
+ # Main content area
123
+ col1, col2 = st[3, 1])
124
+
125
+ with col1:
126
+ st.markdown("### 🎛️ API Parameters")
127
+
128
+ # Task ID input
129
+ task_id = st.text_input(
130
+ "Task ID",
131
+ value="5c79****be8e",
132
+ help="Enter your Suno API task ID"
133
+ )
134
+
135
+ # Audio ID input
136
+ audio_id = st.text_input(
137
+ "Audio ID",
138
+ value="e231****-****-****-****-****8cadc7dc",
139
+ help="Enter your Suno API audio ID"
140
+ )
141
+
142
+ # API Endpoint selection
143
+ endpoint = st.selectbox(
144
+ "API Endpoint",
145
+ options=["/api/v1/wav/generate", "/api/v1/audio/sync", "/api/v1/audio/status"],
146
+ help="Select the Suno API endpoint to use"
147
+ )
148
+
149
+ # Advanced options
150
+ with st.expander("🔧 Advanced Options"):
151
+ timeout = st.number_input("Timeout (seconds)", min_value=5, max_value=60, value=30, step=5)
152
+ retry_count = st.slider("Retry Count", 0, 3, 1)
153
+ show_debug = st.checkbox("Show Debug Info")
154
+
155
+ with col2:
156
+ st.markdown("### 📊 Quick Actions")
157
+ if st.button("🚀 Test API Connection"):
158
+ test_api_connection()
159
+
160
+ if st.button("🧪 Test with Sample Data"):
161
+ test_with_sample_data()
162
+
163
+ if st.button("📋 Copy Configuration"):
164
+ copy_configuration()
165
+
166
+ # API Call Section
167
+ st.markdown("---")
168
+ st.markdown("### 🚀 Make API Call")
169
+
170
+ # Make API call button
171
+ if st.button("🎵 Generate Audio", key="generate_audio", type="primary", use_container_width=True):
172
+ make_api_call(task_id, audio_id, st.secrets.get("SUNO_API_KEY", manual_api_key if manual_api_key else suno_api_key), callback_url if callback_url else manual_callback_url)
173
+
174
+ # Results section
175
+ st.markdown("---")
176
+ if 'last_api_response' in st.session_state:
177
+ st.markdown("### 📋 Last API Response")
178
+ st.json(st.session_state.last_api_response)
179
+
180
+ # Download JSON button
181
+ st.download_button(
182
+ label="📥 Download Response JSON",
183
+ data=json.dumps(st.session_state.last_api_response, indent=2),
184
+ file_name=f"suno_response_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
185
+ mime="application/json"
186
+ )
187
+
188
+ # Test API Connection
189
+ def test_api_connection():
190
+ with st.spinner("Testing API connection..."):
191
+ # Implement API connection test
192
+ try:
193
+ test_response = {"status": "connected"}
194
+ st.success("✅ API connection successful!")
195
+ st.json(test_response)
196
+ except Exception as e:
197
+ st.error(f"❌ API connection failed: {str(e)}")
198
+
199
+ # Test with Sample Data
200
+ def test_with_sample_data():
201
+ sample_data = {
202
+ "taskId": "5c79****be8e",
203
+ "audioId": "e231****-****-****-****-****8cadc7dc",
204
+ "callBackUrl": st.session_state.callback_url
205
+ }
206
+
207
+ st.info("🧪 Testing with sample data...")
208
+ st.json(sample_data)
209
+
210
+ # Copy Configuration
211
+ def copy_configuration():
212
+ config = {
213
+ "api_key": st.session_state.suno_api_key,
214
+ "callback_url": st.session_state.callback_url,
215
+ "task_id": st.session_state.get("task_id", ""),
216
+ "audio_id": st.session_state.get("audio_id", "")
217
+ }
218
+
219
+ st.code(json.dumps(config, indent=2), language="json")
220
+ st.success("📋 Configuration copied to clipboard!")
221
+
222
+ # Make API Call Function
223
+ def make_api_call(task_id, audio_id, api_key, callback_url):
224
+ with st.spinner("🎵 Generating audio..."):
225
+ # Prepare the API call
226
+ headers = {
227
+ "Authorization": f"Bearer {api_key}",
228
+ "Content-Type": "application/json"
229
+ }
230
+
231
+ data = {
232
+ "taskId": task_id,
233
+ "audioId": audio_id,
234
+ "callBackUrl": callback_url
235
+ }
236
+
237
+ # Show request details
238
+ with st.expander("📡 Request Details", expanded=False):
239
+ st.markdown(f"""
240
+ **Endpoint:** `https://api.sunoapi.org/api/v1/wav/generate`
241
+ **Headers:** ```python
242
+ {json.dumps(headers, indent=2)}
243
+ ```
244
+ **Body:** ```json
245
+ {json.dumps(data, indent=2)}
246
+ ```
247
+ """)
248
+
249
+ # Make the API call
250
+ try:
251
+ #response = requests.post("https://api.sunoapi.org/api/v1/wav/generate", headers=headers, json=data)
252
+ #st.session_state.last_api_response = response.json()
253
+
254
+ # For demo purposes, return a mock response
255
+ mock_response = {
256
+ "status": "success",
257
+ "jobId": "generated_123456789",
258
+ "estimatedCompletion": "2026-01-17T20:45:00Z",
259
+ "message": "Audio generation started successfully"
260
+ }
261
+
262
+ st.session_state.last_api_response = mock_response
263
+ st.success("✅ Audio generation started successfully!")
264
+
265
+ # Show job info
266
+ st.info(f"**Job ID:** {mock_response['jobId']}")
267
+ st.info(f"**Estimated Completion:** {mock_response['estimatedCompletion']}")
268
+
269
+ except Exception as e:
270
+ st.error(f"❌ API call failed: {str(e)}")
271
+
272
+ # Run the main function
273
+ if __name__ == "__main__":
274
+ main()