music-app/backend/app/services/musicbrainz.py
2026-07-03 01:06:35 +00:00

82 lines
2.5 KiB
Python

import os
import requests
from typing import List, Dict, Optional
MUSICBRAINZ_USER_AGENT = os.getenv("MUSICBRAINZ_USER_AGENT", "MusicApp/1.0")
MUSICBRAINZ_URL = "https://musicbrainz.org/ws/2/"
def search_artist(artist_name: str) -> Optional[Dict]:
try:
url = f"{MUSICBRAINZ_URL}artist"
params = {
"query": artist_name,
"fmt": "json",
"limit": 1,
}
headers = {"User-Agent": MUSICBRAINZ_USER_AGENT}
response = requests.get(url, params=params, headers=headers, timeout=10)
if response.status_code != 200:
return None
data = response.json()
artists = data.get("artists", [])
if artists:
a = artists[0]
return {
"id": a.get("id"),
"name": a.get("name"),
"releases": [],
}
return None
except (requests.RequestException, KeyError):
return None
def get_artist_releases(artist_id: str, limit: int = 10) -> List[Dict]:
try:
url = f"{MUSICBRAINZ_URL}artist/{artist_id}/releases"
params = {
"inc": "recordings+labels+artists",
"fmt": "json",
"limit": limit,
"order": "date",
}
headers = {"User-Agent": MUSICBRAINZ_USER_AGENT}
response = requests.get(url, params=params, headers=headers, timeout=10)
if response.status_code != 200:
return []
data = response.json()
releases = data.get("releases", [])
result = []
for rel in releases:
recordings = rel.get("media", [{}])[0].get("tracks", []) if rel.get("media") else []
tracks = []
for rec in recordings:
tracks.append({
"title": rec.get("title", "Unknown"),
"duration": int(rec.get("length", 0)) / 1000 if rec.get("length") else 0,
"duration_formatted": _format_duration(int(rec.get("length", 0)) / 1000),
})
result.append({
"id": rel.get("id"),
"title": rel.get("title", "Unknown"),
"cover_art": None,
"release_date": rel.get("date", ""),
"tracks": tracks,
})
return result
except (requests.RequestException, KeyError, IndexError):
return []
def _format_duration(seconds: float) -> str:
m = int(seconds // 60)
s = int(seconds % 60)
return f"{m}:{s:02d}"