Bandcamp Async API
Project description
Bandcamp Async API
A modern, asynchronous Python client for the Bandcamp API.
This project was created to implement a Bandcamp music provider for Music Assistant, enabling seamless integration of Bandcamp's music catalog into home audio systems.
- Repository: https://github.com/ALERTua/bandcamp_async_api
- Changelog: https://github.com/ALERTua/bandcamp_async_api/releases
- PyPI: https://pypi.org/project/bandcamp_async_api/
- Music Assistant: https://github.com/music-assistant
Features
- Search: Search for artists, albums, and tracks across Bandcamp
- Albums: Retrieve detailed album information including track listings
- Tracks: Get individual track details and streaming information
- Artists: Access artist profiles, discographies, and metadata
- Collections: Browse user collections (requires authentication)
- Async: Fully asynchronous API using aiohttp
- Type-safe: Complete type hints for all models and methods
- Well-tested: Comprehensive test suite with real API data
Installation
Install from PyPI:
pip install bandcamp-async-api
Or using uv:
uv add bandcamp-async-api
Quick Start
import asyncio
from bandcamp_async_api import BandcampAPIClient
async def main():
async with BandcampAPIClient(identity_token='7%09optional_identity_token%7D') as client:
# Search for music
results = await client.search("radiohead")
print(f"Found {len(results)} results")
# Get album details
if results:
album_result = next(r for r in results if r.type == "album")
album = await client.get_album(album_result.artist_id, album_result.id)
print(f"Album: {album.title} by {album.artist.name}")
# Get artist information
artist_result = next(r for r in results if r.type == "artist")
artist = await client.get_artist(artist_result.id)
print(f"Artist: {artist.name} - {artist.bio}")
if __name__ == '__main__':
asyncio.run(main())
Authentication
For accessing user collections, you need to obtain an identity token from Bandcamp cookies:
from bandcamp_async_api import BandcampAPIClient
client = BandcampAPIClient(identity_token="your_identity_token")
API Reference
Core Client
BandcampAPIClient()- Main API clientsearch(query: str)- Search Bandcampget_album(artist_id, album_id)- Get album detailsget_track(artist_id, track_id)- Get track detailsget_artist(artist_id)- Get artist detailsget_collection_summary()- Get collection overviewget_collection_items()- Get collection items with paginationget_artist_discography(artist_id)- Get artist's complete discography
Data Models
SearchResultItem- Base search resultBCAlbum- Album with tracks and metadataBCTrack- Individual track informationBCArtist- Artist/band profileCollectionSummary- User's collection dataCollectionItem- Individual collection item
Exceptions
BandcampAPIError- Base API errorBandcampNotFoundError- Resource not foundBandcampBadQueryError- Invalid search queryBandcampRateLimitError- Rate limit exceeded (includesretry_afterattribute)
Error Handling
The client provides specific exception types for different error conditions:
from bandcamp_async_api import (
BandcampAPIClient,
BandcampNotFoundError,
BandcampAPIError
)
async def safe_get_album(client, artist_id, album_id):
try:
return await client.get_album(artist_id, album_id)
except BandcampNotFoundError:
print("Album not found")
return None
except BandcampAPIError as e:
print(f"API error: {e}")
return None
Rate Limiting
When Bandcamp's API rate limit is exceeded, a BandcampRateLimitError is raised with a retry_after attribute indicating how many seconds to wait before retrying:
import asyncio
from bandcamp_async_api import BandcampAPIClient, BandcampRateLimitError
async def get_album_with_retry(client, artist_id, album_id, max_retries=3):
for attempt in range(max_retries):
try:
return await client.get_album(artist_id, album_id)
except BandcampRateLimitError as e:
if attempt < max_retries - 1:
wait_time = e.retry_after or 30
print(f"Rate limited. Waiting {wait_time} seconds...")
await asyncio.sleep(wait_time)
else:
raise
For automatic retries with exponential backoff, you can use the tenacity library:
from tenacity import retry, retry_if_exception_type, wait_exponential
from bandcamp_async_api import BandcampAPIClient, BandcampRateLimitError
@retry(
retry=retry_if_exception_type(BandcampRateLimitError),
wait=wait_exponential(multiplier=1, min=30, max=300)
)
async def get_album(client, artist_id, album_id):
return await client.get_album(artist_id, album_id)
Development
Setup
# Clone the repository
git clone https://github.com/ALERTua/bandcamp_async_api.git
cd bandcamp_async_api
# Install dependencies
uv sync --dev
# Run tests
uv run pytest
# Run linting
uv run ruff check
Testing
The project includes comprehensive tests:
# Run all tests
uv run pytest
# Run integration tests (requires real API access)
echo "BANDCAMP_IDENTITY_TOKEN=7%09identity_token%7D" > .env
uv run pytest tests/real_data/
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
This project is built based on data from:
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bandcamp_async_api-0.0.7.tar.gz.
File metadata
- Download URL: bandcamp_async_api-0.0.7.tar.gz
- Upload date:
- Size: 9.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb81d5e57e2aaaed2557cbdb1180d29923e62ea0cde0f10c0e73f56d19ff9c8a
|
|
| MD5 |
3b93c327f4914235baead4088421356f
|
|
| BLAKE2b-256 |
808f5a9472fd0e097fa9e73decfb7d1ef3e57cc7fef986bf0bbc8b70ecff50df
|
File details
Details for the file bandcamp_async_api-0.0.7-py3-none-any.whl.
File metadata
- Download URL: bandcamp_async_api-0.0.7-py3-none-any.whl
- Upload date:
- Size: 14.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f44401fb39382c7f9c689877f1e9cee1924d146655393e093293e440b72c1462
|
|
| MD5 |
7a804a3234348a7ade4b4de4a7cdc172
|
|
| BLAKE2b-256 |
832ed554313a17bed767066f6c1dd325617fa56f3d68b0487ed02463b9153480
|