Skip to main content

A Python SDK for the Spotify Web API.

Project description

Spotify SDK for Python

PyPI version Python versions Actions status Documentation License

A Python SDK for the Spotify Web API.

Full documentation is available at spotify-sdk.dev.

[!NOTE] This is an independent, community-developed library and is not affiliated with or endorsed by Spotify.

Features

  • Type-safe: Full type hints with Pydantic models for all API responses
  • Sync and async: Dedicated SpotifyClient and AsyncSpotifyClient classes
  • Automatic retries: Exponential backoff with jitter for rate limits and transient errors
  • Context managers: Clean resource management with with and async with support

Installation

pip install spotify-sdk

Or with uv:

uv add spotify-sdk

Requirements

  • Python 3.10+

Python version support follows the official Python release cycle. We support all versions that have not reached end-of-life.

Authentication

The SDK supports:

  • Access token authentication
  • Client credentials flow
  • Authorization code flow with refresh tokens
# Access token
client = SpotifyClient(access_token="your-access-token")

# Client credentials
client = SpotifyClient.from_client_credentials(
    client_id="your-client-id",
    client_secret="your-client-secret",
)
# Authorization code (user-scoped endpoints)
from spotify_sdk.auth import AuthorizationCode, FileTokenCache, authorize_local

auth = AuthorizationCode(
    client_id="your-client-id",
    client_secret="your-client-secret",
    redirect_uri="http://127.0.0.1:8080/callback",
    scope=["user-read-private"],
    token_cache=FileTokenCache(".cache/spotify-sdk/token.json"),
)

# Local helper: opens browser and captures the callback automatically
authorize_local(auth)

client = SpotifyClient(auth_provider=auth)

Quick Start

from spotify_sdk import SpotifyClient

client = SpotifyClient(access_token="your-access-token")

# Get an album
album = client.albums.get("5K79FLRUCSysQnVESLcTdb")
print(f"{album.name} by {album.artists[0].name}")
# Output: "DeBÍ TiRAR MáS FOToS by Bad Bunny"

# Get album tracks
tracks = client.albums.get_tracks(album.id)
for track in tracks.items:
    print(f"{track.track_number}. {track.name}")

client.close()

Using Context Managers

from spotify_sdk import SpotifyClient

with SpotifyClient(access_token="your-access-token") as client:
    album = client.albums.get("4aawyAB9vmqN3uQ7FjRGTy")
    print(album.name)

Async Support

import asyncio
from spotify_sdk import AsyncSpotifyClient

async def main():
    async with AsyncSpotifyClient(access_token="your-access-token") as client:
        album = await client.albums.get("4Uv86qWpGTxf7fU7lG5X6F")
        print(f"{album.name} by {album.artists[0].name}")
        # "The College Dropout by Kanye West"

asyncio.run(main())

Services

Albums

# Get a single album
album = client.albums.get("<id>")
album = client.albums.get("<id>", market="US")

# Get multiple albums (up to 20)
albums = client.albums.get_several(["<id1>", "<id2>"])

# Get album tracks with pagination
tracks = client.albums.get_tracks("<id>", limit=10, offset=0)

Audiobooks

# Get a single audiobook
audiobook = client.audiobooks.get("<id>")
audiobook = client.audiobooks.get("<id>", market="US")

# Get multiple audiobooks (up to 50)
audiobooks = client.audiobooks.get_several(["<id1>", "<id2>"])

# Get audiobook chapters with pagination
chapters = client.audiobooks.get_chapters("<id>", limit=10, offset=0)

Shows

# Get a single show
show = client.shows.get("show_id_123")
show = client.shows.get("show_id_123", market="US")

# Get show episodes with pagination
episodes = client.shows.get_episodes("show_id_123", limit=10, offset=0)

# Get current user's saved shows
saved_shows = client.shows.get_saved(limit=10, offset=0)

Episodes

# Get a single episode
episode = client.episodes.get("episode_id_123")
episode = client.episodes.get("episode_id_123", market="US")

# Get current user's saved episodes
saved_episodes = client.episodes.get_saved(limit=10, offset=0)
saved_episodes = client.episodes.get_saved(limit=10, offset=0, market="US")

Search

results = client.search.search(
    q="kind of blue",
    types=["album", "artist"],
    market="US",
    limit=10,
)

Error Handling

The SDK raises specific exceptions for different error types:

from spotify_sdk import (
    SpotifyClient,
    AuthenticationError,
    BadRequestError,
    ForbiddenError,
    NotFoundError,
    RateLimitError,
    ServerError,
)

try:
    album = client.albums.get("invalid_id")
except NotFoundError as e:
    print(f"Album not found: {e.message}")
except AuthenticationError as e:
    print(f"Invalid token: {e.message}")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except ServerError as e:
    print(f"Spotify server error: {e.message}")

Exception Hierarchy

Exception HTTP Status Description
SpotifyError - Base exception for all SDK errors
AuthenticationError 401 Invalid or expired access token
BadRequestError 400 Invalid request parameters
ForbiddenError 403 Insufficient permissions
NotFoundError 404 Resource not found
RateLimitError 429 Rate limit exceeded
ServerError 5xx Spotify server error

Configuration

Client Options

client = SpotifyClient(
    access_token="your-access-token",
    timeout=30.0,      # Request timeout in seconds (default: 30.0)
    max_retries=3,     # Maximum retry attempts (default: 3)
)

Retry Behavior

The SDK automatically retries requests on:

  • Connection errors and timeouts
  • Rate limit responses (429) - respects Retry-After header
  • Server errors (5xx)

Retries use exponential backoff with jitter:

  • Initial delay: 0.5 seconds
  • Maximum delay: 8.0 seconds
  • Multiplier: 2x per retry

Models

All API responses are returned as Pydantic models with full type hints:

album = client.albums.get("<id>")

# Access typed attributes
print(album.name)           # str
print(album.release_date)   # str
print(album.total_tracks)   # int
print(album.artists)        # list[SimplifiedArtist]
print(album.images)         # list[Image]

# Models support forward compatibility
# Unknown fields from the API are preserved

Development

Clone the repository:

git clone https://github.com/jonathan343/spotify-sdk.git
cd spotify-sdk

Install dependencies with uv:

uv sync

Run tests:

uv run pytest

Run linting:

uv run ruff check .
uv run ruff format --check --preview .

Sync/Async Architecture

The SDK uses an async-first architecture. Async code under src/spotify_sdk/_async/ is the source of truth, and the sync code under src/spotify_sdk/_sync/ is auto-generated using unasync. Do not edit _sync/ files directly.

After making changes to _async/ source or tests/_async/, regenerate the sync code:

uv run python scripts/run_unasync.py

To verify sync code is up to date (same check that runs in CI):

uv run python scripts/run_unasync.py --check

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spotify_sdk-0.8.0.tar.gz (34.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spotify_sdk-0.8.0-py3-none-any.whl (59.1 kB view details)

Uploaded Python 3

File details

Details for the file spotify_sdk-0.8.0.tar.gz.

File metadata

  • Download URL: spotify_sdk-0.8.0.tar.gz
  • Upload date:
  • Size: 34.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for spotify_sdk-0.8.0.tar.gz
Algorithm Hash digest
SHA256 a09c1c4122ce69021af6658321f3fd6739ac92b3a5ea85e9eb61c812816b4e95
MD5 49e42f72aa63c14d7491c4d26b9206cf
BLAKE2b-256 8c9c2049161b9de9d2a1251a546bb42ecfced3d9849781fb5ae581e0db455088

See more details on using hashes here.

File details

Details for the file spotify_sdk-0.8.0-py3-none-any.whl.

File metadata

  • Download URL: spotify_sdk-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 59.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for spotify_sdk-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cbea3c0a68f60e66cbed8e27947f4ef3d6c943124c2bff695ae1d924767bd993
MD5 733a9b8112a564cd903a04ee346e870b
BLAKE2b-256 79d91deacd6cde1178b362837d57df018e024672b6412b570b9c31dd0f1cad11

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page