Python CLI tool that syncs your offline music library (AudioMirror XML) to a Spotify playlist.
Use case: Offline music library at home → listen to the same tracks on Spotify at work.
- Reads XML files from your AudioMirror library
- Computes a sync plan: what to add, remove, recover, or search
- Searches Spotify for unmatched tracks (artist + title + album)
- Adds EXACT and HIGH confidence matches to your playlist automatically
- LOW confidence matches are saved for manual review (not added)
- Saves decision history - re-runs only process new/changed tracks
- Removes tracks from playlist if they're deleted from your library
The tool is deterministic and idempotent - running it multiple times always converges to the same playlist state.
- Go to Spotify Developer Dashboard
- Create a new app with these settings:
- Redirect URI:
http://127.0.0.1:8888/callback - API/SDKs: Web API
- Redirect URI:
- Copy your Client ID and Client Secret
cp config/config.example.json config/config.jsonEdit config/config.json:
{
"spotify_client_id": "your_client_id",
"spotify_client_secret": "your_client_secret",
"spotify_redirect_uri": "http://127.0.0.1:8888/callback",
"spotify_playlist_id": "your_playlist_id",
"audiomirror_path": "C:/path/to/AudioMirror/AUDIO_MIRROR"
}To get your playlist ID: open the playlist in Spotify → Share → Copy link → the ID is the part after /playlist/ and before ?
pip install -r config/requirements.txtDouble-click scripts/run.bat (Windows) or:
python -m src.mainOn first run, a browser window will open for Spotify login. After that, auth is cached.
Use --simulate to run against mock data without touching the real API.
SpotifyPlaylistGen/
├── CLAUDE.md / GUIDELINES.md # Engineering rules
├── config/
│ ├── config.json # Credentials (gitignored)
│ ├── config.example.json # Template
│ └── requirements.txt
├── src/
│ ├── main.py # CLI entrypoint + pipeline
│ ├── config.py # Config loading/validation
│ ├── xml_parser.py # AudioMirror XML reader
│ ├── matcher.py # Match scoring
│ ├── spotify_interface.py # ABC for API clients
│ ├── spotify_client.py # Real Spotify client
│ ├── spotify_simulator.py # Mock client for testing
│ ├── history_store.py # Safe JSON persistence
│ ├── reconciler.py # Deterministic sync algorithm
│ ├── report_generator.py # Markdown reports
│ └── lockfile.py # Concurrent run protection
├── tests/
│ ├── unit/ # Unit tests
│ ├── golden/ # End-to-end golden path tests
│ └── fixtures/ # Test data
├── scripts/
│ ├── run.bat / run.sh # Launchers
│ └── diagnose.py # Auth diagnostic
├── docs/
│ └── spotify-api-reference.md
└── data/ # Gitignored runtime data
├── history.json # Decision history
├── logs/ # Run logs
└── reports/ # Match reports
| State | Meaning |
|---|---|
added |
Matched and in playlist - skipped on re-run |
unmatched |
No match found - retried on re-run |
exhausted |
Failed 5+ times - no longer retried |
custom |
Manually marked as not on Spotify - always skipped |
python -m pytest tests/ -vDeveloped: March 2026 · Status: Actively developed · Tests: 88