Files
librespot-python/CONTRIBUTING.md
2025-10-13 03:32:25 -04:00

5.8 KiB

Contributing

What this library is

  • A headless Spotify client, allowing you to authenticate and retrieve a decrypted audio stream for any track.
  • Not a standalone audio player: the provided stream must be piped to another application (like ffplay) or handled by a server to be played.

Environment setup

Prerequisites

  • Python 3.10+

Install runtime packages

pip install -r requirements.txt

Install protoc

This step is only needed if you're changing any .proto serialization schema files, which will subsequently require using the protoc compiler to generate updated versions of the *_pb2.py Python stubs that implement serialization/deserialization for those schemas.

After modifying the .proto files you need to, make sure to follow these steps to regenerate the Python stubs.

Protocol buffer generation

These steps are only necessary after changing .proto files.

  • From the repository root, conveniently recompile all .proto schema files with this command:

    find proto -name "*.proto" | xargs protoc -I=proto --python_out=librespot/proto
    
  • Alternatively, to recompile a single file (e.g. proto/metadata.proto), run:

    protoc -I=proto --python_out=librespot/proto proto/metadata.proto
    
  • Commit both the source .proto and the regenerated Python output together so they can be compared easily.

Architecture

The main components are:

  • Session class (entrypoint)

    • Session.Builder is used to configure and create a session, via one of:

      • username/password
      • stored credentials
      • OAuth
    • An active session is required for all other operations.

  • ApiClient class

    • A high-level client for making standard HTTPS requests to Spotify's Web API endpoints (e.g., https://spclient.wg.spotify.com).
    • Accessed via session.api(), it provides convenient methods like get_metadata_4_track() and handles client tokens automatically.
  • MercuryClient class

    • The low-level client for Spotify's proprietary mercury protocol, which uses hm:// URIs.
    • Accessed via session.mercury(), it handles sending and receiving messages over the main session connection for metadata lookups and subscriptions that are not available via the standard Web API.
  • DealerClient class

    • Manages the persistent WebSocket (wss://) connection to Spotify's dealer service.
    • Accessed via session.dealer(), it listens for and dispatches real-time, asynchronous JSON-based events, such as remote player state changes or notifications from other connected devices.
  • Session.Receiver thread

    • Spawned after authentication to read every encrypted packet coming from the access point.
    • Routes decoded commands to subsystems (MercuryClient, AudioKeyManager, ChannelManager, etc.) and responds to keep-alive pings to hold the session open.
  • Metadata types

    • The librespot.metadata module provides typed identifiers (TrackId, AlbumId, PlaylistId, EpisodeId, etc.) used to reference Spotify content throughout the API.

    • They are constructed from Spotify identifiers, typically using one of the following methods:

      • from_uri(): For all ID types.
      • from_base62(): For most ID types (e.g., tracks, albums, artists).
  • PlayableContentFeeder class

    • Retrieves audio streams; is accessed via session.content_feeder().

    • load(playable_id, audio_quality_picker, preload, halt_listener):

      • Accepts:

        • a TrackId or EpisodeId (any PlayableId)
        • an AudioQualityPicker
        • a preload flag
        • an optional HaltListener callback (pass None if unneeded).
      • Returns a LoadedStream that contains the decrypted stream together with:

        • track/episode metadata
        • normalization data
        • transfer metrics
  • audio module

    • Contains tools for format selection, quality management, streaming, and decryption.
    • VorbisOnlyAudioQuality and LosslessOnlyAudioQuality choose the best matching Metadata.AudioFile for a preferred container/quality combination.
    • CdnManager acquires and refreshes signed CDN URLs, feeding a Streamer that decrypts chunks on the fly while staying seekable.
  • AudioKeyManager and ChannelManager

    • Handle the low-level transport for protected audio: AudioKeyManager requests AES keys, and ChannelManager can stream encrypted chunks directly from the access point when CDN delivery is unavailable.
    • Both are driven transparently by PlayableContentFeeder/CdnManager, so callers only interact with the decrypted LoadedStream.
  • EventService class

    • Asynchronous publisher that emits telemetry (e.g., fetch metrics, playback events) to hm://event-service/v1/events via Mercury.
    • Accessible through session.event_service() for consumers that need to forward custom events.
  • TokenProvider class

    • Caches Login5 access tokens per scope, refreshing them proactively as they near expiry.
    • Used by ApiClient to supply the correct Authorization headers for Spotify Web API calls.
  • SearchManager class

    • High-level wrapper around hm://searchview/km/v4/search/... requests sent over Mercury.
    • Fills in username, locale, and country defaults from the current session before dispatching the call.
  • OAuth tokens for Spotify Web API

    • Can be obtained via session.tokens().get(scope)
    • Enable authenticated API calls for operations like search, playlist management, and user data access