Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running the commands to donwload user saved albums or songs fails with error 'ResponseError: too many 429 error responses' #2111

Open
yayitazale opened this issue Jun 4, 2024 · 21 comments
Labels
Bug Unexpected problem or unintended behavior that needs to be fixed

Comments

@yayitazale
Copy link

System OS

Windows

Python Version

3.10 (CPython)

Install Source

pip / PyPi

Install version / commit hash

v4.2.5

Expected Behavior vs Actual Behavior

Trying to download the user saved albums or song throws this error

Max Retries reached

An error occurred
ResponseError: too many 429 error responses

Steps to reproduce - Ensure to include actual links!

python -m spotdl download all-user-saved-albums --user-auth

Traceback

python -m spotdl download all-user-saved-albums --user-auth
Processing query: all-user-saved-albums
Max Retries reached

An error occurred
ResponseError: too many 429 error responses

The above exception was the direct cause of the following exception:

╭─────────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────────╮
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\requests\adapters.py:667 in send                                                                                                    │
│                                                                                                                                         │
│   664 │   │   │   timeout = TimeoutSauce(connect=timeout, read=timeout)                                                                 │
│   665 │   │                                                                                                                             │
│   666 │   │   try:                                                                                                                      │
│ ❱ 667 │   │   │   resp = conn.urlopen(                                                                                                  │
│   668 │   │   │   │   method=request.method,                                                                                            │
│   669 │   │   │   │   url=url,                                                                                                          │
│   670 │   │   │   │   body=request.body,                                                                                                │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\urllib3\connectionpool.py:948 in urlopen                                                                                            │
│                                                                                                                                         │
│    945 │   │   │   response.drain_conn()                                                                                                │
│    946 │   │   │   retries.sleep(response)                                                                                              │
│    947 │   │   │   log.debug("Retry: %s", url)                                                                                          │
│ ❱  948 │   │   │   return self.urlopen(                                                                                                 │
│    949 │   │   │   │   method,                                                                                                          │
│    950 │   │   │   │   url,                                                                                                             │
│    951 │   │   │   │   body,                                                                                                            │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\urllib3\connectionpool.py:948 in urlopen                                                                                            │
│                                                                                                                                         │
│    945 │   │   │   response.drain_conn()                                                                                                │
│    946 │   │   │   retries.sleep(response)                                                                                              │
│    947 │   │   │   log.debug("Retry: %s", url)                                                                                          │
│ ❱  948 │   │   │   return self.urlopen(                                                                                                 │
│    949 │   │   │   │   method,                                                                                                          │
│    950 │   │   │   │   url,                                                                                                             │
│    951 │   │   │   │   body,                                                                                                            │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\urllib3\connectionpool.py:948 in urlopen                                                                                            │
│                                                                                                                                         │
│    945 │   │   │   response.drain_conn()                                                                                                │
│    946 │   │   │   retries.sleep(response)                                                                                              │
│    947 │   │   │   log.debug("Retry: %s", url)                                                                                          │
│ ❱  948 │   │   │   return self.urlopen(                                                                                                 │
│    949 │   │   │   │   method,                                                                                                          │
│    950 │   │   │   │   url,                                                                                                             │
│    951 │   │   │   │   body,                                                                                                            │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\urllib3\connectionpool.py:938 in urlopen                                                                                            │
│                                                                                                                                         │
│    935 │   │   has_retry_after = bool(response.headers.get("Retry-After"))                                                              │
│    936 │   │   if retries.is_retry(method, response.status, has_retry_after):                                                           │
│    937 │   │   │   try:                                                                                                                 │
│ ❱  938 │   │   │   │   retries = retries.increment(method, url, response=response, _pool=self)                                          │
│    939 │   │   │   except MaxRetryError:                                                                                                │
│    940 │   │   │   │   if retries.raise_on_status:                                                                                      │
│    941 │   │   │   │   │   response.drain_conn()                                                                                        │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\urllib3\util\retry.py:515 in increment                                                                                              │
│                                                                                                                                         │
│   512 │   │                                                                                                                             │
│   513 │   │   if new_retry.is_exhausted():                                                                                              │
│   514 │   │   │   reason = error or ResponseError(cause)                                                                                │
│ ❱ 515 │   │   │   raise MaxRetryError(_pool, url, reason) from reason  # type:                                                          │
│       ignore[arg-type]                                                                                                                  │
│   516 │   │                                                                                                                             │
│   517 │   │   log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)                                                         │
│   518                                                                                                                                   │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
MaxRetryError: HTTPSConnectionPool(host='api.spotify.com', port=443): Max retries exceeded with url: /v1/albums/6V4QJ3nyhgFiMGGPH7VupN
(Caused by ResponseError('too many 429 error responses'))

During handling of the above exception, another exception occurred:

╭─────────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────────╮
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\spotipy\client.py:270 in _internal_call                                                                                             │
│                                                                                                                                         │
│    267 │   │   │   │   │    method, url, args.get("params"), headers, args.get('data'))                                                 │
│    268 │   │                                                                                                                            │
│    269 │   │   try:                                                                                                                     │
│ ❱  270 │   │   │   response = self._session.request(                                                                                    │
│    271 │   │   │   │   method, url, headers=headers, proxies=self.proxies,                                                              │
│    272 │   │   │   │   timeout=self.requests_timeout, **args                                                                            │
│    273 │   │   │   )                                                                                                                    │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\requests\sessions.py:589 in request                                                                                                 │
│                                                                                                                                         │
│   586 │   │   │   "allow_redirects": allow_redirects,                                                                                   │
│   587 │   │   }                                                                                                                         │
│   588 │   │   send_kwargs.update(settings)                                                                                              │
│ ❱ 589 │   │   resp = self.send(prep, **send_kwargs)                                                                                     │
│   590 │   │                                                                                                                             │
│   591 │   │   return resp                                                                                                               │
│   592                                                                                                                                   │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\requests\sessions.py:703 in send                                                                                                    │
│                                                                                                                                         │
│   700 │   │   start = preferred_clock()                                                                                                 │
│   701 │   │                                                                                                                             │
│   702 │   │   # Send the request                                                                                                        │
│ ❱ 703 │   │   r = adapter.send(request, **kwargs)                                                                                       │
│   704 │   │                                                                                                                             │
│   705 │   │   # Total elapsed time of the request (approximately)                                                                       │
│   706 │   │   elapsed = preferred_clock() - start                                                                                       │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\requests\adapters.py:691 in send                                                                                                    │
│                                                                                                                                         │
│   688 │   │   │   │   │   raise ConnectTimeout(e, request=request)                                                                      │
│   689 │   │   │                                                                                                                         │
│   690 │   │   │   if isinstance(e.reason, ResponseError):                                                                               │
│ ❱ 691 │   │   │   │   raise RetryError(e, request=request)                                                                              │
│   692 │   │   │                                                                                                                         │
│   693 │   │   │   if isinstance(e.reason, _ProxyError):                                                                                 │
│   694 │   │   │   │   raise ProxyError(e, request=request)                                                                              │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
RetryError: HTTPSConnectionPool(host='api.spotify.com', port=443): Max retries exceeded with url: /v1/albums/6V4QJ3nyhgFiMGGPH7VupN (Caused
by ResponseError('too many 429 error responses'))

During handling of the above exception, another exception occurred:

╭─────────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────────╮
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\spotdl\console\entry_point.py:142 in console_entry_point                                                                            │
│                                                                                                                                         │
│   139 │   try:                                                                                                                          │
│   140 │   │   # Pick the operation to perform                                                                                           │
│   141 │   │   # based on the name and run it!                                                                                           │
│ ❱ 142 │   │   OPERATIONS[arguments.operation](                                                                                          │
│   143 │   │   │   query=arguments.query,                                                                                                │
│   144 │   │   │   downloader=downloader,                                                                                                │
│   145 │   │   )                                                                                                                         │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\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"],                                                              │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\spotdl\utils\search.py:280 in get_simple_songs                                                                                      │
│                                                                                                                                         │
│   277 │   │   elif request == "all-user-followed-artists":                                                                              │
│   278 │   │   │   lists.extend(get_user_followed_artists())                                                                             │
│   279 │   │   elif request == "all-user-saved-albums":                                                                                  │
│ ❱ 280 │   │   │   lists.extend(get_user_saved_albums())                                                                                 │
│   281 │   │   elif request == "all-saved-playlists":                                                                                    │
│   282 │   │   │   lists.extend(get_all_saved_playlists())                                                                               │
│   283 │   │   elif request.endswith(".spotdl"):                                                                                         │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\spotdl\utils\search.py:443 in get_user_saved_albums                                                                                 │
│                                                                                                                                         │
│   440 │   │   user_saved_albums_response = response                                                                                     │
│   441 │   │   user_saved_albums.extend(user_saved_albums_response["items"])                                                             │
│   442 │                                                                                                                                 │
│ ❱ 443 │   return [                                                                                                                      │
│   444 │   │   Album.from_url(item["album"]["external_urls"]["spotify"], fetch_songs=False)                                              │
│   445 │   │   for item in user_saved_albums                                                                                             │
│   446 │   ]                                                                                                                             │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\spotdl\utils\search.py:444 in <listcomp>                                                                                            │
│                                                                                                                                         │
│   441 │   │   user_saved_albums.extend(user_saved_albums_response["items"])                                                             │
│   442 │                                                                                                                                 │
│   443 │   return [                                                                                                                      │
│ ❱ 444 │   │   Album.from_url(item["album"]["external_urls"]["spotify"], fetch_songs=False)                                              │
│   445 │   │   for item in user_saved_albums                                                                                             │
│   446 │   ]                                                                                                                             │
│   447                                                                                                                                   │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\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:                                                                                                           │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\spotdl\types\album.py:42 in get_metadata                                                                                            │
│                                                                                                                                         │
│    39 │   │                                                                                                                             │
│    40 │   │   spotify_client = SpotifyClient()                                                                                          │
│    41 │   │                                                                                                                             │
│ ❱  42 │   │   album_metadata = spotify_client.album(url)                                                                                │
│    43 │   │   if album_metadata is None:                                                                                                │
│    44 │   │   │   raise AlbumError(                                                                                                     │
│    45 │   │   │   │   "Couldn't get metadata, check if you have passed correct album id"                                                │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\spotipy\client.py:476 in album                                                                                                      │
│                                                                                                                                         │
│    473 │   │   if market is not None:                                                                                                   │
│    474 │   │   │   return self._get("albums/" + trid + '?market=' + market)                                                             │
│    475 │   │   else:                                                                                                                    │
│ ❱  476 │   │   │   return self._get("albums/" + trid)                                                                                   │
│    477 │                                                                                                                                │
│    478 │   def album_tracks(self, album_id, limit=50, offset=0, market=None):                                                           │
│    479 │   │   """ Get Spotify catalog information about an album's tracks                                                              │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\spotdl\utils\spotify.py:195 in _get                                                                                                 │
│                                                                                                                                         │
│   192 │   │   retries = self.max_retries  # type: ignore # pylint: disable=E1101                                                        │
│   193 │   │   while response is None:                                                                                                   │
│   194 │   │   │   try:                                                                                                                  │
│ ❱ 195 │   │   │   │   response = self._internal_call("GET", url, payload, kwargs)                                                       │
│   196 │   │   │   except (requests.exceptions.Timeout, requests.ConnectionError) as exc:                                                │
│   197 │   │   │   │   retries -= 1                                                                                                      │
│   198 │   │   │   │   if retries <= 0:                                                                                                  │
│                                                                                                                                         │
│ C:\Users\yayit\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packa │
│ ges\spotipy\client.py:311 in _internal_call                                                                                             │
│                                                                                                                                         │
│    308 │   │   │   │   reason = retry_error.args[0].reason                                                                              │
│    309 │   │   │   except (IndexError, AttributeError):                                                                                 │
│    310 │   │   │   │   reason = None                                                                                                    │
│ ❱  311 │   │   │   raise SpotifyException(                                                                                              │
│    312 │   │   │   │   429,                                                                                                             │
│    313 │   │   │   │   -1,                                                                                                              │
│    314 │   │   │   │   f"{request.path_url}:\n Max Retries",                                                                            │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
SpotifyException: http status: 429, code:-1 - /v1/albums/6V4QJ3nyhgFiMGGPH7VupN:
 Max Retries, reason: too many 429 error responses

Other details

I get same error with playlist with more than 400 songs.

@yayitazale yayitazale added the Bug Unexpected problem or unintended behavior that needs to be fixed label Jun 4, 2024
@Cylis-Dragneel
Copy link

Getting the same error, it seems to occur when the number of songs exceed 100. Larger number of songs downloaded fine before and I haven't updated spotdl since then so I tried updating and there wasn't any new update.

@dragonlutin
Copy link

same here

@sudo-userv2
Copy link

Having the same issue

@VlastikYoutubeKo
Copy link

Same issue.
I have 3k songs in my liked songs. I get this:

Processing query: saved
Max Retries reached

An error occurred
ResponseError: too many 429 error responses

The above exception was the direct cause of the following exception:

╭───────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────────╮
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\requests\adapters.py:486 in send                       │
│                                                                                                                      │
│   483 │   │   │   timeout = TimeoutSauce(connect=timeout, read=timeout)                                              │
│   484 │   │                                                                                                          │
│   485 │   │   try:                                                                                                   │
│ ❱ 486 │   │   │   resp = conn.urlopen(                                                                               │
│   487 │   │   │   │   method=request.method,                                                                         │
│   488 │   │   │   │   url=url,                                                                                       │
│   489 │   │   │   │   body=request.body,                                                                             │
│                                                                                                                      │
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\urllib3\connectionpool.py:948 in urlopen               │
│                                                                                                                      │
│    945 │   │   │   response.drain_conn()                                                                             │
│    946 │   │   │   retries.sleep(response)                                                                           │
│    947 │   │   │   log.debug("Retry: %s", url)                                                                       │
│ ❱  948 │   │   │   return self.urlopen(                                                                              │
│    949 │   │   │   │   method,                                                                                       │
│    950 │   │   │   │   url,                                                                                          │
│    951 │   │   │   │   body,                                                                                         │
│                                                                                                                      │
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\urllib3\connectionpool.py:948 in urlopen               │
│                                                                                                                      │
│    945 │   │   │   response.drain_conn()                                                                             │
│    946 │   │   │   retries.sleep(response)                                                                           │
│    947 │   │   │   log.debug("Retry: %s", url)                                                                       │
│ ❱  948 │   │   │   return self.urlopen(                                                                              │
│    949 │   │   │   │   method,                                                                                       │
│    950 │   │   │   │   url,                                                                                          │
│    951 │   │   │   │   body,                                                                                         │
│                                                                                                                      │
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\urllib3\connectionpool.py:948 in urlopen               │
│                                                                                                                      │
│    945 │   │   │   response.drain_conn()                                                                             │
│    946 │   │   │   retries.sleep(response)                                                                           │
│    947 │   │   │   log.debug("Retry: %s", url)                                                                       │
│ ❱  948 │   │   │   return self.urlopen(                                                                              │
│    949 │   │   │   │   method,                                                                                       │
│    950 │   │   │   │   url,                                                                                          │
│    951 │   │   │   │   body,                                                                                         │
│                                                                                                                      │
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\urllib3\connectionpool.py:938 in urlopen               │
│                                                                                                                      │
│    935 │   │   has_retry_after = bool(response.headers.get("Retry-After"))                                           │
│    936 │   │   if retries.is_retry(method, response.status, has_retry_after):                                        │
│    937 │   │   │   try:                                                                                              │
│ ❱  938 │   │   │   │   retries = retries.increment(method, url, response=response, _pool=self)                       │
│    939 │   │   │   except MaxRetryError:                                                                             │
│    940 │   │   │   │   if retries.raise_on_status:                                                                   │
│    941 │   │   │   │   │   response.drain_conn()                                                                     │
│                                                                                                                      │
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\urllib3\util\retry.py:515 in increment                 │
│                                                                                                                      │
│   512 │   │                                                                                                          │
│   513 │   │   if new_retry.is_exhausted():                                                                           │
│   514 │   │   │   reason = error or ResponseError(cause)                                                             │
│ ❱ 515 │   │   │   raise MaxRetryError(_pool, url, reason) from reason  # type:                                       │
│       ignore[arg-type]                                                                                               │
│   516 │   │                                                                                                          │
│   517 │   │   log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)                                      │
│   518                                                                                                                │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
MaxRetryError: HTTPSConnectionPool(host='api.spotify.com', port=443): Max retries exceeded with url:
/v1/me/tracks?offset=540&limit=20 (Caused by ResponseError('too many 429 error responses'))

During handling of the above exception, another exception occurred:

╭───────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────────╮
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\spotipy\client.py:266 in _internal_call                │
│                                                                                                                      │
│    263 │   │   │   │   │    method, url, args.get("params"), headers, args.get('data'))                              │
│    264 │   │                                                                                                         │
│    265 │   │   try:                                                                                                  │
│ ❱  266 │   │   │   response = self._session.request(                                                                 │
│    267 │   │   │   │   method, url, headers=headers, proxies=self.proxies,                                           │
│    268 │   │   │   │   timeout=self.requests_timeout, **args                                                         │
│    269 │   │   │   )                                                                                                 │
│                                                                                                                      │
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\requests\sessions.py:589 in request                    │
│                                                                                                                      │
│   586 │   │   │   "allow_redirects": allow_redirects,                                                                │
│   587 │   │   }                                                                                                      │
│   588 │   │   send_kwargs.update(settings)                                                                           │
│ ❱ 589 │   │   resp = self.send(prep, **send_kwargs)                                                                  │
│   590 │   │                                                                                                          │
│   591 │   │   return resp                                                                                            │
│   592                                                                                                                │
│                                                                                                                      │
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\requests\sessions.py:703 in send                       │
│                                                                                                                      │
│   700 │   │   start = preferred_clock()                                                                              │
│   701 │   │                                                                                                          │
│   702 │   │   # Send the request                                                                                     │
│ ❱ 703 │   │   r = adapter.send(request, **kwargs)                                                                    │
│   704 │   │                                                                                                          │
│   705 │   │   # Total elapsed time of the request (approximately)                                                    │
│   706 │   │   elapsed = preferred_clock() - start                                                                    │
│                                                                                                                      │
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\requests\adapters.py:510 in send                       │
│                                                                                                                      │
│   507 │   │   │   │   │   raise ConnectTimeout(e, request=request)                                                   │
│   508 │   │   │                                                                                                      │
│   509 │   │   │   if isinstance(e.reason, ResponseError):                                                            │
│ ❱ 510 │   │   │   │   raise RetryError(e, request=request)                                                           │
│   511 │   │   │                                                                                                      │
│   512 │   │   │   if isinstance(e.reason, _ProxyError):                                                              │
│   513 │   │   │   │   raise ProxyError(e, request=request)                                                           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
RetryError: HTTPSConnectionPool(host='api.spotify.com', port=443): Max retries exceeded with url:
/v1/me/tracks?offset=540&limit=20 (Caused by ResponseError('too many 429 error responses'))

During handling of the above exception, another exception occurred:

╭───────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────────╮
│ C:\Program Files\Python312\Lib\site-packages\spotdl\console\entry_point.py:142 in console_entry_point                │
│                                                                                                                      │
│   139 │   try:                                                                                                       │
│   140 │   │   # Pick the operation to perform                                                                        │
│   141 │   │   # based on the name and run it!                                                                        │
│ ❱ 142 │   │   OPERATIONS[arguments.operation](                                                                       │
│   143 │   │   │   query=arguments.query,                                                                             │
│   144 │   │   │   downloader=downloader,                                                                             │
│   145 │   │   )                                                                                                      │
│                                                                                                                      │
│ C:\Program Files\Python312\Lib\site-packages\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"],                                           │
│                                                                                                                      │
│ C:\Program Files\Python312\Lib\site-packages\spotdl\utils\search.py:274 in get_simple_songs                          │
│                                                                                                                      │
│   271 │   │   elif "artist:" in request:                                                                             │
│   272 │   │   │   lists.append(Artist.from_search_term(request, fetch_songs=False))                                  │
│   273 │   │   elif request == "saved":                                                                               │
│ ❱ 274 │   │   │   lists.append(Saved.from_url(request, fetch_songs=False))                                           │
│   275 │   │   elif request == "all-user-playlists":                                                                  │
│   276 │   │   │   lists.extend(get_all_user_playlists())                                                             │
│   277 │   │   elif request == "all-user-followed-artists":                                                           │
│                                                                                                                      │
│ C:\Program Files\Python312\Lib\site-packages\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:                                                                                        │
│                                                                                                                      │
│ C:\Program Files\Python312\Lib\site-packages\spotdl\types\saved.py:53 in get_metadata                                │
│                                                                                                                      │
│    50 │   │                                                                                                          │
│    51 │   │   # Fetch all saved tracks                                                                               │
│    52 │   │   while saved_tracks_response and saved_tracks_response["next"]:                                         │
│ ❱  53 │   │   │   response = spotify_client.next(saved_tracks_response)                                              │
│    54 │   │   │   if response is None:                                                                               │
│    55 │   │   │   │   break                                                                                          │
│    56                                                                                                                │
│                                                                                                                      │
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\spotipy\client.py:347 in next                          │
│                                                                                                                      │
│    344 │   │   │   │   - result - a previously returned paged result                                                 │
│    345 │   │   """                                                                                                   │
│    346 │   │   if result["next"]:                                                                                    │
│ ❱  347 │   │   │   return self._get(result["next"])                                                                  │
│    348 │   │   else:                                                                                                 │
│    349 │   │   │   return None                                                                                       │
│    350                                                                                                               │
│                                                                                                                      │
│ C:\Program Files\Python312\Lib\site-packages\spotdl\utils\spotify.py:195 in _get                                     │
│                                                                                                                      │
│   192 │   │   retries = self.max_retries  # type: ignore # pylint: disable=E1101                                     │
│   193 │   │   while response is None:                                                                                │
│   194 │   │   │   try:                                                                                               │
│ ❱ 195 │   │   │   │   response = self._internal_call("GET", url, payload, kwargs)                                    │
│   196 │   │   │   except (requests.exceptions.Timeout, requests.ConnectionError) as exc:                             │
│   197 │   │   │   │   retries -= 1                                                                                   │
│   198 │   │   │   │   if retries <= 0:                                                                               │
│                                                                                                                      │
│ C:\Users\admin\AppData\Roaming\Python\Python312\site-packages\spotipy\client.py:307 in _internal_call                │
│                                                                                                                      │
│    304 │   │   │   │   reason = retry_error.args[0].reason                                                           │
│    305 │   │   │   except (IndexError, AttributeError):                                                              │
│    306 │   │   │   │   reason = None                                                                                 │
│ ❱  307 │   │   │   raise SpotifyException(                                                                           │
│    308 │   │   │   │   429,                                                                                          │
│    309 │   │   │   │   -1,                                                                                           │
│    310 │   │   │   │   "%s:\n %s" % (request.path_url, "Max Retries"),                                               │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
SpotifyException: http status: 429, code:-1 - /v1/me/tracks?offset=540&limit=20:
 Max Retries, reason: too many 429 error responses

Command I used:

spotdl download saved "joost luchtballon" https://open.spotify.com/artist/6s5ubAp65wXoTZefE01RNR --user-auth --m3u {title}.m3u --id3-separator ", " --force-update-metadata --proxy "http://176.---.---.158:-----" --no-cache

@mahmoudk1000
Copy link

Same here

@VlastikYoutubeKo
Copy link

VlastikYoutubeKo commented Jun 8, 2024 via email

@mahmoudk1000
Copy link

mahmoudk1000 commented Jun 8, 2024

Uh, so it is somehow working now by using auth token 😆

Yes, indeed. Thanks for the tip :)

@VlastikYoutubeKo
Copy link

But now I am stuck on "Processing" when downloading songs...

@yayitazale
Copy link
Author

Still having same error with spotdl download saved --user-auth, spotdl download all-user-playlists --user-auth and spotdl download all-user-saved-albums --user-auth

@yayitazale yayitazale changed the title Runnng the commands to donwload user saved albums or songs fails with error 'ResponseError: too many 429 error responses' Running the commands to donwload user saved albums or songs fails with error 'ResponseError: too many 429 error responses' Jun 8, 2024
@truppelito
Copy link

I also just started having the same issue

@Cylis-Dragneel
Copy link

It's not even just user saved albums or songs, it fails if you try to download a playlist or all songs of an artist using the spotify link

@yayitazale
Copy link
Author

Today worked for me without any changes.

@llessi06
Copy link

Same issue here.
There is also an issue about the same problem at the spotipy repo.
spotipy-dev/spotipy#1093

@1RandomDev
Copy link

1RandomDev commented Jun 11, 2024

By default spotDL uses a preconfigured Spotify app thats the same for all users (so many users using spotDL at the same time will lead to the rate limit being exceeded). You can bypass this by creating your own app at https://developer.spotify.com/dashboard , for the name and description enter whatever you like, redirect URI http://127.0.0.1:9900/ and select Web API at the bottom. Then enter the client ID and client secret in the spotdl config.json.

Edit: you'll also need to delete the .spotipy file and relogin with your newly created app

@truppelito
Copy link

truppelito commented Jun 11, 2024

Would it be possible to add the possibility of providing those two items via the command line when running spotDL? That way it would be easy to fix for those of us using docker compose:

dl-spotify:
    image: spotdl/spotify-downloader:latest
    volumes:
        - xxxx:/music
    command: download https://open.spotify.com/xxxx --output "{album}/{title}.{output-ext}" 

@1RandomDev
Copy link

I think there actually are the options --client-id and --client-secret

@truppelito
Copy link

You're right, I just found them now. I was looking in the wrong place in the docs.

@truppelito
Copy link

FYI just adding those two options with my own Spotify app details worked:

dl-spotify:
    image: spotdl/spotify-downloader:latest
    volumes:
        - xxxx:/music
    command: download https://open.spotify.com/xxxx --output "{album}/{title}.{output-ext}" --client-id xxx --client-secret xxx

@sagivoulu
Copy link

I have a possible improvement suggestion.
Currently even when running spotdl sync and the song file doesn't need to be downloaded, still spotdl will query spotify once for every single song in the query. This of course takes time and can cause a querying limit.

Suggestion: assuming that song metadata doesn't change very often / ever, we can cache the response in a local file cache.
Still thinking about the interface, but how about adding these params:

--metadata-cache-path - Path to a local metadata cache file that will store metadata about fetched songs. This option can be used to speed up download times
--metadata-cache-ttl - The maximum amount of time to store a songs metadata in the local file cache. Set to 0 to never invalidate the cache

I wouldn't cache playlist metadata because it can change often (and usually there is only one / few playlists but many songs)

WDYT? would like your feedback
I will try to free up some time to implement this PR

@redfast00
Copy link

@sagivoulu you might want to think about your approach towards the metadata-cache-ttl; if all metadata expires at the same time, you will hit the rate limits once again.

Alternatively, you might want to implement respecting the Spotify ratelimits (using the Retry-After header, see https://developer.spotify.com/documentation/web-api/concepts/rate-limits). You could then sleep for that amount of time (and maybe tell the user that they will hit less rate limits if they add their own API keys.

@hseg
Copy link

hseg commented Jul 7, 2024

Alternatively, you might want to implement respecting the Spotify ratelimits (using the Retry-After header, see https://developer.spotify.com/documentation/web-api/concepts/rate-limits). You could then sleep for that amount of time.

This would make my work writing #2128 easier -- I need to use the default spotdl credentials for the tests, but the search endpoints are often rate-limited and it is unclear to me how long I need to wait before retrying.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Unexpected problem or unintended behavior that needs to be fixed
Projects
None yet
Development

No branches or pull requests