Mthrfkr commited on
Commit
b5e6768
·
verified ·
1 Parent(s): 000977c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -142
app.py CHANGED
@@ -1,15 +1,11 @@
1
- import gradio as gr
2
  import requests
3
- import pandas as pd
4
  import time
5
- from tempfile import NamedTemporaryFile
6
- from openpyxl import Workbook
7
- import shutil
8
  from collections import deque
9
  from datetime import datetime, timedelta
10
 
11
  # Lista de credenciales de API de Spotify
12
- client_ids = [
13
  '37492f29c7fe478391e8fd8fe66f3f1b',
14
  'ac3c1dd6252740e68aeb0d7dd4e6e37d',
15
  '807008cb2ce041178c1871973fc81716',
@@ -19,7 +15,7 @@ client_ids = [
19
  '9df51caba5d247dc921b21de35a47c44',
20
  '191227c66e0d4be692bc8ee73ea6eb3d',
21
  'e272c0705c7c4fd68937c58adaa446ed'
22
- ]
23
  client_secrets = [
24
  'b61fa17afff64c8693ea5147b79562be',
25
  'ff49073ebd324e8cac2d997a8e34644c',
@@ -31,9 +27,12 @@ client_secrets = [
31
  '2d2a895d85874c088897dd9894dc64ad',
32
  '9fdfa58ea0a94ce7a0cb34fa19fb7d74'
33
  ]
 
34
  current_api_index = 0
35
  session = requests.Session()
36
- requests_queue = deque(maxlen=100)
 
 
37
 
38
  def obtener_token(client_id, client_secret):
39
  print(f"Obteniendo token de Spotify con client_id: {client_id}")
@@ -69,143 +68,50 @@ def obtener_nuevo_token():
69
  print(f"Nuevo token obtenido: {token}")
70
  return token
71
 
72
- def manejar_limite_peticiones():
73
- now = datetime.now()
74
- while requests_queue and now - requests_queue[0] > timedelta(minutes=1):
75
- requests_queue.popleft()
76
- if len(requests_queue) >= 100:
77
- print("Límite de 100 peticiones por minuto alcanzado, esperando...")
78
- time.sleep(60 - (now - requests_queue[0]).seconds)
79
- requests_queue.append(now)
80
-
81
- def realizar_solicitud(url, headers, params, reintentos=5):
82
- manejar_limite_peticiones()
83
- espera = 1 # Inicializar tiempo de espera en 1 segundo
84
- for i in range(reintentos):
85
- response = session.get(url, headers=headers, params=params)
 
 
 
 
 
 
 
86
  if response.status_code == 429:
87
- print(f"Límite de peticiones alcanzado, esperando {espera} segundos antes de reintentar...")
88
- time.sleep(espera)
89
- espera *= 2 # Incrementar espera de manera exponencial
90
- cerrar_y_reiniciar_sesion()
91
- headers['Authorization'] = f'Bearer {obtener_nuevo_token()}'
92
  else:
93
  return response
94
- print("Límite de reintentos alcanzado.")
95
- return None
96
 
97
- def buscar_playlists_spotify(token, query, limit=50):
98
- print("Buscando playlists en Spotify...")
99
  url = 'https://api.spotify.com/v1/search'
100
- headers = {'Authorization': f'Bearer {token}'}
101
- playlists = []
102
-
103
- try:
104
- if limit <= 50:
105
- params = {'q': query, 'type': 'playlist', 'limit': limit}
106
- response = realizar_solicitud(url, headers, params)
107
- if response:
108
- playlists.extend(response.json().get('playlists', {}).get('items', []))
109
- else:
110
- offset = 0
111
- while limit > 0:
112
- params = {'q': query, 'type': 'playlist', 'limit': min(50, limit), 'offset': offset}
113
- response = realizar_solicitud(url, headers, params)
114
- if response:
115
- playlists.extend(response.json().get('playlists', {}).get('items', []))
116
- limit -= min(50, limit)
117
- offset += 50
118
- except Exception as e:
119
- print(f"Error al buscar playlists: {e}")
120
 
121
- return [{'playlist_id': playlist['id'], 'playlist_name': playlist['name']} for playlist in playlists]
122
-
123
- def obtener_canciones_playlist_spotify(token, playlist_id, playlist_name):
124
- print(f"Obteniendo canciones de la playlist {playlist_id} ({playlist_name}) de Spotify...")
125
- url = f'https://api.spotify.com/v1/playlists/{playlist_id}/tracks'
126
- headers = {'Authorization': f'Bearer {token}'}
127
- canciones = []
128
-
129
- try:
130
- response = realizar_solicitud(url, headers, {})
131
- if response and response.status_code == 200:
132
- tracks = response.json().get('items')
133
- for item in tracks:
134
- track = item.get('track')
135
- if track:
136
- audio_features = obtener_caracteristicas_audio(token, track['id'])
137
- canciones.append({
138
- 'playlist_name': playlist_name,
139
- 'artista': track['artists'][0]['name'] if track['artists'] else 'Desconocido',
140
- 'titulo': track['name'],
141
- 'isrc': track['external_ids'].get('isrc', 'No disponible'),
142
- 'popularity': track.get('popularity', 'No disponible'),
143
- 'valence': audio_features.get('valence', 'No disponible'),
144
- 'danceability': audio_features.get('danceability', 'No disponible'),
145
- 'energy': audio_features.get('energy', 'No disponible'),
146
- 'tempo': audio_features.get('tempo', 'No disponible'),
147
- 'speechiness': audio_features.get('speechiness', 'No disponible'),
148
- 'instrumentalness': audio_features.get('instrumentalness', 'No disponible'),
149
- 'duration': track.get('duration_ms', 'No disponible'),
150
- 'release_year': track.get('album', {}).get('release_date', 'No disponible').split('-')[0] if track.get('album', {}).get('release_date') else 'No disponible',
151
- 'record_label': obtener_record_label_spotify(track['album']['id'], token)
152
- })
153
- except Exception as e:
154
- print(f"Error al obtener canciones de la playlist: {e}")
155
-
156
- return canciones
157
-
158
- def obtener_caracteristicas_audio(token, track_id):
159
- url = f'https://api.spotify.com/v1/audio-features/{track_id}'
160
- headers = {'Authorization': f'Bearer {token}'}
161
- response = realizar_solicitud(url, headers, {})
162
- return response.json() if response and response.status_code == 200 else {}
163
-
164
- def obtener_record_label_spotify(album_id, token):
165
- url = f'https://api.spotify.com/v1/albums/{album_id}'
166
- headers = {'Authorization': f'Bearer {token}'}
167
- response = realizar_solicitud(url, headers, {})
168
- album_info = response.json() if response and response.status_code == 200 else {}
169
- return album_info.get('label', 'No disponible')
170
-
171
- def interface(project_name, query, num_spotify_playlists=50):
172
- # Obtener tokens y claves
173
- token_spotify = obtener_nuevo_token()
174
- if not token_spotify:
175
- return pd.DataFrame(), "Error obteniendo el token de Spotify. Intenta de nuevo."
176
-
177
- playlists_spotify = buscar_playlists_spotify(token_spotify, query, num_spotify_playlists)
178
- canciones_spotify = []
179
- for playlist in playlists_spotify:
180
- songs = obtener_canciones_playlist_spotify(token_spotify, playlist['playlist_id'], playlist['playlist_name'])
181
- canciones_spotify.extend(songs)
182
-
183
- # Crear DataFrame
184
- df = pd.DataFrame(canciones_spotify)
185
- df.rename(columns={'isrc': 'ISRCs'}, inplace=True)
186
-
187
- # Ordenar por popularidad
188
- df.sort_values(by=['popularity'], ascending=False, inplace=True)
189
-
190
- # Guardar DataFrame en un archivo Excel
191
- with NamedTemporaryFile(delete=False, suffix='.xlsx') as tmpfile:
192
- df.to_excel(tmpfile.name, index=False)
193
- project_file_name = f"{project_name}.xlsx"
194
- shutil.move(tmpfile.name, project_file_name)
195
-
196
- return df, project_file_name # Devuelve el DataFrame y el enlace al archivo Excel
197
-
198
- # Configuración de Gradio
199
- iface = gr.Interface(
200
- fn=interface,
201
- inputs=[
202
- gr.Textbox(label="Nombre del Proyecto"),
203
- gr.Textbox(label="Keywords - Palabras Clave para tu búsqueda"),
204
- gr.Number(label="Numero de Playlists que vamos a buscar con estas Keywords", value=50, minimum=1, maximum=1000)
205
- ],
206
- outputs=[gr.Dataframe(), gr.File(label="Download Excel")],
207
- title="Spotify Playlist Fetcher",
208
- description="Introduce una consulta de búsqueda para obtener playlists y sus canciones de Spotify. Las credenciales del cliente están preconfiguradas."
209
- )
210
-
211
- iface.launch()
 
1
+
2
  import requests
 
3
  import time
 
 
 
4
  from collections import deque
5
  from datetime import datetime, timedelta
6
 
7
  # Lista de credenciales de API de Spotify
8
+ client_ids =[
9
  '37492f29c7fe478391e8fd8fe66f3f1b',
10
  'ac3c1dd6252740e68aeb0d7dd4e6e37d',
11
  '807008cb2ce041178c1871973fc81716',
 
15
  '9df51caba5d247dc921b21de35a47c44',
16
  '191227c66e0d4be692bc8ee73ea6eb3d',
17
  'e272c0705c7c4fd68937c58adaa446ed'
18
+ ]
19
  client_secrets = [
20
  'b61fa17afff64c8693ea5147b79562be',
21
  'ff49073ebd324e8cac2d997a8e34644c',
 
27
  '2d2a895d85874c088897dd9894dc64ad',
28
  '9fdfa58ea0a94ce7a0cb34fa19fb7d74'
29
  ]
30
+
31
  current_api_index = 0
32
  session = requests.Session()
33
+
34
+ # Registro de peticiones en los últimos 60 minutos
35
+ request_log = deque()
36
 
37
  def obtener_token(client_id, client_secret):
38
  print(f"Obteniendo token de Spotify con client_id: {client_id}")
 
68
  print(f"Nuevo token obtenido: {token}")
69
  return token
70
 
71
+ def registrar_peticion():
72
+ ahora = datetime.now()
73
+ request_log.append(ahora)
74
+ # Remover peticiones que tienen más de 60 minutos
75
+ while request_log and (ahora - request_log[0]) > timedelta(minutes=60):
76
+ request_log.popleft()
77
+
78
+ def realizar_solicitud(url, params, token):
79
+ headers = {'Authorization': f'Bearer {token}'}
80
+ response = session.get(url, headers=headers, params=params)
81
+ registrar_peticion()
82
+ return response
83
+
84
+ def realizar_solicitud_con_reintento(url, params):
85
+ token = obtener_nuevo_token()
86
+ espera = 1
87
+
88
+ while True:
89
+ response = realizar_solicitud(url, params, token)
90
+ print(f"Solicitud realizada. Código de estado: {response.status_code}")
91
+
92
  if response.status_code == 429:
93
+ retry_after = int(response.headers.get('Retry-After', espera))
94
+ espera *= 2 # Incremento exponencial
95
+ print(f"Límite de peticiones alcanzado, esperando {retry_after} segundos antes de reintentar...")
96
+ time.sleep(retry_after)
97
+ token = obtener_nuevo_token() # Obtener un nuevo token después de esperar
98
  else:
99
  return response
 
 
100
 
101
+ # Ejemplo de uso
102
+ def main():
103
  url = 'https://api.spotify.com/v1/search'
104
+ params = {'q': 'rancheras', 'type': 'playlist', 'limit': 40}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
+ print("Realizando primera solicitud...")
107
+ response = realizar_solicitud_con_reintento(url, params)
108
+ print("Respuesta de la primera solicitud:", response.json())
109
+
110
+ # Simular cambio de API key después de recibir un código 429
111
+ if response.status_code == 429:
112
+ print("Límite de peticiones alcanzado, cambiando API key y realizando una nueva solicitud...")
113
+ response = realizar_solicitud_con_reintento(url, params)
114
+ print("Respuesta de la segunda solicitud:", response.json())
115
+
116
+ if __name__ == "__main__":
117
+ main()