Important: If the app gets stuck on startup, delete the OAuth cache file Documents/naarvent's projects/Spotify_TUI/.cache_spotify_token to force re-authentication.
A terminal-based Spotify client built with Python, Spotipy and Textual. It provides a keyboard-driven TUI for searching, browsing and controlling Spotify playback, viewing synced lyrics, managing playlists and devices, and more.
- Summary π
- Features β¨
- Requirements & Installation π οΈ
- Environment & Credentials π
- How it works (high level) βοΈ
- APIs & External Services π
- Keybindings / Controls β¨οΈ
- Configuration & Cache π
- Troubleshooting & Notes π
- License π
spt is a full-featured TUI for Spotify built using:
- Textual for the terminal UI
- Spotipy for the Spotify Web API
- Requests for lyrics and metadata providers
It supports search, playback, playlists, devices, lyrics, multi-selection workflows, and rich UI panels.
- Full Spotify search (tracks, albums, artists, playlists)
- Playback control: play / pause / next / previous / seek / shuffle / repeat
- Synced LRC lyrics when available; plain lyric fallback
- Multi-review / multi-add batch playlist operations
- Playlist creation, import, and modification
- Device selection and playback transfer
- Real-time playback sync with progress bar
- Persistent cache + config + OAuth token storage
- Expandable / collapsible Library & Playlists panels via keyboard
Recommended: Python 3.10+
Install dependencies:
pip install spotipy textual requests rich pyfigletRun the app:
python spt_tui.pyspt requires Spotify credentials (or it will prompt you to provide them on first run):
SPOTIPY_CLIENT_IDSPOTIPY_CLIENT_SECRETSPOTIPY_REDIRECT_URI
If not provided via environment variables, the app will prompt for them and can save them locally in spt_config.json.
Scopes include playback, playlists, library, and user data as defined in the script.
- Textual builds a two-column TUI: Search/Library/Playlists (left) and Details/Results/Lyrics (right).
- Spotipy handles authentication, tokens, and playback/playlist operations.
- Lyrics are fetched using LRCLib and lyrics.ovh, parsed into synced or pseudo-synced lines.
- A periodic task syncs playback state and updates the UI.
- Keyboard shortcuts drive all navigation and actions.
- Spotify Web API β playback, search, library, playlists, devices
- LRCLib β synced LRC lyrics
- lyrics.ovh β plain lyric fallback
Below are the keybindings as defined in the application (spt_tui.py). Use these keys to navigate and control the TUI.
-
escapeβ Menu -
ctrl+qβ Quit -
upβ Up -
downβ Down -
/β Search (focus search input) -
leftβ Move focus to the left column (sections, library, playlists). When a playlist/album/lyrics view is open in the right panel, pressingLeftreturns focus to the left column and effectively closes or exits the detailed right view so you can navigate other items. -
rightβ Move focus to the right panel (details, track list, lyrics). From the left column select an item and pressRight(orEnter) to open it in the right panel; the right key focuses that panel for interaction.
Escβ Return to main menuCtrl+Qβ Quitβ / ββ Move between sections and list items/β Focus search inputEnterβ Open / Play selected item
enterβ Open/Playspaceβ Play/Pausenβ Nextpβ Prev/Restartrβ Repeat (cycle: off β context β track)Ctrl+Sβ Toggle shufflecβ Queue (add track to queue)
Spaceβ Play / Pausenβ Next trackpβ Previous / Restartrβ Cycle repeat (off β context β track)cβ Add selected track to QueueCtrl+Sβ Toggle shuffle- / +β Volume down / up (uses configured seconds using "<")Ctrl+Left / Ctrl+Rightβ Seek back / Seek forward (uses configured seconds using "<")mβ Mute / Unmute
ctrl+sβ Toggle shuffle-β Volume down (Vol -)+β Volume up (Vol +)mβ Mutectrl+leftβ Seek back (uses configured seconds using "<")ctrl+rightβ Seek forward (uses configured seconds using "<")<β Prompt seek settings
dβ Open device manager (transfer playback)<β Open seek/volume settings
dβ Manage devices?β Helpf1β Helplβ Toggle lyricsctrl+rβ Refreshctrl+cβ Open Queue
fβ Toggle Favorite (Like / Unlike selected track)Ctrl+Shift+Pβ Add selected track(s) to a playlistCtrl+Dβ Delete (playlist or remove item)Ctrl+Rβ Refresh / reload contentCtrl+Cβ Open Queue view
Ctrl+Lβ Toggle Multi-Add mode- In Multi-Add: use movement keys and
Enterto toggle selection Ctrl+Aβ Confirm selection (when prompted / in multi-add flows)Ctrl+Oβ Add all / confirm add-all action
?orF1β Toggle Help viewLeft / Rightarrows β Move focus between left column and right panel- Log file:
Documents/naarvent's projects/Spotify_TUI/spt_py_textual_spotify.log
Default location for cache, config and logs (created under the user's Documents folder):
Documents/naarvent's projects/Spotify_TUI/
Files:
spt_config.jsonβ saved credentials.cache_spotify_tokenβ OAuth token cachespt_py_textual_spotify.logβ log file (rotating)
The app supports quick filters by starting the query with a prefix (case-insensitive). These are parsed by the search routine:
/ART <query>β search artists/ALB <query>β search albums/TRK <query>β search tracks/PLY <query>β search playlists/PDC <query>β search podcasts/EPS <query>β search episodes from podcasts
You can also write natural queries (e.g., FEEL.)βthe app applies smart parsing and multiple candidate queries to maximize relevant results.
spt attempts to provide synced and plain lyrics using multiple external services and local caching:
- LRCLib (
https://lrclib.net) β primary source for synced LRC lyrics (fetches.lrcwhen available). - lyrics.ovh (
https://api.lyrics.ovh) β fallback for plain lyrics when synced versions are not found. - Local lyrics cache stored under the same cache directory to avoid repeated network lookups.
If synced LRC lyrics are found, the app parses timestamps into a timeline and highlights the current line in sync with playback. If only plain lyrics are available, the app will generate a pseudo-timed timeline to display lines progressively.
If lyrics aren't showing, try Ctrl+R to refresh data or ensure the network and external services are reachable.
- If playlists don't load: press
Ctrl+R(Refresh). - Lyrics fall back to plain text if synced LRC is not available.
- Device switching requires an active Spotify client/device.
- Check
spt_py_textual_spotify.logfor detailed debug output.
This project is licensed under the MIT License β see the LICENSE file for details.
