Skip to main content

Deterministic Spotify playlist creation from exact track URIs.

Project description

Perfect Playlist

Build the Spotify playlist you chose, exactly as you chose it.

Perfect Playlist is a local CLI and importable Python package for turning an ordered set of exact Spotify track references into an exact playlist. It preserves order and duplicates, validates before writing, and verifies what Spotify stored afterward.

Vision

AI should be able to build a deterministic playlist without outsourcing the final decision to another generative system. Perfect Playlist is intended to become that dependable final-mile primitive for both people and AI agents.

Mission

Provide the smallest safe interface that can discover Spotify tracks, inspect exact candidates, preserve a chosen TrackSequence, and build or compare playlists without substitution, hidden reordering, silent skips, or destructive overwrites.

Why This Exists

The idea came from trying to create deterministic playlists through ChatGPT's Spotify integration. Asking ChatGPT to ask Spotify to "generate" a playlist passes the intent through multiple interpretive layers. It is like playing a game of Telephone with AI: the request may sound similar at the other end, but the exact tracks and order are no longer guaranteed.

Perfect Playlist removes that last interpretive handoff. An AI agent can search, inspect, and deliberately select exact Spotify track references, then hand the resulting TrackSequence to a deterministic build command. Discovery can be intelligent; the final write should be exact.

This project is not trying to replace recommendation systems. It provides the reliable mechanism that builds a playlist after the choices have already been made.

Product Direction

  • build is the primary action and creates a new public playlist by default.
  • A public or private playlist can be built by supplying an owned, empty target.
  • add is a secondary, append-only action and never changes visibility.
  • verify compares any two Sources as exact ordered TrackSequences.
  • export creates durable YAML, JSON, text, or link output without overwriting files.
  • search and inspect expose facts without choosing tracks or writing playlists.
  • Repair and natural-language resolve workflows are removed from the interface.

The approved behavior is specified in the CLI contract. The canonical TrackSequence, Source pipeline, authentication behavior, deterministic write workflows, read-only discovery commands, agent guidance, and offline/live QA matrix are complete.

Documentation

Start with the documentation index when implementing or reviewing the project.

Requirements

  • Python 3.11+
  • A Spotify developer app
  • A registered loopback redirect URI such as http://127.0.0.1:8888/callback

Installation

Install the released command and Python package from PyPI:

python -m pip install perfect-playlist
perfect-playlist --help

Create a private environment file outside the package installation:

SPOTIPY_CLIENT_ID=your_client_id_here
SPOTIPY_CLIENT_SECRET=your_client_secret_here
SPOTIPY_REDIRECT_URI=http://127.0.0.1:8888/callback

Point Perfect Playlist to that file, then authorize the Spotify account once:

$env:PERFECT_PLAYLIST_SECRETS_FILE='C:\path\to\spotify-secrets.env'
perfect-playlist auth login

Keep PERFECT_PLAYLIST_SECRETS_FILE set whenever you run the CLI, or set the three SPOTIPY_* variables directly. OAuth tokens are stored separately in the operating-system user cache.

Development Setup

py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"
New-Item -ItemType Directory -Force resources | Out-Null
Copy-Item spotify-secrets.env.example resources/spotify-secrets.env

Populate the local, gitignored resources/spotify-secrets.env:

SPOTIPY_CLIENT_ID=your_client_id_here
SPOTIPY_CLIENT_SECRET=your_client_secret_here
SPOTIPY_REDIRECT_URI=http://127.0.0.1:8888/callback
PERFECT_PLAYLIST_RUN_INTEGRATION_TESTS=0

The package loads this file directly with python-dotenv. The safe committed shape is spotify-secrets.env.example; Ralph-specific configuration is documented in the repository setup guide. The real file, its values, OAuth material, and token caches must never be committed.

Register the exact redirect URI in Spotify's developer dashboard, then authorize once:

perfect-playlist auth login

OAuth tokens are stored outside the repository in the operating-system user cache.

Usage

Use Search and Inspect to choose exact tracks, store the chosen canonical URIs in a durable Source, and pass that Source to write commands:

tracks:
  - spotify:track:5Qamlcya1Hz5Z4AgzdQ5q8
  - spotify:track:5irdISp39LC6kD10muguYh
perfect-playlist search 'track:"Call On You" artist:"Corey Lingo"'
perfect-playlist inspect spotify:track:5Qamlcya1Hz5Z4AgzdQ5q8
perfect-playlist build tracks.yaml
perfect-playlist add tracks.yaml --target spotify:playlist:PLAYLIST_ID
perfect-playlist verify tracks.yaml spotify:playlist:PLAYLIST_ID
perfect-playlist export spotify:playlist:PLAYLIST_ID --out playlist.yaml

With no --name or --target, Build creates a new public My Perfect Playlist, advancing to a numeric suffix if that name is already owned. Use --target only for an owned empty Build Target; Add requires --target and appends without changing earlier tracks or visibility.

The importable API exposes the same workflow boundaries and typed results:

from perfect_playlist import (
    add_to_playlist,
    build_public_playlist,
    build_target_playlist,
    compare_track_sequences,
    inspect_track,
    read_source,
    search_tracks,
)

source = read_source("tracks.yaml")
candidates = search_tracks('track:"Call On You" artist:"Corey Lingo"')
selected = inspect_track(candidates[0].uri)
built = build_public_playlist(source)
target_build = build_target_playlist(source, "spotify:playlist:PLAYLIST_ID")
added = add_to_playlist(source, "spotify:playlist:WRITABLE_PLAYLIST_ID")
verification = compare_track_sequences(source, read_source(built.playlist.uri))

Search results and inspected metadata are command responses, not Sources. The caller deliberately chooses canonical URIs before Build or Add.

Current Validation

Offline checks:

$env:PERFECT_PLAYLIST_RUN_INTEGRATION_TESTS='0'
python -m pytest
python -m ruff check --no-cache perfect_playlist tests
python -m mypy --no-incremental perfect_playlist tests

The live Spotify test is controlled by resources/spotify-secrets.env. Set PERFECT_PLAYLIST_RUN_INTEGRATION_TESTS=1 to include a temporary public create/verify/unfollow cycle in every full pytest run. Leave it at 0 to keep live writes opt-in.

$env:PERFECT_PLAYLIST_RUN_INTEGRATION_TESTS='1'
python -m pytest

The latest credentialed run proved public creation and exact ordered writes, but Spotify did not persist a requested private state during API creation. The package now fails closed before adding tracks. The approved private flow therefore fills an empty private playlist that the user already owns instead of claiming that the API can create one reliably. See live QA evidence.

Determinism Policy

Write operations accept only Sources that resolve to exact Spotify track URIs. Human-readable song requests belong in an agent's discovery workflow, where Search and Inspect can be used deliberately. They are never silently resolved inside Build or Add.

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

perfect_playlist-1.0.0.tar.gz (81.9 kB view details)

Uploaded Source

Built Distribution

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

perfect_playlist-1.0.0-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

Details for the file perfect_playlist-1.0.0.tar.gz.

File metadata

  • Download URL: perfect_playlist-1.0.0.tar.gz
  • Upload date:
  • Size: 81.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for perfect_playlist-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f638c97ac6460c9ac98b5e08d155b341ff5d25519c38797aefc25c8225b28940
MD5 d45cd91d1e6f2d91f756380a72ac9401
BLAKE2b-256 8bc38bc15470d69c7733e0fe61e2d31b6768298534f998a6ffa6246cd98a2bd4

See more details on using hashes here.

Provenance

The following attestation bundles were made for perfect_playlist-1.0.0.tar.gz:

Publisher: publish.yml on devin-thomas/perfect-playlist

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file perfect_playlist-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for perfect_playlist-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fe76ff20d408fca5b7276ec779ef0595ad24a37af63dba976f1a58e9cc456530
MD5 7248b4153d01638dc5c31613380faa4a
BLAKE2b-256 7cdc7bb7bc64875d65077a07d94e11c758b1838975099df4a5869264e5d384f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for perfect_playlist-1.0.0-py3-none-any.whl:

Publisher: publish.yml on devin-thomas/perfect-playlist

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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