Update app.py
Browse files
app.py
CHANGED
|
@@ -23,17 +23,39 @@ def buscar_playlists_spotify(token, query, limit=50):
|
|
| 23 |
if limit <= 50:
|
| 24 |
params = {'q': query, 'type': 'playlist', 'limit': limit}
|
| 25 |
response = requests.get(url, headers=headers, params=params)
|
| 26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
else:
|
| 28 |
offset = 0
|
| 29 |
while limit > 0:
|
| 30 |
params = {'q': query, 'type': 'playlist', 'limit': min(50, limit), 'offset': offset}
|
| 31 |
response = requests.get(url, headers=headers, params=params)
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
|
| 38 |
def obtener_canciones_playlist_spotify(token, playlist_id, playlist_name):
|
| 39 |
print(f"Obteniendo canciones de la playlist {playlist_id} de Spotify...")
|
|
@@ -42,22 +64,25 @@ def obtener_canciones_playlist_spotify(token, playlist_id, playlist_name):
|
|
| 42 |
response = requests.get(url, headers=headers)
|
| 43 |
canciones = []
|
| 44 |
if response.status_code == 200:
|
| 45 |
-
tracks = response.json().get('items')
|
| 46 |
for item in tracks:
|
| 47 |
track = item.get('track')
|
| 48 |
if track:
|
| 49 |
-
artista_info =
|
|
|
|
|
|
|
|
|
|
| 50 |
canciones.append({
|
| 51 |
'playlist_name': playlist_name,
|
| 52 |
'artista': track['artists'][0]['name'] if track['artists'] else 'Desconocido',
|
| 53 |
'titulo': track['name'],
|
| 54 |
-
'isrc': track
|
| 55 |
'popularity': track.get('popularity', 'No disponible'),
|
| 56 |
'track_id': track['id'],
|
| 57 |
-
'link': track
|
| 58 |
-
'record_label':
|
| 59 |
'source': 'Spotify',
|
| 60 |
-
'genero_artista': ', '.join(artista_info.get('genres', []))
|
| 61 |
})
|
| 62 |
return canciones
|
| 63 |
|
|
@@ -67,49 +92,39 @@ def obtener_caracteristicas_audio(token, track_ids):
|
|
| 67 |
headers = {'Authorization': f'Bearer {token}'}
|
| 68 |
params = {'ids': ','.join(track_ids)}
|
| 69 |
response = requests.get(url, headers=headers, params=params)
|
| 70 |
-
if response.status_code == 200
|
| 71 |
-
return response.json().get('audio_features', [])
|
| 72 |
-
else:
|
| 73 |
-
print(f"No se pudieron obtener las características de audio para las pistas {track_ids}")
|
| 74 |
-
return []
|
| 75 |
|
| 76 |
def obtener_record_label_spotify(album_id, token):
|
| 77 |
url = f'https://api.spotify.com/v1/albums/{album_id}'
|
| 78 |
headers = {'Authorization': f'Bearer {token}'}
|
| 79 |
response = requests.get(url, headers=headers)
|
| 80 |
-
|
| 81 |
-
return album_info.get('label', 'No disponible')
|
| 82 |
|
| 83 |
def obtener_info_artista(artista_id, token):
|
| 84 |
url = f'https://api.spotify.com/v1/artists/{artista_id}'
|
| 85 |
headers = {'Authorization': f'Bearer {token}'}
|
| 86 |
response = requests.get(url, headers=headers)
|
| 87 |
-
|
| 88 |
-
return {
|
| 89 |
-
'genres': artista_info.get('genres', [])
|
| 90 |
-
}
|
| 91 |
|
| 92 |
-
# Función principal de la interfaz
|
| 93 |
def interface(query, num_spotify_playlists=50, project_name="Proyecto"):
|
| 94 |
-
# Obtener tokens y claves
|
| 95 |
client_id = os.getenv('Spotify_ID')
|
| 96 |
client_secret = os.getenv('Spotify_client')
|
| 97 |
|
| 98 |
-
# Spotify
|
| 99 |
token_spotify = obtener_token(client_id, client_secret)
|
|
|
|
|
|
|
|
|
|
| 100 |
playlists_spotify = buscar_playlists_spotify(token_spotify, query, num_spotify_playlists)
|
| 101 |
canciones_spotify = []
|
| 102 |
track_ids = []
|
| 103 |
for playlist in playlists_spotify:
|
| 104 |
songs = obtener_canciones_playlist_spotify(token_spotify, playlist['playlist_id'], playlist['playlist_name'])
|
| 105 |
canciones_spotify.extend(songs)
|
| 106 |
-
track_ids.extend([song['track_id'] for song in songs])
|
| 107 |
|
| 108 |
-
# Obtener características de audio en un solo paso
|
| 109 |
audio_features_list = obtener_caracteristicas_audio(token_spotify, track_ids)
|
| 110 |
audio_features_dict = {af['id']: af for af in audio_features_list if af}
|
| 111 |
|
| 112 |
-
# Añadir características de audio a las canciones
|
| 113 |
for song in canciones_spotify:
|
| 114 |
audio_features = audio_features_dict.get(song['track_id'], {})
|
| 115 |
song.update({
|
|
@@ -121,20 +136,16 @@ def interface(query, num_spotify_playlists=50, project_name="Proyecto"):
|
|
| 121 |
'instrumentalness': audio_features.get('instrumentalness', 'No disponible')
|
| 122 |
})
|
| 123 |
|
| 124 |
-
# Crear DataFrame
|
| 125 |
df = pd.DataFrame(canciones_spotify)
|
| 126 |
df.rename(columns={'isrc': 'ISRCs'}, inplace=True)
|
| 127 |
-
|
| 128 |
-
# Ordenar por popularidad
|
| 129 |
df.sort_values(by=['popularity'], ascending=False, inplace=True)
|
| 130 |
|
| 131 |
with NamedTemporaryFile(delete=False, suffix='.xlsx') as tmpfile:
|
| 132 |
df.to_excel(tmpfile.name, index=False)
|
| 133 |
project_filename = f"{project_name}.xlsx"
|
| 134 |
shutil.move(tmpfile.name, project_filename)
|
| 135 |
-
return df, project_filename
|
| 136 |
|
| 137 |
-
# Configuración de Gradio
|
| 138 |
iface = gr.Interface(
|
| 139 |
fn=interface,
|
| 140 |
inputs=[
|
|
@@ -146,4 +157,4 @@ iface = gr.Interface(
|
|
| 146 |
title="Busca Playlists con Keywords",
|
| 147 |
description="Ingresa tu búsqueda para encontrar playlists en Spotify con esas palabras en sus títulos."
|
| 148 |
)
|
| 149 |
-
iface.launch()
|
|
|
|
| 23 |
if limit <= 50:
|
| 24 |
params = {'q': query, 'type': 'playlist', 'limit': limit}
|
| 25 |
response = requests.get(url, headers=headers, params=params)
|
| 26 |
+
if response.status_code != 200:
|
| 27 |
+
print(f"Error en la solicitud a Spotify: {response.status_code}")
|
| 28 |
+
print(response.json())
|
| 29 |
+
return []
|
| 30 |
+
items = response.json().get('playlists', {}).get('items', [])
|
| 31 |
+
items = [item for item in items if item is not None]
|
| 32 |
+
playlists.extend(items)
|
| 33 |
else:
|
| 34 |
offset = 0
|
| 35 |
while limit > 0:
|
| 36 |
params = {'q': query, 'type': 'playlist', 'limit': min(50, limit), 'offset': offset}
|
| 37 |
response = requests.get(url, headers=headers, params=params)
|
| 38 |
+
if response.status_code != 200:
|
| 39 |
+
print(f"Error en la solicitud a Spotify: {response.status_code}")
|
| 40 |
+
print(response.json())
|
| 41 |
+
break
|
| 42 |
+
items = response.json().get('playlists', {}).get('items', [])
|
| 43 |
+
items = [item for item in items if item is not None]
|
| 44 |
+
playlists.extend(items)
|
| 45 |
+
fetched = len(items)
|
| 46 |
+
limit -= fetched
|
| 47 |
+
offset += fetched
|
| 48 |
+
if fetched == 0:
|
| 49 |
+
break
|
| 50 |
+
|
| 51 |
+
valid_playlists = []
|
| 52 |
+
for playlist in playlists:
|
| 53 |
+
if playlist is not None and 'id' in playlist and 'name' in playlist:
|
| 54 |
+
valid_playlists.append({
|
| 55 |
+
'playlist_id': playlist['id'],
|
| 56 |
+
'playlist_name': playlist['name']
|
| 57 |
+
})
|
| 58 |
+
return valid_playlists
|
| 59 |
|
| 60 |
def obtener_canciones_playlist_spotify(token, playlist_id, playlist_name):
|
| 61 |
print(f"Obteniendo canciones de la playlist {playlist_id} de Spotify...")
|
|
|
|
| 64 |
response = requests.get(url, headers=headers)
|
| 65 |
canciones = []
|
| 66 |
if response.status_code == 200:
|
| 67 |
+
tracks = response.json().get('items', [])
|
| 68 |
for item in tracks:
|
| 69 |
track = item.get('track')
|
| 70 |
if track:
|
| 71 |
+
artista_info = {}
|
| 72 |
+
if track['artists']:
|
| 73 |
+
artista_info = obtener_info_artista(track['artists'][0]['id'], token)
|
| 74 |
+
record_label = obtener_record_label_spotify(track['album']['id'], token) if track.get('album') else 'No disponible'
|
| 75 |
canciones.append({
|
| 76 |
'playlist_name': playlist_name,
|
| 77 |
'artista': track['artists'][0]['name'] if track['artists'] else 'Desconocido',
|
| 78 |
'titulo': track['name'],
|
| 79 |
+
'isrc': track.get('external_ids', {}).get('isrc', 'No disponible'),
|
| 80 |
'popularity': track.get('popularity', 'No disponible'),
|
| 81 |
'track_id': track['id'],
|
| 82 |
+
'link': track.get('external_urls', {}).get('spotify', 'No disponible'),
|
| 83 |
+
'record_label': record_label,
|
| 84 |
'source': 'Spotify',
|
| 85 |
+
'genero_artista': ', '.join(artista_info.get('genres', [])) if artista_info else 'No disponible'
|
| 86 |
})
|
| 87 |
return canciones
|
| 88 |
|
|
|
|
| 92 |
headers = {'Authorization': f'Bearer {token}'}
|
| 93 |
params = {'ids': ','.join(track_ids)}
|
| 94 |
response = requests.get(url, headers=headers, params=params)
|
| 95 |
+
return response.json().get('audio_features', []) if response.status_code == 200 else []
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
def obtener_record_label_spotify(album_id, token):
|
| 98 |
url = f'https://api.spotify.com/v1/albums/{album_id}'
|
| 99 |
headers = {'Authorization': f'Bearer {token}'}
|
| 100 |
response = requests.get(url, headers=headers)
|
| 101 |
+
return response.json().get('label', 'No disponible') if response.status_code == 200 else 'No disponible'
|
|
|
|
| 102 |
|
| 103 |
def obtener_info_artista(artista_id, token):
|
| 104 |
url = f'https://api.spotify.com/v1/artists/{artista_id}'
|
| 105 |
headers = {'Authorization': f'Bearer {token}'}
|
| 106 |
response = requests.get(url, headers=headers)
|
| 107 |
+
return response.json() if response.status_code == 200 else {}
|
|
|
|
|
|
|
|
|
|
| 108 |
|
|
|
|
| 109 |
def interface(query, num_spotify_playlists=50, project_name="Proyecto"):
|
|
|
|
| 110 |
client_id = os.getenv('Spotify_ID')
|
| 111 |
client_secret = os.getenv('Spotify_client')
|
| 112 |
|
|
|
|
| 113 |
token_spotify = obtener_token(client_id, client_secret)
|
| 114 |
+
if not token_spotify:
|
| 115 |
+
raise gr.Error("Failed to obtain Spotify token. Check client ID and secret.")
|
| 116 |
+
|
| 117 |
playlists_spotify = buscar_playlists_spotify(token_spotify, query, num_spotify_playlists)
|
| 118 |
canciones_spotify = []
|
| 119 |
track_ids = []
|
| 120 |
for playlist in playlists_spotify:
|
| 121 |
songs = obtener_canciones_playlist_spotify(token_spotify, playlist['playlist_id'], playlist['playlist_name'])
|
| 122 |
canciones_spotify.extend(songs)
|
| 123 |
+
track_ids.extend([song['track_id'] for song in songs if song.get('track_id')])
|
| 124 |
|
|
|
|
| 125 |
audio_features_list = obtener_caracteristicas_audio(token_spotify, track_ids)
|
| 126 |
audio_features_dict = {af['id']: af for af in audio_features_list if af}
|
| 127 |
|
|
|
|
| 128 |
for song in canciones_spotify:
|
| 129 |
audio_features = audio_features_dict.get(song['track_id'], {})
|
| 130 |
song.update({
|
|
|
|
| 136 |
'instrumentalness': audio_features.get('instrumentalness', 'No disponible')
|
| 137 |
})
|
| 138 |
|
|
|
|
| 139 |
df = pd.DataFrame(canciones_spotify)
|
| 140 |
df.rename(columns={'isrc': 'ISRCs'}, inplace=True)
|
|
|
|
|
|
|
| 141 |
df.sort_values(by=['popularity'], ascending=False, inplace=True)
|
| 142 |
|
| 143 |
with NamedTemporaryFile(delete=False, suffix='.xlsx') as tmpfile:
|
| 144 |
df.to_excel(tmpfile.name, index=False)
|
| 145 |
project_filename = f"{project_name}.xlsx"
|
| 146 |
shutil.move(tmpfile.name, project_filename)
|
| 147 |
+
return df, project_filename
|
| 148 |
|
|
|
|
| 149 |
iface = gr.Interface(
|
| 150 |
fn=interface,
|
| 151 |
inputs=[
|
|
|
|
| 157 |
title="Busca Playlists con Keywords",
|
| 158 |
description="Ingresa tu búsqueda para encontrar playlists en Spotify con esas palabras en sus títulos."
|
| 159 |
)
|
| 160 |
+
iface.launch()
|