74 lines
2.2 KiB
Python
74 lines
2.2 KiB
Python
"""Bandcamp discovery using their public APIs (no scraping)."""
|
|
|
|
import httpx
|
|
|
|
HEADERS = {
|
|
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0",
|
|
}
|
|
|
|
DIG_DEEPER_URL = "https://bandcamp.com/api/hub/2/dig_deeper"
|
|
|
|
|
|
async def discover_by_tag(
|
|
tags: list[str],
|
|
sort: str = "new",
|
|
page: int = 1,
|
|
) -> list[dict]:
|
|
"""Discover new music on Bandcamp by tag using their public API.
|
|
|
|
Args:
|
|
tags: List of genre/tag strings (e.g. ["indie-rock", "shoegaze"])
|
|
sort: "new", "rec", or "pop" (new releases, recommended, popular)
|
|
page: Page number for pagination
|
|
|
|
Returns list of releases with: title, artist, art_url, bandcamp_url, genre, item_type
|
|
"""
|
|
async with httpx.AsyncClient(timeout=15, headers=HEADERS) as client:
|
|
resp = await client.post(
|
|
DIG_DEEPER_URL,
|
|
json={
|
|
"filters": {
|
|
"format": "all",
|
|
"location": 0,
|
|
"sort": sort,
|
|
"tags": tags,
|
|
},
|
|
"page": page,
|
|
},
|
|
)
|
|
|
|
if resp.status_code != 200:
|
|
return []
|
|
|
|
data = resp.json()
|
|
results = []
|
|
|
|
for item in data.get("items", []):
|
|
art_id = item.get("art_id")
|
|
art_url = f"https://f4.bcbits.com/img/a{art_id}_16.jpg" if art_id else None
|
|
|
|
tralbum_type = item.get("tralbum_type", "a")
|
|
type_path = "album" if tralbum_type == "a" else "track"
|
|
item_url = item.get("tralbum_url", "")
|
|
|
|
results.append({
|
|
"title": item.get("title", ""),
|
|
"artist": item.get("artist", ""),
|
|
"art_url": art_url,
|
|
"bandcamp_url": item_url,
|
|
"genre": ", ".join(tags),
|
|
"item_type": type_path,
|
|
})
|
|
|
|
return results
|
|
|
|
|
|
async def get_trending_tags() -> list[str]:
|
|
"""Return common Bandcamp genre tags for discovery."""
|
|
return [
|
|
"indie-rock", "electronic", "hip-hop-rap", "ambient", "punk",
|
|
"experimental", "folk", "jazz", "metal", "pop", "r-b-soul",
|
|
"shoegaze", "post-punk", "synthwave", "lo-fi", "dream-pop",
|
|
"indie-pop", "psychedelic", "garage-rock", "emo",
|
|
]
|