Manuel Zafra commited on
Commit
412755c
·
verified ·
1 Parent(s): 1d0ca9d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +257 -29
app.py CHANGED
@@ -1,23 +1,15 @@
1
- from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool
2
  import datetime
3
  import requests
4
  import pytz
5
  import yaml
 
 
 
 
6
  from tools.final_answer import FinalAnswerTool
7
 
8
- from Gradio_UI import GradioUI
9
-
10
- # Below is an example of a tool that does nothing. Amaze us with your creativity !
11
- @tool
12
- def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return type
13
- #Keep this format for the description / args / args description but feel free to modify the tool
14
- """A tool that does nothing yet
15
- Args:
16
- arg1: the first argument
17
- arg2: the second argument
18
- """
19
- return "What magic will you build ?"
20
-
21
  @tool
22
  def get_current_time_in_timezone(timezone: str) -> str:
23
  """A tool that fetches the current local time in a specified timezone.
@@ -33,30 +25,214 @@ def get_current_time_in_timezone(timezone: str) -> str:
33
  except Exception as e:
34
  return f"Error fetching time for timezone '{timezone}': {str(e)}"
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
- final_answer = FinalAnswerTool()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- # If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
40
- # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
 
 
42
  model = HfApiModel(
43
- max_tokens=2096,
44
- temperature=0.5,
45
- model_id='Qwen/Qwen2.5-Coder-32B-Instruct',# it is possible that this model may be overloaded
46
- custom_role_conversions=None,
47
  )
48
 
49
-
50
- # Import tool from Hub
51
- image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
52
-
53
  with open("prompts.yaml", 'r') as stream:
54
  prompt_templates = yaml.safe_load(stream)
55
-
56
  agent = CodeAgent(
57
  model=model,
58
- tools=[final_answer], ## add your tools here (don't remove final answer)
59
- max_steps=6,
 
 
 
 
 
 
60
  verbosity_level=1,
61
  grammar=None,
62
  planning_interval=None,
@@ -65,5 +241,57 @@ agent = CodeAgent(
65
  prompt_templates=prompt_templates
66
  )
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
- GradioUI(agent).launch()
 
1
+ from smolagents import CodeAgent, HfApiModel, tool
2
  import datetime
3
  import requests
4
  import pytz
5
  import yaml
6
+ import os
7
+ import pickle
8
+ import time
9
+ import gradio as gr
10
  from tools.final_answer import FinalAnswerTool
11
 
12
+ # Herramienta para obtener la hora actual en una zona horaria
 
 
 
 
 
 
 
 
 
 
 
 
13
  @tool
14
  def get_current_time_in_timezone(timezone: str) -> str:
15
  """A tool that fetches the current local time in a specified timezone.
 
25
  except Exception as e:
26
  return f"Error fetching time for timezone '{timezone}': {str(e)}"
27
 
28
+ # Herramienta para reconocer canciones usando AudD
29
+ @tool
30
+ def recognize_song(audio_path: str) -> dict:
31
+ """Reconoce una canción a partir de un archivo de audio
32
+ Args:
33
+ audio_path: ruta al archivo de audio a reconocer
34
+ """
35
+ AUDD_API_TOKEN = os.getenv("AUDD_API_TOKEN")
36
+
37
+ if not os.path.exists(audio_path):
38
+ return {"error": "El archivo de audio no existe"}
39
+
40
+ try:
41
+ with open(audio_path, 'rb') as file:
42
+ data = {
43
+ 'api_token': AUDD_API_TOKEN,
44
+ 'return': 'spotify,apple_music'
45
+ }
46
+ files = {
47
+ 'file': file
48
+ }
49
+ response = requests.post('https://api.audd.io/', data=data, files=files)
50
+
51
+ if response.status_code != 200:
52
+ return {"error": f"Error en la API: {response.status_code}"}
53
+
54
+ result = response.json()
55
+
56
+ if result['status'] == 'error':
57
+ return {"error": result['error']['error_message']}
58
+
59
+ if not result.get('result'):
60
+ return {"error": "No se pudo reconocer la canción"}
61
+
62
+ song_info = result['result']
63
+
64
+ return {
65
+ "🎶 Canción": song_info.get('title', 'Desconocido'),
66
+ "🎤 Artista": song_info.get('artist', 'Desconocido'),
67
+ "📀 Álbum": song_info.get('album', 'Desconocido'),
68
+ "🎧 Spotify": song_info.get('spotify', {}).get('external_urls', {}).get('spotify', 'No disponible'),
69
+ "🍏 Apple Music": song_info.get('apple_music', {}).get('url', 'No disponible')
70
+ }
71
+
72
+ except Exception as e:
73
+ return {"error": f"Error al procesar el audio: {str(e)}"}
74
 
75
+ # Herramienta para iniciar sesión en Soundeo
76
+ @tool
77
+ def login_soundeo() -> str:
78
+ """Inicia sesión en Soundeo usando las credenciales almacenadas en secrets"""
79
+ from selenium import webdriver
80
+ from selenium.webdriver.chrome.options import Options
81
+ from selenium.webdriver.common.by import By
82
+ from selenium.webdriver.support.ui import WebDriverWait
83
+ from selenium.webdriver.support import expected_conditions as EC
84
+
85
+ # Obtener credenciales de los secrets
86
+ username = os.getenv("SOUNDEO_USERNAME")
87
+ password = os.getenv("SOUNDEO_PASSWORD")
88
+
89
+ if not username or not password:
90
+ return "❌ No se encontraron las credenciales en los secrets"
91
+
92
+ # Configurar opciones de Chrome
93
+ chrome_options = Options()
94
+ chrome_options.add_argument("--headless")
95
+ chrome_options.add_argument("--no-sandbox")
96
+ chrome_options.add_argument("--disable-dev-shm-usage")
97
+ chrome_options.add_argument("--disable-gpu")
98
+
99
+ try:
100
+ # Inicializar el driver
101
+ driver = webdriver.Chrome(options=chrome_options)
102
+
103
+ # Navegar a Soundeo
104
+ driver.get("https://soundeo.com/login")
105
+ time.sleep(3) # Esperar a que cargue la página
106
+
107
+ # Capturar screenshot para debug
108
+ driver.save_screenshot("pre_login.png")
109
+
110
+ # Completar formulario de login
111
+ username_field = WebDriverWait(driver, 10).until(
112
+ EC.presence_of_element_located((By.ID, "username"))
113
+ )
114
+ username_field.send_keys(username)
115
+
116
+ password_field = driver.find_element(By.ID, "password")
117
+ password_field.send_keys(password)
118
+
119
+ # Hacer clic en el botón de login
120
+ login_button = driver.find_element(By.XPATH, "//button[@type='submit']")
121
+ login_button.click()
122
+
123
+ # Esperar a que se complete el login
124
+ time.sleep(5)
125
+
126
+ # Capturar screenshot para verificar
127
+ driver.save_screenshot("post_login.png")
128
+
129
+ # Guardar cookies para uso futuro
130
+ pickle.dump(driver.get_cookies(), open("soundeo_cookies.pkl", "wb"))
131
+
132
+ # Verificar si el login fue exitoso
133
+ if "dashboard" in driver.current_url or "account" in driver.current_url:
134
+ result = "✅ Login exitoso en Soundeo"
135
+ else:
136
+ result = "❌ Error al iniciar sesión. Verifica tus credenciales."
137
+
138
+ driver.quit()
139
+ return result
140
+
141
+ except Exception as e:
142
+ return f"❌ Error con Selenium: {str(e)}"
143
 
144
+ # Herramienta para buscar y añadir una canción a la lista de descarga
145
+ @tool
146
+ def add_song_to_download_list(song_title: str, artist: str) -> str:
147
+ """Busca una canción en Soundeo y la añade a la lista de descarga
148
+ Args:
149
+ song_title: título de la canción
150
+ artist: nombre del artista
151
+ """
152
+ from selenium import webdriver
153
+ from selenium.webdriver.chrome.options import Options
154
+ from selenium.webdriver.common.by import By
155
+ from selenium.webdriver.support.ui import WebDriverWait
156
+ from selenium.webdriver.support import expected_conditions as EC
157
+
158
+ chrome_options = Options()
159
+ chrome_options.add_argument("--headless")
160
+ chrome_options.add_argument("--no-sandbox")
161
+ chrome_options.add_argument("--disable-dev-shm-usage")
162
+ chrome_options.add_argument("--disable-gpu")
163
+
164
+ try:
165
+ driver = webdriver.Chrome(options=chrome_options)
166
+
167
+ # Cargar cookies si existen
168
+ cookies_file = "soundeo_cookies.pkl"
169
+ if os.path.exists(cookies_file):
170
+ driver.get("https://soundeo.com")
171
+ cookies = pickle.load(open(cookies_file, "rb"))
172
+ for cookie in cookies:
173
+ driver.add_cookie(cookie)
174
+ else:
175
+ driver.quit()
176
+ return "❌ No hay cookies de sesión. Primero debes iniciar sesión."
177
+
178
+ # Navegar a la búsqueda
179
+ search_query = f"{song_title} {artist}"
180
+ search_query = search_query.replace(" ", "+")
181
+ driver.get(f"https://soundeo.com/search?q={search_query}")
182
+ time.sleep(5)
183
+
184
+ # Capturar screenshot para debug
185
+ driver.save_screenshot("search_results.png")
186
+
187
+ # Buscar el primer resultado
188
+ try:
189
+ first_result = WebDriverWait(driver, 10).until(
190
+ EC.presence_of_element_located((By.CSS_SELECTOR, ".track-item"))
191
+ )
192
+
193
+ # Hacer clic en "Add to Download List"
194
+ download_button = first_result.find_element(By.CSS_SELECTOR, ".download-button")
195
+ download_button.click()
196
+
197
+ time.sleep(3)
198
+ driver.save_screenshot("added_to_list.png")
199
+
200
+ # Obtener información del track añadido
201
+ track_info = first_result.find_element(By.CSS_SELECTOR, ".track-title").text
202
+ artist_info = first_result.find_element(By.CSS_SELECTOR, ".track-artist").text
203
+
204
+ driver.quit()
205
+ return f"✅ Añadida a la lista de descarga: {track_info} - {artist_info}"
206
+
207
+ except Exception as e:
208
+ driver.quit()
209
+ return f"❌ No se encontraron resultados o no se pudo añadir: {str(e)}"
210
+
211
+ except Exception as e:
212
+ return f"❌ Error con Selenium: {str(e)}"
213
 
214
+ # Configuración del agente
215
+ final_answer = FinalAnswerTool()
216
  model = HfApiModel(
217
+ max_tokens=2096,
218
+ temperature=0.5,
219
+ model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
220
+ custom_role_conversions=None,
221
  )
222
 
 
 
 
 
223
  with open("prompts.yaml", 'r') as stream:
224
  prompt_templates = yaml.safe_load(stream)
225
+
226
  agent = CodeAgent(
227
  model=model,
228
+ tools=[
229
+ final_answer,
230
+ recognize_song,
231
+ login_soundeo,
232
+ add_song_to_download_list,
233
+ get_current_time_in_timezone
234
+ ],
235
+ max_steps=8,
236
  verbosity_level=1,
237
  grammar=None,
238
  planning_interval=None,
 
241
  prompt_templates=prompt_templates
242
  )
243
 
244
+ # Interfaz de usuario con Gradio
245
+ with gr.Blocks() as demo:
246
+ gr.Markdown("# 🎵 Asistente Musical - Reconocimiento y Descarga")
247
+
248
+ with gr.Tab("Reconocimiento de Música"):
249
+ with gr.Row():
250
+ audio_input = gr.Audio(type="filepath", label="Sube o graba un fragmento de audio")
251
+
252
+ query_input = gr.Textbox(
253
+ label="Consulta (opcional)",
254
+ placeholder="Reconoce esta canción y agrégala a mi lista de descarga"
255
+ )
256
+ submit_btn = gr.Button("Procesar")
257
+ output = gr.Markdown()
258
+
259
+ def process_with_agent(audio=None, text_query=""):
260
+ context = {}
261
+
262
+ if audio:
263
+ context["audio_path"] = audio
264
+ if not text_query:
265
+ text_query = "Reconoce esta canción y dame información detallada sobre ella."
266
+
267
+ if not text_query:
268
+ return "❌ Por favor ingresa una consulta o sube un archivo de audio."
269
+
270
+ try:
271
+ result = agent.run(text_query, context=context)
272
+ return result
273
+ except Exception as e:
274
+ return f"❌ Error al procesar la solicitud: {str(e)}"
275
+
276
+ submit_btn.click(
277
+ fn=process_with_agent,
278
+ inputs=[audio_input, query_input],
279
+ outputs=output
280
+ )
281
+
282
+ with gr.Tab("Login a Soundeo"):
283
+ info_text = gr.Markdown("Las credenciales se cargarán automáticamente desde los secrets")
284
+ login_btn = gr.Button("Iniciar Sesión en Soundeo")
285
+ login_output = gr.Markdown()
286
+
287
+ def login_process():
288
+ query = "Inicia sesión en Soundeo usando las credenciales almacenadas"
289
+ return agent.run(query)
290
+
291
+ login_btn.click(
292
+ fn=login_process,
293
+ inputs=[],
294
+ outputs=login_output
295
+ )
296
 
297
+ demo.launch()