"""YouTube API client for searching songs."""
from googleapiclient.discovery import build
import warnings
from typing import Any
# Suprimir deprecation warning
warnings.filterwarnings("ignore", category=DeprecationWarning)
from .validators import validate_api_key, validate_search_query, validate_max_results
from .constants import YOUTUBE_API_SERVICE, YOUTUBE_API_VERSION, DEFAULT_REGION_CODE, DEFAULT_MAX_RESULTS, ERROR_SEARCHING_YOUTUBE
class YouTubeClient:
"""Client for interacting with YouTube API."""
def __init__(self, api_key: str) -> None:
"""
Initialize YouTube client.
Args:
api_key: Google API key for YouTube Data API v3
Raises:
ValueError: If API key is invalid
"""
is_valid, message = validate_api_key(api_key)
if not is_valid:
raise ValueError(message)
self.youtube = build(YOUTUBE_API_SERVICE, YOUTUBE_API_VERSION, developerKey=api_key)
def search_song(
self, query: str, max_results: int = DEFAULT_MAX_RESULTS, region_code: str = DEFAULT_REGION_CODE
) -> list[dict[str, Any]]:
"""
Search for songs on YouTube.
Args:
query: Song name or artist to search
max_results: Maximum number of results to return (1-50, default: 5)
region_code: Region code for search results (default: "ES")
Returns:
List of dictionaries containing video information
Raises:
ValueError: If query or max_results parameters are invalid
RuntimeError: If API request fails
"""
# Validate inputs
is_valid, message = validate_search_query(query)
if not is_valid:
raise ValueError(message)
is_valid, message = validate_max_results(max_results)
if not is_valid:
raise ValueError(message)
try:
request = self.youtube.search().list( # type: ignore
q=query,
part="snippet",
type="video",
maxResults=max_results,
regionCode=region_code,
)
response = request.execute()
results = []
for item in response.get("items", []):
video_id = item["id"]["videoId"]
title = item["snippet"]["title"]
channel = item["snippet"]["channelTitle"]
results.append(
{
"title": title,
"channel": channel,
"video_id": video_id,
"url": f"https://www.youtube.com/watch?v={video_id}",
}
)
return results
except Exception as e:
raise RuntimeError(ERROR_SEARCHING_YOUTUBE.format(str(e))) from e