Download app.py from Mthrfkr/Busca-Playlists-con-Keywords-Open-test: direct link, hf CLI and curl.
- Browser
- Download file 7.36 kB
-
https://huggingface.co/spaces/Mthrfkr/Busca-Playlists-con-Keywords-Open-test/resolve/main/app.py
- Command line
-
hf download hf://spaces/Mthrfkr/Busca-Playlists-con-Keywords-Open-test/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Mthrfkr/Busca-Playlists-con-Keywords-Open-test/resolve/main/app.py
7.36 kB
| import gradio as gr | |
| import requests | |
| import pandas as pd | |
| from tempfile import NamedTemporaryFile | |
| import shutil | |
| import os | |
| # Funciones para Spotify | |
| def obtener_token(client_id, client_secret): | |
| print("Obteniendo token de Spotify...") | |
| url = 'https://accounts.spotify.com/api/token' | |
| headers = {'Content-Type': 'application/x-www-form-urlencoded'} | |
| payload = {'grant_type': 'client_credentials'} | |
| response = requests.post(url, headers=headers, data=payload, auth=(client_id, client_secret)) | |
| return response.json().get('access_token') | |
| def buscar_playlists_spotify(token, query, limit=50): | |
| print("Buscando playlists en Spotify...") | |
| url = 'https://api.spotify.com/v1/search' | |
| headers = {'Authorization': f'Bearer {token}'} | |
| playlists = [] | |
| if limit <= 50: | |
| params = {'q': query, 'type': 'playlist', 'limit': limit} | |
| response = requests.get(url, headers=headers, params=params) | |
| if response.status_code != 200: | |
| print(f"Error en la solicitud a Spotify: {response.status_code}") | |
| print(response.json()) | |
| return [] | |
| items = response.json().get('playlists', {}).get('items', []) | |
| items = [item for item in items if item is not None] | |
| playlists.extend(items) | |
| else: | |
| offset = 0 | |
| while limit > 0: | |
| params = {'q': query, 'type': 'playlist', 'limit': min(50, limit), 'offset': offset} | |
| response = requests.get(url, headers=headers, params=params) | |
| if response.status_code != 200: | |
| print(f"Error en la solicitud a Spotify: {response.status_code}") | |
| print(response.json()) | |
| break | |
| items = response.json().get('playlists', {}).get('items', []) | |
| items = [item for item in items if item is not None] | |
| playlists.extend(items) | |
| fetched = len(items) | |
| limit -= fetched | |
| offset += fetched | |
| if fetched == 0: | |
| break | |
| valid_playlists = [] | |
| for playlist in playlists: | |
| if playlist is not None and 'id' in playlist and 'name' in playlist: | |
| valid_playlists.append({ | |
| 'playlist_id': playlist['id'], | |
| 'playlist_name': playlist['name'] | |
| }) | |
| return valid_playlists | |
| def obtener_canciones_playlist_spotify(token, playlist_id, playlist_name): | |
| print(f"Obteniendo canciones de la playlist {playlist_id} de Spotify...") | |
| url = f'https://api.spotify.com/v1/playlists/{playlist_id}/tracks' | |
| headers = {'Authorization': f'Bearer {token}'} | |
| response = requests.get(url, headers=headers) | |
| canciones = [] | |
| if response.status_code == 200: | |
| tracks = response.json().get('items', []) | |
| for item in tracks: | |
| track = item.get('track') | |
| if track: | |
| artista_info = {} | |
| if track['artists']: | |
| artista_info = obtener_info_artista(track['artists'][0]['id'], token) | |
| record_label = obtener_record_label_spotify(track['album']['id'], token) if track.get('album') else 'No disponible' | |
| canciones.append({ | |
| 'playlist_name': playlist_name, | |
| 'artista': track['artists'][0]['name'] if track['artists'] else 'Desconocido', | |
| 'titulo': track['name'], | |
| 'isrc': track.get('external_ids', {}).get('isrc', 'No disponible'), | |
| 'popularity': track.get('popularity', 'No disponible'), | |
| 'track_id': track['id'], | |
| 'link': track.get('external_urls', {}).get('spotify', 'No disponible'), | |
| 'record_label': record_label, | |
| 'source': 'Spotify', | |
| 'genero_artista': ', '.join(artista_info.get('genres', [])) if artista_info else 'No disponible' | |
| }) | |
| return canciones | |
| def obtener_caracteristicas_audio(token, track_ids): | |
| print("Obteniendo características de audio para las pistas...") | |
| url = f'https://api.spotify.com/v1/audio-features' | |
| headers = {'Authorization': f'Bearer {token}'} | |
| params = {'ids': ','.join(track_ids)} | |
| response = requests.get(url, headers=headers, params=params) | |
| return response.json().get('audio_features', []) if response.status_code == 200 else [] | |
| def obtener_record_label_spotify(album_id, token): | |
| url = f'https://api.spotify.com/v1/albums/{album_id}' | |
| headers = {'Authorization': f'Bearer {token}'} | |
| response = requests.get(url, headers=headers) | |
| return response.json().get('label', 'No disponible') if response.status_code == 200 else 'No disponible' | |
| def obtener_info_artista(artista_id, token): | |
| url = f'https://api.spotify.com/v1/artists/{artista_id}' | |
| headers = {'Authorization': f'Bearer {token}'} | |
| response = requests.get(url, headers=headers) | |
| return response.json() if response.status_code == 200 else {} | |
| def interface(query, num_spotify_playlists=50, project_name="Proyecto"): | |
| client_id = os.getenv('Spotify_ID') | |
| client_secret = os.getenv('Spotify_client') | |
| token_spotify = obtener_token(client_id, client_secret) | |
| if not token_spotify: | |
| raise gr.Error("Failed to obtain Spotify token. Check client ID and secret.") | |
| playlists_spotify = buscar_playlists_spotify(token_spotify, query, num_spotify_playlists) | |
| canciones_spotify = [] | |
| track_ids = [] | |
| for playlist in playlists_spotify: | |
| songs = obtener_canciones_playlist_spotify(token_spotify, playlist['playlist_id'], playlist['playlist_name']) | |
| canciones_spotify.extend(songs) | |
| track_ids.extend([song['track_id'] for song in songs if song.get('track_id')]) | |
| audio_features_list = obtener_caracteristicas_audio(token_spotify, track_ids) | |
| audio_features_dict = {af['id']: af for af in audio_features_list if af} | |
| for song in canciones_spotify: | |
| audio_features = audio_features_dict.get(song['track_id'], {}) | |
| song.update({ | |
| 'valence': audio_features.get('valence', 'No disponible'), | |
| 'danceability': audio_features.get('danceability', 'No disponible'), | |
| 'energy': audio_features.get('energy', 'No disponible'), | |
| 'tempo': audio_features.get('tempo', 'No disponible'), | |
| 'speechiness': audio_features.get('speechiness', 'No disponible'), | |
| 'instrumentalness': audio_features.get('instrumentalness', 'No disponible') | |
| }) | |
| df = pd.DataFrame(canciones_spotify) | |
| df.rename(columns={'isrc': 'ISRCs'}, inplace=True) | |
| df.sort_values(by=['popularity'], ascending=False, inplace=True) | |
| with NamedTemporaryFile(delete=False, suffix='.xlsx') as tmpfile: | |
| df.to_excel(tmpfile.name, index=False) | |
| project_filename = f"{project_name}.xlsx" | |
| shutil.move(tmpfile.name, project_filename) | |
| return df, project_filename | |
| iface = gr.Interface( | |
| fn=interface, | |
| inputs=[ | |
| gr.Textbox(label="Keywords o Títulos de Playlists"), | |
| gr.Number(label="Número de playlists que queremos buscar", value=50, minimum=1, maximum=1000), | |
| gr.Textbox(label="Nombre del proyecto") | |
| ], | |
| outputs=[gr.Dataframe(), gr.File(label="Descargar Excel")], | |
| title="Busca Playlists con Keywords", | |
| description="Ingresa tu búsqueda para encontrar playlists en Spotify con esas palabras en sus títulos." | |
| ) | |
| iface.launch() |