getwavefromsuno / app.py
MySafeCode's picture
Update app.py
16dd2cd verified
raw
history blame
9.25 kB
import streamlit as st
import requests
import json
import os
from datetime import datetime
# Page configuration
st.set_page_config(
page_title="🎵 Suno AI Audio Generator",
page_icon="🎵",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS
st.markdown("""
<style>
.stApp {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.api-card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
}
.secret-mask {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
background: #f3f4f6;
padding: 2px 6px;
border-radius: 4px;
font-size: 12px;
color: #374151;
}
.success-badge {
background: #d1fae5;
color: #065f46;
border-radius: 9999px;
padding: 4px 12px;
display: inline-flex;
align-items: center;
font-size: 12px;
margin: 4px;
}
.error-badge {
background: #fee2e2;
color: #7c2d1a;
border-radius: 9999px;
padding: 4px 12px;
display: inline-flex;
align-items: center;
font-size: 12px;
margin: 4px;
}
</style>
""", unsafe_allow_html=True)
# Main App
def main():
# Header
st.title("🎵 Suno AI Audio Generator")
st.markdown("Generate audio using Suno API with secure secret management")
# Initialize session state
if 'secrets_loaded' not in st.session_state:
st.session_state.secrets_loaded = False
st.session_state.suno_api_key = None
st.session_state.callback_url = None
st.session_state.last_api_response = None
# Sidebar for configuration
with st.sidebar:
st.header("⚙️ Configuration")
st.markdown("---")
# Secret Loading Section
st.subheader("🔐 Load Secrets")
# Load secrets from environment variables
suno_api_key = st.secrets.get("SUNO_API_KEY", "").strip() or os.environ.get("SUNO_API_KEY", "")
callback_url = st.secrets.get("CALLBACK_URL", "").strip() or os.environ.get("CALLBACK_URL", "")
# Show loaded secrets status
if suno_api_key and callback_url:
st.success("Secrets loaded!")
# Display masked secrets
with st.expander("🔐 Loaded Secrets", expanded=True):
st.markdown(f"""
**API Key Status:** ✅ Loaded
**Callback URL:** ✅ Loaded
**Usage:** API calls will automatically use these secrets.
""")
st.session_state.suno_api_key = suno_api_key
st.session_state.callback_url = callback_url
st.session_state.secrets_loaded = True
else:
st.warning("Secrets not configured")
st.markdown("""
**To configure:**
1. Set **SUNO_API_KEY** in `.streamlit/secrets.toml`
2. Set **CALLBACK_URL** in `.streamlit/secrets.toml`
""")
st.markdown("---")
# Manual input for testing
st.subheader("🔧 Manual Override (Testing)")
manual_api_key = st.text_input("Enter API Key:", type="password")
manual_callback_url = st.text_input("Enter Callback URL:", value=callback_url if callback_url else "")
if st.button("🔧 Use Manual Credentials"):
if manual_api_key and manual_callback_url:
st.session_state.suno_api_key = manual_api_key
st.session_state.callback_url = manual_callback_url
st.session_state.secrets_loaded = True
st.success("Using manual credentials")
st.rerun()
# Main content area
col1, col2 = st[3, 1]
with col1:
st.markdown("### 🎛️ API Parameters")
# Task ID input
task_id = st.text_input(
"Task ID",
value="5c79****be8e",
help="Enter your Suno API task ID"
)
# Audio ID input
audio_id = st.text_input(
"Audio ID",
value="e231****-****-****-****-****8cadc7dc",
help="Enter your Suno API audio ID"
)
# API Endpoint selection
endpoint = st.selectbox(
"API Endpoint",
options=["/api/v1/wav/generate", "/api/v1/audio/sync", "/api/v1/audio/status"],
help="Select the Suno API endpoint to use"
)
# Advanced options
with st.expander("🔧 Advanced Options"):
timeout = st.number_input("Timeout (seconds)", min_value=5, max_value=60, value=30, step=5)
retry_count = st.slider("Retry Count", 0, 3, 1)
show_debug = st.checkbox("Show Debug Info")
with col2:
st.markdown("### 📊 Quick Actions")
if st.button("🚀 Test API Connection"):
test_api_connection()
if st.button("🧪 Test with Sample Data"):
test_with_sample_data()
if st.button("📋 Copy Configuration"):
copy_configuration()
# API Call Section
st.markdown("---")
st.markdown("### 🚀 Make API Call")
# Make API call button
if st.button("🎵 Generate Audio", key="generate_audio", type="primary", use_container_width=True):
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)
# Results section
st.markdown("---")
if 'last_api_response' in st.session_state:
st.markdown("### 📋 Last API Response")
st.json(st.session_state.last_api_response)
# Download JSON button
st.download_button(
label="📥 Download Response JSON",
data=json.dumps(st.session_state.last_api_response, indent=2),
file_name=f"suno_response_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
mime="application/json"
)
# Test API Connection
def test_api_connection():
with st.spinner("Testing API connection..."):
# Implement API connection test
try:
test_response = {"status": "connected"}
st.success("✅ API connection successful!")
st.json(test_response)
except Exception as e:
st.error(f"❌ API connection failed: {str(e)}")
# Test with Sample Data
def test_with_sample_data():
sample_data = {
"taskId": "5c79****be8e",
"audioId": "e231****-****-****-****-****8cadc7dc",
"callBackUrl": st.session_state.callback_url
}
st.info("🧪 Testing with sample data...")
st.json(sample_data)
# Copy Configuration
def copy_configuration():
config = {
"api_key": st.session_state.suno_api_key,
"callback_url": st.session_state.callback_url,
"task_id": st.session_state.get("task_id", ""),
"audio_id": st.session_state.get("audio_id", "")
}
st.code(json.dumps(config, indent=2), language="json")
st.success("📋 Configuration copied to clipboard!")
# Make API Call Function
def make_api_call(task_id, audio_id, api_key, callback_url):
with st.spinner("🎵 Generating audio..."):
# Prepare the API call
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
data = {
"taskId": task_id,
"audioId": audio_id,
"callBackUrl": callback_url
}
# Show request details
with st.expander("📡 Request Details", expanded=False):
st.markdown(f"""
**Endpoint:** `https://api.sunoapi.org/api/v1/wav/generate`
**Headers:** ```python
{json.dumps(headers, indent=2)}
```
**Body:** ```json
{json.dumps(data, indent=2)}
```
""")
# Make the API call
try:
#response = requests.post("https://api.sunoapi.org/api/v1/wav/generate", headers=headers, json=data)
#st.session_state.last_api_response = response.json()
# For demo purposes, return a mock response
mock_response = {
"status": "success",
"jobId": "generated_123456789",
"estimatedCompletion": "2026-01-17T20:45:00Z",
"message": "Audio generation started successfully"
}
st.session_state.last_api_response = mock_response
st.success("✅ Audio generation started successfully!")
# Show job info
st.info(f"**Job ID:** {mock_response['jobId']}")
st.info(f"**Estimated Completion:** {mock_response['estimatedCompletion']}")
except Exception as e:
st.error(f"❌ API call failed: {str(e)}")
# Run the main function
if __name__ == "__main__":
main()