Spaces:
Sleeping
Sleeping
from smolagents import CodeAgent, HfApiModel, tool | |
import datetime | |
import requests | |
import pytz | |
import yaml | |
import os | |
import pickle | |
import time | |
import gradio as gr | |
from tools.final_answer import FinalAnswerTool | |
# Herramienta para obtener la hora actual en una zona horaria | |
def get_current_time_in_timezone(timezone: str) -> str: | |
"""A tool that fetches the current local time in a specified timezone. | |
Args: | |
timezone: A string representing a valid timezone (e.g., 'America/New_York'). | |
""" | |
try: | |
# Create timezone object | |
tz = pytz.timezone(timezone) | |
# Get current time in that timezone | |
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S") | |
return f"The current local time in {timezone} is: {local_time}" | |
except Exception as e: | |
return f"Error fetching time for timezone '{timezone}': {str(e)}" | |
# Herramienta para reconocer canciones usando AudD | |
def recognize_song(audio_path: str) -> dict: | |
"""Reconoce una canción a partir de un archivo de audio | |
Args: | |
audio_path: ruta al archivo de audio a reconocer | |
""" | |
AUDD_API_TOKEN = os.getenv("AUDD_API_TOKEN") | |
if not os.path.exists(audio_path): | |
return {"error": "El archivo de audio no existe"} | |
try: | |
with open(audio_path, 'rb') as file: | |
data = { | |
'api_token': AUDD_API_TOKEN, | |
'return': 'spotify,apple_music' | |
} | |
files = { | |
'file': file | |
} | |
response = requests.post('https://api.audd.io/', data=data, files=files) | |
if response.status_code != 200: | |
return {"error": f"Error en la API: {response.status_code}"} | |
result = response.json() | |
if result['status'] == 'error': | |
return {"error": result['error']['error_message']} | |
if not result.get('result'): | |
return {"error": "No se pudo reconocer la canción"} | |
song_info = result['result'] | |
return { | |
"🎶 Canción": song_info.get('title', 'Desconocido'), | |
"🎤 Artista": song_info.get('artist', 'Desconocido'), | |
"📀 Álbum": song_info.get('album', 'Desconocido'), | |
"🎧 Spotify": song_info.get('spotify', {}).get('external_urls', {}).get('spotify', 'No disponible'), | |
"🍏 Apple Music": song_info.get('apple_music', {}).get('url', 'No disponible') | |
} | |
except Exception as e: | |
return {"error": f"Error al procesar el audio: {str(e)}"} | |
# Herramienta para iniciar sesión en Soundeo | |
def login_soundeo() -> str: | |
"""Inicia sesión en Soundeo usando las credenciales almacenadas en secrets""" | |
from selenium import webdriver | |
from selenium.webdriver.chrome.options import Options | |
from selenium.webdriver.common.by import By | |
from selenium.webdriver.support.ui import WebDriverWait | |
from selenium.webdriver.support import expected_conditions as EC | |
# Obtener credenciales de los secrets | |
username = os.getenv("SOUNDEO_USERNAME") | |
password = os.getenv("SOUNDEO_PASSWORD") | |
if not username or not password: | |
return "❌ No se encontraron las credenciales en los secrets" | |
# Configurar opciones de Chrome | |
chrome_options = Options() | |
chrome_options.add_argument("--headless") | |
chrome_options.add_argument("--no-sandbox") | |
chrome_options.add_argument("--disable-dev-shm-usage") | |
chrome_options.add_argument("--disable-gpu") | |
try: | |
# Inicializar el driver | |
driver = webdriver.Chrome(options=chrome_options) | |
# Navegar a Soundeo | |
driver.get("https://soundeo.com/login") | |
time.sleep(3) # Esperar a que cargue la página | |
# Capturar screenshot para debug | |
driver.save_screenshot("pre_login.png") | |
# Completar formulario de login | |
username_field = WebDriverWait(driver, 10).until( | |
EC.presence_of_element_located((By.ID, "username")) | |
) | |
username_field.send_keys(username) | |
password_field = driver.find_element(By.ID, "password") | |
password_field.send_keys(password) | |
# Hacer clic en el botón de login | |
login_button = driver.find_element(By.XPATH, "//button[@type='submit']") | |
login_button.click() | |
# Esperar a que se complete el login | |
time.sleep(5) | |
# Capturar screenshot para verificar | |
driver.save_screenshot("post_login.png") | |
# Guardar cookies para uso futuro | |
pickle.dump(driver.get_cookies(), open("soundeo_cookies.pkl", "wb")) | |
# Verificar si el login fue exitoso | |
if "dashboard" in driver.current_url or "account" in driver.current_url: | |
result = "✅ Login exitoso en Soundeo" | |
else: | |
result = "❌ Error al iniciar sesión. Verifica tus credenciales." | |
driver.quit() | |
return result | |
except Exception as e: | |
return f"❌ Error con Selenium: {str(e)}" | |
# Herramienta para buscar y añadir una canción a la lista de descarga | |
def add_song_to_download_list(song_title: str, artist: str) -> str: | |
"""Busca una canción en Soundeo y la añade a la lista de descarga | |
Args: | |
song_title: título de la canción | |
artist: nombre del artista | |
""" | |
from selenium import webdriver | |
from selenium.webdriver.chrome.options import Options | |
from selenium.webdriver.common.by import By | |
from selenium.webdriver.support.ui import WebDriverWait | |
from selenium.webdriver.support import expected_conditions as EC | |
chrome_options = Options() | |
chrome_options.add_argument("--headless") | |
chrome_options.add_argument("--no-sandbox") | |
chrome_options.add_argument("--disable-dev-shm-usage") | |
chrome_options.add_argument("--disable-gpu") | |
try: | |
driver = webdriver.Chrome(options=chrome_options) | |
# Cargar cookies si existen | |
cookies_file = "soundeo_cookies.pkl" | |
if os.path.exists(cookies_file): | |
driver.get("https://soundeo.com") | |
cookies = pickle.load(open(cookies_file, "rb")) | |
for cookie in cookies: | |
driver.add_cookie(cookie) | |
else: | |
driver.quit() | |
return "❌ No hay cookies de sesión. Primero debes iniciar sesión." | |
# Navegar a la búsqueda | |
search_query = f"{song_title} {artist}" | |
search_query = search_query.replace(" ", "+") | |
driver.get(f"https://soundeo.com/search?q={search_query}") | |
time.sleep(5) | |
# Capturar screenshot para debug | |
driver.save_screenshot("search_results.png") | |
# Buscar el primer resultado | |
try: | |
first_result = WebDriverWait(driver, 10).until( | |
EC.presence_of_element_located((By.CSS_SELECTOR, ".track-item")) | |
) | |
# Hacer clic en "Add to Download List" | |
download_button = first_result.find_element(By.CSS_SELECTOR, ".download-button") | |
download_button.click() | |
time.sleep(3) | |
driver.save_screenshot("added_to_list.png") | |
# Obtener información del track añadido | |
track_info = first_result.find_element(By.CSS_SELECTOR, ".track-title").text | |
artist_info = first_result.find_element(By.CSS_SELECTOR, ".track-artist").text | |
driver.quit() | |
return f"✅ Añadida a la lista de descarga: {track_info} - {artist_info}" | |
except Exception as e: | |
driver.quit() | |
return f"❌ No se encontraron resultados o no se pudo añadir: {str(e)}" | |
except Exception as e: | |
return f"❌ Error con Selenium: {str(e)}" | |
# Configuración del agente | |
final_answer = FinalAnswerTool() | |
model = HfApiModel( | |
max_tokens=2096, | |
temperature=0.5, | |
model_id='Qwen/Qwen2.5-Coder-32B-Instruct', | |
custom_role_conversions=None, | |
) | |
with open("prompts.yaml", 'r') as stream: | |
prompt_templates = yaml.safe_load(stream) | |
agent = CodeAgent( | |
model=model, | |
tools=[ | |
final_answer, | |
recognize_song, | |
login_soundeo, | |
add_song_to_download_list, | |
get_current_time_in_timezone | |
], | |
max_steps=8, | |
verbosity_level=1, | |
grammar=None, | |
planning_interval=None, | |
name=None, | |
description=None, | |
prompt_templates=prompt_templates | |
) | |
# Interfaz de usuario con Gradio | |
with gr.Blocks() as demo: | |
gr.Markdown("# 🎵 Asistente Musical - Reconocimiento y Descarga") | |
with gr.Tab("Reconocimiento de Música"): | |
with gr.Row(): | |
audio_input = gr.Audio(type="filepath", label="Sube o graba un fragmento de audio") | |
query_input = gr.Textbox( | |
label="Consulta (opcional)", | |
placeholder="Reconoce esta canción y agrégala a mi lista de descarga" | |
) | |
submit_btn = gr.Button("Procesar") | |
output = gr.Markdown() | |
def process_with_agent(audio=None, text_query=""): | |
context = {} | |
if audio: | |
context["audio_path"] = audio | |
if not text_query: | |
text_query = "Reconoce esta canción y dame información detallada sobre ella." | |
if not text_query: | |
return "❌ Por favor ingresa una consulta o sube un archivo de audio." | |
try: | |
result = agent.run(text_query, context=context) | |
return result | |
except Exception as e: | |
return f"❌ Error al procesar la solicitud: {str(e)}" | |
submit_btn.click( | |
fn=process_with_agent, | |
inputs=[audio_input, query_input], | |
outputs=output | |
) | |
with gr.Tab("Login a Soundeo"): | |
info_text = gr.Markdown("Las credenciales se cargarán automáticamente desde los secrets") | |
login_btn = gr.Button("Iniciar Sesión en Soundeo") | |
login_output = gr.Markdown() | |
def login_process(): | |
query = "Inicia sesión en Soundeo usando las credenciales almacenadas" | |
return agent.run(query) | |
login_btn.click( | |
fn=login_process, | |
inputs=[], | |
outputs=login_output | |
) | |
demo.launch() |