def display_page(pathname, fullpath): if pathname == '/login': return login_layout elif pathname == '/': return home_layout elif pathname == '/callback': if os.getenv('SPOTIFY_USERNAME'): load_dotenv() # Get clientID and clientSecret from .env file client_id = os.getenv("CLIENT_ID") client_secret = os.getenv("CLIENT_SECRET") user_id = os.getenv("SPOTIFY_USERNAME") scope = 'user-read-private user-read-playback-state user-modify-playback-state user-top-read user-library-read playlist-modify-public playlist-modify-private' auth = SpotifyOAuth(client_id, client_secret, 'http://localhost:8050/callback', cache_path=f".cache-{user_id}", scope=scope) code = auth.parse_response_code(fullpath) # authenticate and get the access token try: # this is when the cache is written token = auth.get_access_token(code) return home_layout except spotipy.oauth2.SpotifyOauthError as e: return home_layout return index_page else: return index_page
def authorize_application(token_path, scopes): cached_data_path = os.path.join(os.path.split(__file__)[0], 'cached_data') if not os.path.isdir(cached_data_path): os.mkdir(cached_data_path) oauth = SpotifyOAuth(CLIENT_ID, APP_SECRET, REDIRECT_URI, cache_path=token_path, scope=scopes) authorization_url = oauth.get_authorize_url() webbrowser.open(authorization_url) authorization_response = input("Enter the full callback URL: ") code = oauth.parse_response_code(authorization_response) token = oauth.get_access_token(code) print("Authorization was successful!") return token
redirect_uri='http://localhost/', scope=scope) token_info = oauth.get_cached_token() if not token_info: auth_url = oauth.get_authorize_url() st.write(auth_url) response = st.text_input( 'Click the above link, then paste the redirect url here and hit enter: ' ) st.write( '*The BadAuth error below should go away after entering the redirect url' ) # response = input('Paste the above link into your browser, then paste the redirect url here: ') if response == "": time.sleep(5) code = oauth.parse_response_code(response) token_info = oauth.get_access_token(code) token = token_info['access_token'] sp = spotipy.Spotify(auth=token) ## helper functions spotify api def get_top_tracks(artist_id): return [x['id'] for x in sp.artist_top_tracks(artist_id)['tracks']] def check_playlist(user, pl_name): for playlist in sp.user_playlists(user)['items']: if pl_name == playlist['name']: return playlist['id'] else:
username = '******' scopes = 'playlist-modify-private' sp_oauth = SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, scope=scopes) token_info = sp_oauth.get_cached_token() if not token_info: auth_url = sp_oauth.get_authorize_url(show_dialog=True) print(auth_url) response = input( 'Paste the above link into your browser, then paste the redirect url here: ' ) code = sp_oauth.parse_response_code(response) token_info = sp_oauth.get_access_token(code) token = token_info['access_token'] sp = spotipy.Spotify(auth=token) # refresh function def refresh(): global token_info, sp if sp_oauth.is_token_expired(token_info): token_info = sp_oauth.refresh_access_token(token_info['refresh_token']) token = token_info['access_token'] sp = spotipy.Spotify(auth=token)
def main(): st.title('Nodata.tv Spotify Playlist Maker') st.header('By Xristos Katsaros') st.subheader( 'This app utilizes web scraping to find releases covered by Nodata.tv and places them in a Spotify playlist' ) st.header('Connect to Spotify') #defining spotify oauth parameters scope = 'playlist-modify-public' client_id = os.environ['client_id'] client_secret = os.environ['client_secret'] #initializing spotify oauth oauth = SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri='http://localhost:8080/', scope=scope) auth_url = oauth.get_authorize_url() st.write(auth_url) response = st.text_input( 'Click the link above, then copy the URL from the new tab, paste it here, and press enter: ' ) #defining variables genres = pickle.load(open('genres.pkl', 'rb')) years = list(range(1990, 2022)) st.header('Select playlist preferences') st.text('Number of pages to scrape on the Nodata blog') pages = st.selectbox('Pages', list(range(1, 1800))) user_genre1 = st.selectbox('Genre 1', sorted(list(genres))) user_genre2 = st.selectbox('Genre 2', sorted(list(genres))) user_genres = [user_genre1, user_genre2] username = st.text_input('Spotify username') playlist_name = st.text_input('Name of new or existing playlist') year = str(st.selectbox('Year', sorted(years, reverse=True))) if st.button('Make playlist'): #connect to spotify code = oauth.parse_response_code(response) token_info = oauth.get_access_token(code) token = token_info['access_token'] sp = spotipy.Spotify(auth=token) #get the names of of all the user's playlists playlists = [ x['name'].lower() for x in sp.current_user_playlists()['items'] ] #determine playlist ID if playlist_name not in playlists: sp.user_playlist_create(user=username, name=playlist_name) #create a new playlist playlist_id = sp.current_user_playlists()['items'][0][ 'id'] #grab new playlist ID elif playlist_name in playlists: playlist_id = sp.current_user_playlists()['items'][playlists.index( playlist_name)]['id'] #find ID of existing playlist #the 2 main functions for scraping & searching spotify scrape_results = scraper.scrape(int(pages), user_genres, year) #scrapes nodata.tv spotify_results = search_spotify( scrape_results, sp) #inserts scraped results into search function confirm_and_add(spotify_results, username, playlist_id, sp)
class SpotifyAuthManager(): """ A class used to handle Spotify Oauth. Refreshable user authentication. Owned by Playlist & ArtistManager. Args: Instance Attributes Class Attributes: """ username = os.environ['SPOTIFY_USERNAME'] client_id = os.environ['SPOTIFY_CLIENT_ID'] client_secret = os.environ['SPOTIFY_CLIENT_SECRET'] scope = os.environ['SPOTIFY_SCOPE'] redirect_uri = os.environ['SPOTIFY_REDIRECT_URI'] def __init__(self, session=None): self.token_info = None self.response_code = None self.client_mgr = None self.session = session # use same session # self.session = session def create_client_mgr(self): """ Create SpotifyOauth object. Args: client_id client_secret redirect_uri scope cache_path """ cache_path = WindowsPath("__pycache__") / fr'.cache-{self.username}' self.client_mgr = SpotifyOAuth(self.client_id, self.client_secret, self.redirect_uri, scope=self.scope, cache_path=cache_path) return self def get_auth_token(self): """ Get oauth token from cache or prompt for new token. """ try: self.token_info = self.client_mgr.get_cached_token() logger.info( f"Token expires at {time.strftime('%c', time.localtime(self.token_info['expires_at']))}" ) return self # TODO: add specific exceptions except Exception: logger.info("No token in cache. Getting new token.", exc_info=True) auth_url = self.client_mgr.get_authorize_url() user_auth = self.session.get(auth_url).url response_code = input(f'Use Browser to authenticate: {user_auth}') code = self.client_mgr.parse_response_code(response_code) self.token_info = self.client_mgr.get_access_token(code) with open(self.client_mgr.cache_path, 'w') as f: f.write(json.dumps(self.token_info)) def refresh_auth_token(self): """ Refresh authentication token. Same spotify obect used throughout. How to call from owning classes. """ self.client_mgr.refresh_access_token(self.token_info['refresh_token']) logger.info( f"Token refreshed, expires at: {time.strftime('%c', time.localtime(self.token_info['expires_at']))}" ) def create_spotify(self): """ Create Spotify object for Authorization Code flow. Args: token, session, client_mgr """ try: auth_info = { 'auth': self.token_info['access_token'], 'requests_session': self.session, 'client_credentials_manager': self.client_mgr } return catch(spotipy.Spotify, auth_info) except TypeError: # Why TypeError? logger.error("Token error.", exc_info=True)
def prompt_for_user_token(username, scope=None, client_id=None, client_secret=None, redirect_uri=None, cache_path=None): """ Function taken & modified from the spotipy library """ ''' prompts the user to login if necessary and returns the user token suitable for use with the spotipy.Spotify constructor Parameters: - username - the Spotify username - scope - the desired scope of the request - client_id - the client id of your app - client_secret - the client secret of your app - redirect_uri - the redirect URI of your app - cache_path - path to location to save tokens ''' cache_path = cache_path or ".cache-" + username sp_oauth = SpotifyOAuth(client_id, client_secret, redirect_uri, scope=scope, cache_path=cache_path) # try to get a valid token for this user, from the cache, # if not in the cache, then create a new token (this will send # the user to a web page where they can authorize this app) token_info = sp_oauth.get_cached_token() if not token_info: print(''' User authentication requires interaction with your web browser. Once you enter your credentials and give authorization, you will be redirected to a url. Paste that url you were directed to to complete the authorization. ''') auth_url = sp_oauth.get_authorize_url() try: r = requests.get(auth_url) response = r.url code = sp_oauth.parse_response_code(response) token_info = sp_oauth.get_access_token(code) except Exception as e: print(e) try: import webbrowser webbrowser.open(auth_url) print("Opened %s in your browser" % auth_url) except: print("Please navigate here: %s" % auth_url) print() print() try: response = raw_input("Enter the URL you were redirected to: ") except NameError: response = input("Enter the URL you were redirected to: ") code = sp_oauth.parse_response_code(response) token_info = sp_oauth.get_access_token(code) # Auth'ed API request if token_info: return token_info['access_token'] else: return None