System OS
Docker
Python Version
3.8 (CPython)
Install Source
GitHub
Install version / commit hash
v4.2.10
Expected Behavior vs Actual Behavior
Expected to be able to circumvent both API retry issues & issues with consistent auth in docker, tried to set up my own spotify developer app with client id & client secret. Valid redirect URI added: "http://127.0.0.1:9900/"
Then to generate auth_code went to
https://accounts.spotify.com/authorize?client_id=<clientid>&response_type=code&redirect_uri=http://127.0.0.1:9900/&scope=playlist-read-private+user-follow-read+user-library-read
Put the code generated from that in config.json but then getting error 401 - Invalid Access Token when running
docker run --rm -v <spotdl-config>:/root/.spotdl -v <musicfolder>:/music spotdl/spotify-downloader download saved --config --user-auth --no-cache --output "{list-name}/{artists} - {title}.{output-ext}"
Relevant part of my config.json:
{
"client_id": "<custom client id from app on spotify developer>",
"client_secret": "<custom client secret from app on spotify developer>",
"auth_token": "<custom auth code generated from the url mentioned above>",
"user_auth": true,
"headless": true,
"cache_path": "/root/.spotdl/.spotipy",
"no_cache": false,
"max_retries": 3,
Steps to reproduce - Ensure to include actual links!
- Create your own app on spotify developer account
- Go to
https://accounts.spotify.com/authorize?client_id=<clientid>&response_type=code&redirect_uri=https://127.0.0.1:9900/&scope=playlist-read-private+user-follow-read+user-library-read to get http://127.0.0.1:9900/?code=AQCd ... in the URL bar. Copy everything after code= and put in the config file under auth_token
- Try to run docker to download saved user songs
Traceback
Processing query: saved
HTTP Error for GET to https://api.spotify.com/v1/me/tracks with Params: {'limit': 20, 'offset': 0, 'market': None} returned 401 due to Invalid access token
An error occurred
╭───────────────────── Traceback (most recent call last) ──────────────────────╮
│ /root/.cache/pypoetry/virtualenvs/spotdl-il7asoJj-py3.13/lib/python3.13/site │
│ -packages/spotipy/client.py:275 in _internal_call │
│ │
│ 272 │ │ │ │ timeout=self.requests_timeout, **args │
│ 273 │ │ │ ) │
│ 274 │ │ │ │
│ ❱ 275 │ │ │ response.raise_for_status() │
│ 276 │ │ │ results = response.json() │
│ 277 │ │ except requests.exceptions.HTTPError as http_error: │
│ 278 │ │ │ response = http_error.response │
│ │
│ /root/.cache/pypoetry/virtualenvs/spotdl-il7asoJj-py3.13/lib/python3.13/site │
│ -packages/requests/models.py:1024 in raise_for_status │
│ │
│ 1021 │ │ │ ) │
│ 1022 │ │ │
│ 1023 │ │ if http_error_msg: │
│ ❱ 1024 │ │ │ raise HTTPError(http_error_msg, response=self) │
│ 1025 │ │
│ 1026 │ def close(self): │
│ 1027 │ │ """Releases the connection back to the pool. Once this method │
╰──────────────────────────────────────────────────────────────────────────────╯
HTTPError: 401 Client Error: Unauthorized for url:
https://api.spotify.com/v1/me/tracks?limit=20&offset=0
During handling of the above exception, another exception occurred:
╭───────────────────── Traceback (most recent call last) ──────────────────────╮
│ /spotdl/console/entry_point.py:160 in entry_point │
│ │
│ 157 │ try: │
│ 158 │ │ # Pick the operation to perform │
│ 159 │ │ # based on the name and run it! │
│ ❱ 160 │ │ OPERATIONS[arguments.operation]( │
│ 161 │ │ │ query=arguments.query, │
│ 162 │ │ │ downloader=downloader, │
│ 163 │ │ ) │
│ │
│ /spotdl/console/download.py:25 in download │
│ │
│ 22 │ """ │
│ 23 │ │
│ 24 │ # Parse the query │
│ ❱ 25 │ songs = get_simple_songs( │
│ 26 │ │ query, │
│ 27 │ │ use_ytm_data=downloader.settings["ytm_data"], │
│ 28 │ │ playlist_numbering=downloader.settings["playlist_numbering"], │
│ │
│ /spotdl/utils/search.py:278 in get_simple_songs │
│ │
│ 275 │ │ elif "artist:" in request: │
│ 276 │ │ │ lists.append(Artist.from_search_term(request, fetch_songs= │
│ 277 │ │ elif request == "saved": │
│ ❱ 278 │ │ │ lists.append(Saved.from_url(request, fetch_songs=False)) │
│ 279 │ │ elif request == "all-user-playlists": │
│ 280 │ │ │ lists.extend(get_all_user_playlists()) │
│ 281 │ │ elif request == "all-user-followed-artists": │
│ │
│ /spotdl/types/song.py:306 in from_url │
│ │
│ 303 │ │ - The SongList object. │
│ 304 │ │ """ │
│ 305 │ │ │
│ ❱ 306 │ │ metadata, songs = cls.get_metadata(url) │
│ 307 │ │ urls = [song.url for song in songs] │
│ 308 │ │ │
│ 309 │ │ if fetch_songs: │
│ │
│ /spotdl/types/saved.py:45 in get_metadata │
│ │
│ 42 │ │ if spotify_client.user_auth is False: # type: ignore │
│ 43 │ │ │ raise SavedError("You must be logged in to use this functi │
│ 44 │ │ │
│ ❱ 45 │ │ saved_tracks_response = spotify_client.current_user_saved_trac │
│ 46 │ │ if saved_tracks_response is None: │
│ 47 │ │ │ raise SavedError("Couldn't get saved tracks") │
│ 48 │
│ │
│ /root/.cache/pypoetry/virtualenvs/spotdl-il7asoJj-py3.13/lib/python3.13/site │
│ -packages/spotipy/client.py:1302 in current_user_saved_tracks │
│ │
│ 1299 │ │ │ │ - market - an ISO 3166-1 alpha-2 country code │
│ 1300 │ │ │
│ 1301 │ │ """ │
│ ❱ 1302 │ │ return self._get("me/tracks", limit=limit, offset=offset, mar │
│ 1303 │ │
│ 1304 │ def current_user_saved_tracks_add(self, tracks=None): │
│ 1305 │ │ """ Add one or more tracks to the current user's │
│ │
│ /spotdl/utils/spotify.py:195 in _get │
│ │
│ 192 │ │ retries = self.max_retries # type: ignore # pylint: disable=E │
│ 193 │ │ while response is None: │
│ 194 │ │ │ try: │
│ ❱ 195 │ │ │ │ response = self._internal_call("GET", url, payload, kw │
│ 196 │ │ │ except (requests.exceptions.Timeout, requests.ConnectionEr │
│ 197 │ │ │ │ retries -= 1 │
│ 198 │ │ │ │ if retries <= 0: │
│ │
│ /root/.cache/pypoetry/virtualenvs/spotdl-il7asoJj-py3.13/lib/python3.13/site │
│ -packages/spotipy/client.py:297 in _internal_call │
│ │
│ 294 │ │ │ │ method, url, args.get("params"), response.status_code │
│ 295 │ │ │ ) │
│ 296 │ │ │ │
│ ❱ 297 │ │ │ raise SpotifyException( │
│ 298 │ │ │ │ response.status_code, │
│ 299 │ │ │ │ -1, │
│ 300 │ │ │ │ f"{response.url}:\n {msg}", │
╰──────────────────────────────────────────────────────────────────────────────╯
SpotifyException: http status: 401, code:-1 -
https://api.spotify.com/v1/me/tracks?limit=20&offset=0:
Invalid access token, reason: None
Other details
No response
System OS
Docker
Python Version
3.8 (CPython)
Install Source
GitHub
Install version / commit hash
v4.2.10
Expected Behavior vs Actual Behavior
Expected to be able to circumvent both API retry issues & issues with consistent auth in docker, tried to set up my own spotify developer app with client id & client secret. Valid redirect URI added: "http://127.0.0.1:9900/"
Then to generate auth_code went to
https://accounts.spotify.com/authorize?client_id=<clientid>&response_type=code&redirect_uri=http://127.0.0.1:9900/&scope=playlist-read-private+user-follow-read+user-library-readPut the code generated from that in config.json but then getting error 401 - Invalid Access Token when running
docker run --rm -v <spotdl-config>:/root/.spotdl -v <musicfolder>:/music spotdl/spotify-downloader download saved --config --user-auth --no-cache --output "{list-name}/{artists} - {title}.{output-ext}"Relevant part of my config.json:
Steps to reproduce - Ensure to include actual links!
https://accounts.spotify.com/authorize?client_id=<clientid>&response_type=code&redirect_uri=https://127.0.0.1:9900/&scope=playlist-read-private+user-follow-read+user-library-readto get http://127.0.0.1:9900/?code=AQCd ... in the URL bar. Copy everything after code= and put in the config file under auth_tokenTraceback
Other details
No response