import os from typing import Dict, List, Optional import logging from urllib import parse import requests import json from similarity.string_handling import normalize_string logger = logging.getLogger('similarity') def parse_response(content: List, target: str, min_similarity: float) -> List[Dict]: if len(content) is not 0: similar_artists = [] for artist in content["similarartists"]["artist"]: if artist["name"].count(target) == 0: if float(artist["match"]) >= min_similarity: similar_artists.append({"name": artist["name"], "similarity_score": artist["match"]}) else: logging.debug(f"Omitting {artist['name']} from similar artists for {target} as it contains the target.") return similar_artists else: return [] def get_similar_artists(artist: str, min_similarity: Optional[float] = 0.0) -> List[Dict]: normalized_artist_name = normalize_string(artist) if artist != normalized_artist_name: logger.info(f"Processing a query for {artist} (normalized to {normalized_artist_name})...") else: logger.info(f"Processing a query for {artist}...") try: response = requests.get( url="http://ws.audioscrobbler.com/2.0/", params={ "method": "artist.getsimilar", "artist": normalized_artist_name, "api_key": os.getenv("API_KEY"), "format": "json", }, ) response_content = json.loads(response.content) if "error" in response_content: logger.error( f"Audioscrobbler API returned error {response_content['error']}: {response_content['message']}") return [] else: return parse_response(response_content, artist, min_similarity) except requests.exceptions.RequestException: logger.error("HTTP Request failed for {normalized_artist_name} with HTTP status code {response.status_code}.")