57 lines
1.7 KiB
Python
57 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
import httpx
|
|
|
|
|
|
class LastFmClient:
|
|
BASE_URL = "https://ws.audioscrobbler.com/2.0/"
|
|
|
|
def __init__(self, api_key: str | None, http: httpx.AsyncClient) -> None:
|
|
self.api_key = api_key
|
|
self.http = http
|
|
|
|
@property
|
|
def enabled(self) -> bool:
|
|
return bool(self.api_key)
|
|
|
|
async def track_similar(self, *, artist: str, track: str, limit: int = 20) -> list[dict[str, Any]]:
|
|
if not self.api_key:
|
|
return []
|
|
params = {
|
|
"method": "track.getSimilar",
|
|
"api_key": self.api_key,
|
|
"artist": artist,
|
|
"track": track,
|
|
"limit": limit,
|
|
"format": "json",
|
|
"autocorrect": 1,
|
|
}
|
|
resp = await self.http.get(self.BASE_URL, params=params, timeout=20)
|
|
resp.raise_for_status()
|
|
data = resp.json()
|
|
similar = ((data.get("similartracks") or {}).get("track")) or []
|
|
if isinstance(similar, dict):
|
|
similar = [similar]
|
|
return similar
|
|
|
|
async def artist_similar(self, *, artist: str, limit: int = 15) -> list[dict[str, Any]]:
|
|
if not self.api_key:
|
|
return []
|
|
params = {
|
|
"method": "artist.getSimilar",
|
|
"api_key": self.api_key,
|
|
"artist": artist,
|
|
"limit": limit,
|
|
"format": "json",
|
|
"autocorrect": 1,
|
|
}
|
|
resp = await self.http.get(self.BASE_URL, params=params, timeout=20)
|
|
resp.raise_for_status()
|
|
data = resp.json()
|
|
similar = ((data.get("similarartists") or {}).get("artist")) or []
|
|
if isinstance(similar, dict):
|
|
similar = [similar]
|
|
return similar
|