MusicIndexer/README.md
Шурупов Илья Викторович 83f782d125 Remove hardcoded credentials; read them from the environment
- Env.py now reads SPOTIFY_CLIENT_ID/SPOTIFY_CLIENT_SECRET (and optional
  path overrides) from the environment instead of hardcoding them.
- Add .env.example and ignore .env / .venv.
- Rewrite README with setup, usage and layout (drops the leaked secret).

Note: secrets are also purged from prior history in this push.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 00:39:59 +03:00

3.4 KiB

MusicIndexer

Pull your Spotify library and listening stats via the Spotify Web API, index a local music library (audio tags + iTunes XML), and match the two so you can see which tracks you own, what's missing, and your top artists/tracks/playlists — in a Streamlit GUI.

Features

  • Spotify backend — OAuth (Authorization Code) login, then fetch the user profile, liked tracks, all playlists and their tracks, long-term top tracks and top artists, and playlist/profile cover art. Resilient paginated fetching (follows next, retries dropped connections, honours 429 rate limits) with progress bars.
  • Local backend — index a folder of audio files via mutagen tags.
  • iTunes backend — parse an iTunes Library XML export.
  • Matching — map local tracks to Spotify tracks (fuzzy matcher; ISRC/MBID matching planned).
  • Stats & lyrics — generate listening stats and fetch lyrics.
  • GUI — browse libraries as artist → album → track tables.

Setup

Requires Python 3.13+.

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Credentials

Create an app at https://developer.spotify.com/dashboard and add http://127.0.0.1:8888 as a Redirect URI. Credentials are read from the environment — never commit them.

cp .env.example .env
# edit .env with your client id/secret
source .env

Env.py reads SPOTIFY_CLIENT_ID / SPOTIFY_CLIENT_SECRET (plus optional MUSIC_LIBRARY_PATH and WORK_DIR) from the environment.

Usage

Edit main.py to uncomment the steps you want, then run:

python main.py

The flow steps (see Flow.py) include:

Step What it does
fetch_spotify() OAuth login + download all Spotify data into work_dir/spotify/
fetch_local() index local audio files into work_dir/local/
parse_spotify_library() / parse_itunes_library() / parse_local_library() build normalized libraries
load_libraries() / save_libraries() (de)serialize libraries to work_dir
map_local_to_spotify() match local tracks against the Spotify library
fetch_and_save_lyrics() fetch lyrics for tracks
log_stats() generate stats

On first fetch_spotify() a browser opens for the Spotify login; a local server on 127.0.0.1:8888 catches the redirect and exchanges the code for a token.

GUI

./gui.sh        # runs: .venv/bin/streamlit run Gui.py

Layout

main.py                 entry point (CLI flow)
Gui.py / gui.sh         Streamlit GUI
Flow.py                 orchestrates fetch / parse / map / stats
Env.py                  config (reads credentials from the environment)
src/
  Library.py            data model (Library / Artist / Album / Track)
  LibrarySerializer.py  load/save libraries
  backends/
    spotify/            Web API client, OAuth, parser
    local/              local-file indexer, parser, playlist generator
    itunes/             iTunes XML parser
    navidrome/          Navidrome backend
  mappers/              local↔Spotify matching (fuzzy / search)
  lyrics/               lyrics fetching
work_dir/               fetched data and serialized libraries (gitignored)

Notes

  • Data is cached as JSON under work_dir/ (gitignored); re-running reuses it.
  • The deprecated Spotify endpoints (audio-features, recommendations, etc.) are not used — only currently-supported endpoints.