lenpanda commited on
Commit
7a38972
·
verified ·
1 Parent(s): 6cdd918

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -70
app.py CHANGED
@@ -1,7 +1,7 @@
1
  import os
2
  import requests
3
  import gradio as gr
4
- from flask import Flask, redirect, request
5
 
6
  # Spotify API credentials (set in HF Space secrets)
7
  CLIENT_ID = os.getenv("SPOTIFY_CLIENT_ID")
@@ -11,15 +11,80 @@ SPOTIFY_AUTH_URL = "https://accounts.spotify.com/authorize"
11
  SPOTIFY_TOKEN_URL = "https://accounts.spotify.com/api/token"
12
  SCOPE = "playlist-modify-public playlist-modify-private"
13
 
14
- # Initialize Flask app (for route definitions, but we'll use Gradio's server)
15
- app = Flask(__name__)
16
-
17
  # Store access token (for demo; use a session store in production)
18
  access_token = None
19
 
20
- # Flask routes defined as functions
21
  def home():
22
- return '<a href="/login">Login with Spotify</a>'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
  def login():
25
  auth_url = (
@@ -33,7 +98,6 @@ def callback(code=None):
33
  if not code:
34
  return "Error: No authorization code provided", 400
35
 
36
- # Exchange code for access token
37
  token_data = {
38
  "grant_type": "authorization_code",
39
  "code": code,
@@ -46,79 +110,58 @@ def callback(code=None):
46
 
47
  if response.status_code == 200:
48
  access_token = token_json.get("access_token")
49
- return f"Authorization successful! Access token stored. <a href='/add-song'>Add a song</a>"
50
  else:
51
  return f"Error: {token_json.get('error_description', 'Failed to get access token')}", 400
52
 
53
- def add_song():
54
- if not access_token:
55
- return "Error: Not authenticated. <a href='/login'>Login with Spotify</a>", 401
56
-
57
- playlist_id = "YOUR_PLAYLIST_ID" # Replace with actual ID
58
- track_uri = "spotify:track:4u7EnebtmKWzUH433cf5Qv" # Example: Bohemian Rhapsody
59
- url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
60
- headers = {
61
- "Authorization": f"Bearer {access_token}",
62
- "Content-Type": "application/json"
63
- }
64
- data = {"uris": [track_uri], "position": 0}
65
- response = requests.post(url, headers=headers, json=data)
66
-
67
- if response.status_code == 201:
68
- return "Song added to playlist!"
69
- else:
70
- return f"Error adding song: {response.json().get('error', {}).get('message', 'Unknown error')}", 400
71
-
72
- # Gradio interface
73
  def gradio_interface(song_name="", artist_name=""):
74
- if song_name:
75
- try:
76
- track_uri = get_track_uri(song_name, access_token, artist_name)
77
- result = add_song_to_playlist("YOUR_PLAYLIST_ID", track_uri, access_token)
78
- return f"Added song: {song_name}. Result: {result}"
79
- except Exception as e:
80
- return f"Error: {str(e)}"
81
- return "Enter a song name and artist (optional) to add to your playlist."
82
-
83
- # Spotify API helper functions
84
- def get_track_uri(song_name, access_token, artist_name=None):
85
- query = f"track:{song_name}"
86
- if artist_name:
87
- query += f" artist:{artist_name}"
88
- url = f"https://api.spotify.com/v1/search?q={query}&type=track&limit=1"
89
- headers = {"Authorization": f"Bearer {access_token}"}
90
- response = requests.get(url, headers=headers)
91
- data = response.json()
92
- if data.get("tracks", {}).get("items"):
93
- return data["tracks"]["items"][0]["uri"]
94
- raise Exception("Song not found")
95
-
96
- def add_song_to_playlist(playlist_id, track_uri, access_token):
97
- url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
98
- headers = {
99
- "Authorization": f"Bearer {access_token}",
100
- "Content-Type": "application/json"
101
- }
102
- data = {"uris": [track_uri], "position": 0}
103
- response = requests.post(url, headers=headers, json=data)
104
- return response.json()
105
-
106
- # Set up Gradio Blocks with Flask-like routes
107
- with gr.Blocks() as demo:
 
 
 
 
 
 
108
  gr.Markdown("## Spotify Playlist Manager")
109
  with gr.Row():
110
  song_input = gr.Textbox(label="Song Name")
111
  artist_input = gr.Textbox(label="Artist Name (optional)")
112
  submit_button = gr.Button("Add Song to Playlist")
113
  output = gr.Textbox(label="Result")
114
-
115
- # Map Flask routes to Gradio
116
- demo.route("/", home)
117
- demo.route("/login", login)
118
- demo.route("/callback", callback)
119
- demo.route("/add-song", add_song)
120
-
121
- # Gradio interface submission
122
  submit_button.click(
123
  fn=gradio_interface,
124
  inputs=[song_input, artist_input],
 
1
  import os
2
  import requests
3
  import gradio as gr
4
+ from flask import redirect
5
 
6
  # Spotify API credentials (set in HF Space secrets)
7
  CLIENT_ID = os.getenv("SPOTIFY_CLIENT_ID")
 
11
  SPOTIFY_TOKEN_URL = "https://accounts.spotify.com/api/token"
12
  SCOPE = "playlist-modify-public playlist-modify-private"
13
 
 
 
 
14
  # Store access token (for demo; use a session store in production)
15
  access_token = None
16
 
17
+ # Flask-like route handlers
18
  def home():
19
+ return """
20
+ <a href="/login">Login with Spotify</a><br><br>
21
+ <div id="song-form">
22
+ <input id="song-name" placeholder="Song Name" type="text">
23
+ <input id="artist-name" placeholder="Artist Name (optional)" type="text">
24
+ <button onclick="addSong()">Add Song to Playlist</button>
25
+ <div id="result"></div>
26
+ </div>
27
+ <script>
28
+ async function getTrackUri(songName, accessToken, artistName = null) {
29
+ let query = `track:${songName}`;
30
+ if (artistName) query += ` artist:${artistName}`;
31
+ const url = `https://api.spotify.com/v1/search?q=${encodeURIComponent(query)}&type=track&limit=1`;
32
+ const headers = { "Authorization": `Bearer ${accessToken}` };
33
+ try {
34
+ const response = await fetch(url, { headers });
35
+ const data = await response.json();
36
+ if (data.tracks && data.tracks.items.length > 0) {
37
+ return data.tracks.items[0].uri;
38
+ }
39
+ throw new Error("Song not found");
40
+ } catch (error) {
41
+ throw new Error(`Search error: ${error.message}`);
42
+ }
43
+ }
44
+
45
+ async function addSongToPlaylist(playlistId, trackUri, accessToken) {
46
+ const url = `https://api.spotify.com/v1/playlists/${playlistId}/tracks`;
47
+ const headers = {
48
+ "Authorization": `Bearer ${accessToken}`,
49
+ "Content-Type": "application/json",
50
+ };
51
+ const body = { uris: [trackUri], position: 0 };
52
+ try {
53
+ const response = await fetch(url, {
54
+ method: "POST",
55
+ headers,
56
+ body: JSON.stringify(body),
57
+ });
58
+ const data = await response.json();
59
+ if (response.status === 201) {
60
+ return "Song added to playlist!";
61
+ }
62
+ throw new Error(`Error adding song: ${data.error?.message || "Unknown error"}`);
63
+ } catch (error) {
64
+ throw new Error(`Playlist error: ${error.message}`);
65
+ }
66
+ }
67
+
68
+ async function addSong() {
69
+ const songName = document.getElementById("song-name").value;
70
+ const artistName = document.getElementById("artist-name").value;
71
+ const resultDiv = document.getElementById("result");
72
+ const accessToken = "{{ACCESS_TOKEN}}"; // Replaced server-side
73
+ const playlistId = "YOUR_PLAYLIST_ID"; // Replace with actual ID
74
+ if (!accessToken || accessToken === "Not authenticated") {
75
+ resultDiv.innerText = "Please authenticate with Spotify first.";
76
+ return;
77
+ }
78
+ try {
79
+ const trackUri = await getTrackUri(songName, accessToken, artistName);
80
+ const result = await addSongToPlaylist(playlistId, trackUri, accessToken);
81
+ resultDiv.innerText = result;
82
+ } catch (error) {
83
+ resultDiv.innerText = error.message;
84
+ }
85
+ }
86
+ </script>
87
+ """.replace("{{ACCESS_TOKEN}}", access_token or "Not authenticated")
88
 
89
  def login():
90
  auth_url = (
 
98
  if not code:
99
  return "Error: No authorization code provided", 400
100
 
 
101
  token_data = {
102
  "grant_type": "authorization_code",
103
  "code": code,
 
110
 
111
  if response.status_code == 200:
112
  access_token = token_json.get("access_token")
113
+ return redirect("/")
114
  else:
115
  return f"Error: {token_json.get('error_description', 'Failed to get access token')}", 400
116
 
117
+ # Gradio interface for server-side song addition (optional fallback)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  def gradio_interface(song_name="", artist_name=""):
119
+ if not access_token:
120
+ return "Error: Not authenticated. Please log in via /login."
121
+ if not song_name:
122
+ return "Please enter a song name."
123
+ try:
124
+ query = f"track:{song_name}"
125
+ if artist_name:
126
+ query += f" artist:{artist_name}"
127
+ url = f"https://api.spotify.com/v1/search?q={query}&type=track&limit=1"
128
+ headers = {"Authorization": f"Bearer {access_token}"}
129
+ response = requests.get(url, headers=headers)
130
+ data = response.json()
131
+ if not data.get("tracks", {}).get("items"):
132
+ return "Error: Song not found."
133
+ track_uri = data["tracks"]["items"][0]["uri"]
134
+
135
+ playlist_id = "YOUR_PLAYLIST_ID" # Replace with actual ID
136
+ url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
137
+ headers = {
138
+ "Authorization": f"Bearer {access_token}",
139
+ "Content-Type": "application/json",
140
+ }
141
+ data = {"uris": [track_uri], "position": 0}
142
+ response = requests.post(url, headers=headers, json=data)
143
+ if response.status_code == 201:
144
+ return f"Added '{song_name}' to playlist!"
145
+ return f"Error adding song: {response.json().get('error', {}).get('message', 'Unknown error')}"
146
+ except Exception as e:
147
+ return f"Error: {str(e)}"
148
+
149
+ # Create Gradio Blocks
150
+ demo = gr.Blocks()
151
+
152
+ # Define routes outside Blocks context
153
+ demo.route("/", home)
154
+ demo.route("/login", login)
155
+ demo.route("/callback", callback)
156
+
157
+ # Define Gradio UI
158
+ with demo:
159
  gr.Markdown("## Spotify Playlist Manager")
160
  with gr.Row():
161
  song_input = gr.Textbox(label="Song Name")
162
  artist_input = gr.Textbox(label="Artist Name (optional)")
163
  submit_button = gr.Button("Add Song to Playlist")
164
  output = gr.Textbox(label="Result")
 
 
 
 
 
 
 
 
165
  submit_button.click(
166
  fn=gradio_interface,
167
  inputs=[song_input, artist_input],