spotDL / spotify-downloader

Download your Spotify playlists and songs along with album art and metadata (from YouTube if a match is found).
https://spotdl.readthedocs.io/en/latest/
MIT License
17.31k stars 1.6k forks source link

ReadTimeout: HTTPSConnectionPool(host='api.spotify.com', port=443): Read timed out. (read timeout=5) #1957

Closed periode closed 11 months ago

periode commented 11 months ago

System OS

Linux

Python Version

3.7 (CPython)

Install Source

pip / PyPi

Install version / commit hash

v4.2.1

Expected Behavior vs Actual Behavior

I'm expecting a playlist to be downloaded to the folder. It worked about 12 hours ago, but now fails on timeout.

Steps to reproduce - Ensure to include actual links!

spotdl download https://open.spotify.com/playlist/0XQLRkc8FO1EG4Yqw1LZ6u?si=KTSrGBMdTzeltMC_fdWSqg

Traceback

Processing query:
https://open.spotify.com/playlist/0XQLRkc8FO1EG4Yqw1LZ6u?si=KTSrGBMdTzeltMC_fdWS
qg                                                                              

An error occurred
╭───────────────────── Traceback (most recent call last) ──────────────────────╮
│ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:446 in              │
│ _make_request                                                                │
│                                                                              │
│    443 │   │   │   │   │   # Remove the TypeError from the exception chain i │
│    444 │   │   │   │   │   # Python 3 (including for exceptions like SystemE │
│    445 │   │   │   │   │   # Otherwise it looks like a bug in the code.      │
│ ❱  446 │   │   │   │   │   six.raise_from(e, None)                           │
│    447 │   │   except (SocketTimeout, BaseSSLError, SocketError) as e:       │
│    448 │   │   │   self._raise_timeout(err=e, url=url, timeout_value=read_ti │
│    449 │   │   │   raise                                                     │
│ in raise_from:3                                                              │
│                                                                              │
│ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:441 in              │
│ _make_request                                                                │
│                                                                              │
│    438 │   │   │   except TypeError:                                         │
│    439 │   │   │   │   # Python 3                                            │
│    440 │   │   │   │   try:                                                  │
│ ❱  441 │   │   │   │   │   httplib_response = conn.getresponse()             │
│    442 │   │   │   │   except BaseException as e:                            │
│    443 │   │   │   │   │   # Remove the TypeError from the exception chain i │
│    444 │   │   │   │   │   # Python 3 (including for exceptions like SystemE │
│                                                                              │
│ /usr/lib/python3.10/http/client.py:1375 in getresponse                       │
│                                                                              │
│   1372 │   │                                                                 │
│   1373 │   │   try:                                                          │
│   1374 │   │   │   try:                                                      │
│ ❱ 1375 │   │   │   │   response.begin()                                      │
│   1376 │   │   │   except ConnectionError:                                   │
│   1377 │   │   │   │   self.close()                                          │
│   1378 │   │   │   │   raise                                                 │
│                                                                              │
│ /usr/lib/python3.10/http/client.py:318 in begin                              │
│                                                                              │
│    315 │   │                                                                 │
│    316 │   │   # read until we get a non-100 response                        │
│    317 │   │   while True:                                                   │
│ ❱  318 │   │   │   version, status, reason = self._read_status()             │
│    319 │   │   │   if status != CONTINUE:                                    │
│    320 │   │   │   │   break                                                 │
│    321 │   │   │   # skip the header from the 100 response                   │
│                                                                              │
│ /usr/lib/python3.10/http/client.py:279 in _read_status                       │
│                                                                              │
│    276 │   │   self.will_close = _UNKNOWN      # conn will close at end of r │
│    277 │                                                                     │
│    278 │   def _read_status(self):                                           │
│ ❱  279 │   │   line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")      │
│    280 │   │   if len(line) > _MAXLINE:                                      │
│    281 │   │   │   raise LineTooLong("status line")                          │
│    282 │   │   if self.debuglevel > 0:                                       │
│                                                                              │
│ /usr/lib/python3.10/socket.py:705 in readinto                                │
│                                                                              │
│   702 │   │   │   raise OSError("cannot read from timed out object")         │
│   703 │   │   while True:                                                    │
│   704 │   │   │   try:                                                       │
│ ❱ 705 │   │   │   │   return self._sock.recv_into(b)                         │
│   706 │   │   │   except timeout:                                            │
│   707 │   │   │   │   self._timeout_occurred = True                          │
│   708 │   │   │   │   raise                                                  │
│                                                                              │
│ /usr/lib/python3.10/ssl.py:1274 in recv_into                                 │
│                                                                              │
│   1271 │   │   │   │   raise ValueError(                                     │
│   1272 │   │   │   │     "non-zero flags not allowed in calls to recv_into() │
│   1273 │   │   │   │     self.__class__)                                     │
│ ❱ 1274 │   │   │   return self.read(nbytes, buffer)                          │
│   1275 │   │   else:                                                         │
│   1276 │   │   │   return super().recv_into(buffer, nbytes, flags)           │
│   1277                                                                       │
│                                                                              │
│ /usr/lib/python3.10/ssl.py:1130 in read                                      │
│                                                                              │
│   1127 │   │   │   raise ValueError("Read on closed or unwrapped SSL socket. │
│   1128 │   │   try:                                                          │
│   1129 │   │   │   if buffer is not None:                                    │
│ ❱ 1130 │   │   │   │   return self._sslobj.read(len, buffer)                 │
│   1131 │   │   │   else:                                                     │
│   1132 │   │   │   │   return self._sslobj.read(len)                         │
│   1133 │   │   except SSLError as x:                                         │
╰──────────────────────────────────────────────────────────────────────────────╯
TimeoutError: The read operation timed out

During handling of the above exception, another exception occurred:

╭───────────────────── Traceback (most recent call last) ──────────────────────╮
│ /home/pierre/.local/lib/python3.10/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,                                     │
│                                                                              │
│ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:851 in urlopen      │
│                                                                              │
│    848 │   │   │   response.drain_conn()                                     │
│    849 │   │   │   retries.sleep(response)                                   │
│    850 │   │   │   log.debug("Retry: %s", url)                               │
│ ❱  851 │   │   │   return self.urlopen(                                      │
│    852 │   │   │   │   method,                                               │
│    853 │   │   │   │   url,                                                  │
│    854 │   │   │   │   body,                                                 │
│                                                                              │
│ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:851 in urlopen      │
│                                                                              │
│    848 │   │   │   response.drain_conn()                                     │
│    849 │   │   │   retries.sleep(response)                                   │
│    850 │   │   │   log.debug("Retry: %s", url)                               │
│ ❱  851 │   │   │   return self.urlopen(                                      │
│    852 │   │   │   │   method,                                               │
│    853 │   │   │   │   url,                                                  │
│    854 │   │   │   │   body,                                                 │
│                                                                              │
│ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:756 in urlopen      │
│                                                                              │
│    753 │   │   │   elif isinstance(e, (SocketError, HTTPException)):         │
│    754 │   │   │   │   e = ProtocolError("Connection aborted.", e)           │
│    755 │   │   │                                                             │
│ ❱  756 │   │   │   retries = retries.increment(                              │
│    757 │   │   │   │   method, url, error=e, _pool=self, _stacktrace=sys.exc │
│    758 │   │   │   )                                                         │
│    759 │   │   │   retries.sleep()                                           │
│                                                                              │
│ /usr/lib/python3/dist-packages/urllib3/util/retry.py:532 in increment        │
│                                                                              │
│   529 │   │   elif error and self._is_read_error(error):                     │
│   530 │   │   │   # Read retry?                                              │
│   531 │   │   │   if read is False or not self._is_method_retryable(method): │
│ ❱ 532 │   │   │   │   raise six.reraise(type(error), error, _stacktrace)     │
│   533 │   │   │   elif read is not None:                                     │
│   534 │   │   │   │   read -= 1                                              │
│   535                                                                        │
│                                                                              │
│ /usr/lib/python3/dist-packages/six.py:719 in reraise                         │
│                                                                              │
│   716 │   │   │   │   value = tp()                                           │
│   717 │   │   │   if value.__traceback__ is not tb:                          │
│   718 │   │   │   │   raise value.with_traceback(tb)                         │
│ ❱ 719 │   │   │   raise value                                                │
│   720 │   │   finally:                                                       │
│   721 │   │   │   value = None                                               │
│   722 │   │   │   tb = None                                                  │
│                                                                              │
│ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:700 in urlopen      │
│                                                                              │
│    697 │   │   │   │   self._prepare_proxy(conn)                             │
│    698 │   │   │                                                             │
│    699 │   │   │   # Make the request on the httplib connection object.      │
│ ❱  700 │   │   │   httplib_response = self._make_request(                    │
│    701 │   │   │   │   conn,                                                 │
│    702 │   │   │   │   method,                                               │
│    703 │   │   │   │   url,                                                  │
│                                                                              │
│ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:448 in              │
│ _make_request                                                                │
│                                                                              │
│    445 │   │   │   │   │   # Otherwise it looks like a bug in the code.      │
│    446 │   │   │   │   │   six.raise_from(e, None)                           │
│    447 │   │   except (SocketTimeout, BaseSSLError, SocketError) as e:       │
│ ❱  448 │   │   │   self._raise_timeout(err=e, url=url, timeout_value=read_ti │
│    449 │   │   │   raise                                                     │
│    450 │   │                                                                 │
│    451 │   │   # AppEngine doesn't have a version attr.                      │
│                                                                              │
│ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:337 in              │
│ _raise_timeout                                                               │
│                                                                              │
│    334 │   │   """Is the error actually a timeout? Will raise a ReadTimeout  │
│    335 │   │                                                                 │
│    336 │   │   if isinstance(err, SocketTimeout):                            │
│ ❱  337 │   │   │   raise ReadTimeoutError(                                   │
│    338 │   │   │   │   self, url, "Read timed out. (read timeout=%s)" % time │
│    339 │   │   │   )                                                         │
│    340                                                                       │
╰──────────────────────────────────────────────────────────────────────────────╯
ReadTimeoutError: HTTPSConnectionPool(host='api.spotify.com', port=443): Read
timed out. (read timeout=5)

During handling of the above exception, another exception occurred:

╭───────────────────── Traceback (most recent call last) ──────────────────────╮
│ /home/pierre/.local/lib/python3.10/site-packages/spotdl/console/entry_point. │
│ py:125 in console_entry_point                                                │
│                                                                              │
│   122 │   try:                                                               │
│   123 │   │   # Pick the operation to perform                                │
│   124 │   │   # based on the name and run it!                                │
│ ❱ 125 │   │   OPERATIONS[arguments.operation](                               │
│   126 │   │   │   query=arguments.query,                                     │
│   127 │   │   │   downloader=downloader,                                     │
│   128 │   │   )                                                              │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/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"],   │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/site-packages/spotdl/utils/search.py:239  │
│ in get_simple_songs                                                          │
│                                                                              │
│   236 │   │   │   resp = requests.head(request, allow_redirects=True, timeou │
│   237 │   │   │   songs.append(Song.from_url(url=resp.url))                  │
│   238 │   │   elif "open.spotify.com" in request and "playlist" in request:  │
│ ❱ 239 │   │   │   lists.append(Playlist.from_url(request, fetch_songs=False) │
│   240 │   │   elif "open.spotify.com" in request and "album" in request:     │
│   241 │   │   │   lists.append(Album.from_url(request, fetch_songs=False))   │
│   242 │   │   elif "open.spotify.com" in request and "artist" in request:    │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/site-packages/spotdl/types/song.py:298 in │
│ from_url                                                                     │
│                                                                              │
│   295 │   │   - The SongList object.                                         │
│   296 │   │   """                                                            │
│   297 │   │                                                                  │
│ ❱ 298 │   │   metadata, songs = cls.get_metadata(url)                        │
│   299 │   │   urls = [song.url for song in songs]                            │
│   300 │   │                                                                  │
│   301 │   │   if fetch_songs:                                                │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/site-packages/spotdl/types/playlist.py:48 │
│ in get_metadata                                                              │
│                                                                              │
│    45 │   │                                                                  │
│    46 │   │   spotify_client = SpotifyClient()                               │
│    47 │   │                                                                  │
│ ❱  48 │   │   playlist = spotify_client.playlist(url)                        │
│    49 │   │   if playlist is None:                                           │
│    50 │   │   │   raise PlaylistError("Invalid playlist URL.")               │
│    51                                                                        │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/site-packages/spotipy/client.py:651 in    │
│ playlist                                                                     │
│                                                                              │
│    648 │   │   │   │   │   │   │   │   │    valid types are: track and episo │
│    649 │   │   """                                                           │
│    650 │   │   plid = self._get_id("playlist", playlist_id)                  │
│ ❱  651 │   │   return self._get(                                             │
│    652 │   │   │   "playlists/%s" % (plid),                                  │
│    653 │   │   │   fields=fields,                                            │
│    654 │   │   │   market=market,                                            │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/site-packages/spotdl/utils/spotify.py:199 │
│ in _get                                                                      │
│                                                                              │
│   196 │   │   │   except (requests.exceptions.Timeout, requests.ConnectionEr │
│   197 │   │   │   │   retries -= 1                                           │
│   198 │   │   │   │   if retries <= 0:                                       │
│ ❱ 199 │   │   │   │   │   raise exc                                          │
│   200 │   │                                                                  │
│   201 │   │   if use_cache and cache_key is not None:                        │
│   202 │   │   │   self.cache[cache_key] = response                           │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/site-packages/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:                                       │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/site-packages/spotipy/client.py:266 in    │
│ _internal_call                                                               │
│                                                                              │
│    263 │   │   │   │   │    method, url, args.get("params"), headers, args.g │
│    264 │   │                                                                 │
│    265 │   │   try:                                                          │
│ ❱  266 │   │   │   response = self._session.request(                         │
│    267 │   │   │   │   method, url, headers=headers, proxies=self.proxies,   │
│    268 │   │   │   │   timeout=self.requests_timeout, **args                 │
│    269 │   │   │   )                                                         │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/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                                                                        │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/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                            │
│                                                                              │
│ /home/pierre/.local/lib/python3.10/site-packages/requests/adapters.py:532 in │
│ send                                                                         │
│                                                                              │
│   529 │   │   │   │   # This branch is for urllib3 versions earlier than v1. │
│   530 │   │   │   │   raise SSLError(e, request=request)                     │
│   531 │   │   │   elif isinstance(e, ReadTimeoutError):                      │
│ ❱ 532 │   │   │   │   raise ReadTimeout(e, request=request)                  │
│   533 │   │   │   elif isinstance(e, _InvalidHeader):                        │
│   534 │   │   │   │   raise InvalidHeader(e, request=request)                │
│   535 │   │   │   else:                                                      │
╰──────────────────────────────────────────────────────────────────────────────╯

ReadTimeout: HTTPSConnectionPool(host='api.spotify.com', port=443): Read timed
out. (read timeout=5)


### Other details

Running this on a remote server.

Thanks!
periode commented 11 months ago

Update:

It looks like the Playlists endpoint for the spotify API is down, I'll retry when it's fully up: https://status.spotify.dev/

xnetcat commented 11 months ago

should be up again