"""Spotify related helpers.""" import base64 import threading import requests import time class SpotifyAPI: def __init__(self, api_credentials): self._api_credentials = api_credentials self._counter_lock = threading.Lock() self._creds_number = 0 for creds in self._api_credentials: self._recreate_access_token_for_creds(creds) self._creds = self.get_creds() self._sleep_time = 1.0 def _obtain_access_token(self, client_id, secret_id): """Obtain access token for further Spotify API calls. Returns: str: access token. """ auth_token = '{}:{}'.format(client_id, secret_id) auth_token_encoded = base64.b64encode(auth_token.encode()).decode() resp = requests.post( 'https://accounts.spotify.com/api/token', data={'grant_type': 'client_credentials'}, headers={ 'Authorization': 'Basic {}'.format(auth_token_encoded)}).json() return resp['access_token'] def _auth_headers(self, access_token): return {'Authorization': 'Bearer {}'.format(access_token)} def _recreate_access_token_for_creds(self, creds): creds['access_token'] = self._obtain_access_token( creds['client_id'], creds['secret_id']) creds['headers'] = self._auth_headers(creds['access_token']) print(creds) def get_creds(self): while True: yield self._api_credentials[self._creds_number] self._creds_number += 1 self._creds_number = self._creds_number % len(self._api_credentials) def api_call(self, url, params): with self._counter_lock: creds = next(self._creds) headers = creds['headers'] sign = creds['access_token'][-5:] try: try_number = 0 while try_number < 5: try_number += 1 response = requests.get(url, params, headers=headers) json_data = response.json() if json_data.get('error', {}).get('status', 0) == 401: self._recreate_access_token_for_creds(creds) elif json_data.get('error', {}).get('status', 0) == 429: with self._counter_lock: self._sleep_time += 0.5 print('sleep {}'.format(self._sleep_time)) time.sleep(self._sleep_time) elif json_data: with self._counter_lock: if self._sleep_time > 0: self._sleep_time -= 0.01 return response.text, sign print('no response after retries {}', sign) return '{}', sign except Exception as e: print(e) return '{}', sign