Search code examples
pythonspotify

Python - Spotify API - No Authorization Code received with <Response [200]>


I have looked at several posts here about issues very close to this one including one that is exactly the same but no one gave an answer so I am going to give it a go. I am very new to Python. My current homework is to connect to Spotify using their API. According to the documentation on authorization code flow in Spotify. the response to the authorization request should provide two items: code and state.

After I send my request

def authenticate_user():
auth_code = requests.get(ENPOINT_USER_AUTH, {
    'client_id': CLIENT_ID,
    'response_type': 'code',
    'redirect_uri': 'https://www.example.com/',
    'scope': 'playlist-modify-private'
})

print(f'Auth code: {auth_code}')

I get a Auth code: <Response [200]>. The response however does not include a code or state. What comes with the response though, is a URL that I can copy-paste into the browser which will redirect me to a callabck URL with the code in it.

My issue here is, I want to save that code into a variable in my Python code. This copy-pasting into a browser can't be the way to do this.

My other problem is that I really don't know what a callback server/redirect is and how to use or set it up to extract this information, or how do achieve this in my python code.

Basically a lot of beginer' questions I apologize. But it's been hours of research and reading and I really would like some input.

This is what the redirect URL looks like after pasting the URL I get in the response.

https://www.example.com/?code=AQAqA0eYYk......JLVUomOR0ziDTcIupZoU

I hope this is clear and I am making sense.

Thank you in advance.

Oh, and I know about Spotipy and that it's supposed to simplify things but I am not interested. I want to learn to use the Spotify aPI.

To make it short and clear: how can I obtain this "code" from their response URL and save it into a variable in my python code programmatically?

EDIT:

Let's say that I want to keep a main.py for the logic and a service.py for the for the localhost services.

Once I have authenticated the user and I get the URL that redirects, how can I feed this URL to my service to get the final URL. I want to be able to send requests from my main.py to the service and get the data in the response rather than keeping everything on the service side.


Solution

  • I will demo two versions (full and simple) for get playlist API call.

    Full Version

    This code is v1 using Flask and requests_oauthlib.

    The redirect URL should be match with your Developer Dashboard configuration in here.

    Developer Dashboard

    https://developer.spotify.com/dashboard
    

    Save as full_code.py file name.

    from flask import Flask, request, redirect
    from requests_oauthlib import OAuth2Session
    from requests.auth import HTTPBasicAuth
    import os
    import requests
    import json
    
    app = Flask(__name__)
    
    AUTH_URL = 'https://accounts.spotify.com/authorize'
    TOKEN_URL = 'https://accounts.spotify.com/api/token'
    PORT = 3000 # replace <your redirect port>
    REDIRECT_URI = 'http://localhost:{}/callback'.format(PORT) # my configuration is 'http://localhost:3000/callback' in dashboard
    CLIENT_ID = '<your client id>'
    CLIENT_SECRET = '<your client secret>'
    # You can add your required scopes
    SCOPE = [
        'user-read-currently-playing',
        'playlist-modify-private'
    ]
    @app.route("/login")
    def login():
        spotify = OAuth2Session(client_id = CLIENT_ID, scope=SCOPE, redirect_uri=REDIRECT_URI)
        authorization_url, state = spotify.authorization_url(AUTH_URL)
        return redirect(authorization_url)
    
    @app.route("/callback", methods=['GET'])
    def callback():
        code = request.args.get('code')
        response = requests.post(TOKEN_URL,
            auth = HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET),
            data = {
                'grant_type': 'authorization_code',
                'code': code,
                'redirect_uri': REDIRECT_URI
            })
        # Save Access Token to environment variable
        os.environ['ACCESS_TOKEN'] = response.json()['access_token']
        headers = {
            # Get Access Token from environment variable
            'Authorization': "Bearer {}".format(os.environ['ACCESS_TOKEN'])
        }
    
        # get playlist API call with <your playlist id>
        url = 'https://api.spotify.com/v1/playlists/{}'.format('37i9dQZF1DX0tnKPLNG9Ld')
        response = requests.get(url, headers=headers)
        results = response.json()
        songs = []
        for item in results['tracks']['items']:
            if (item is not None and item['track']['artists'][0] is not None):
                # display format <artists name : song title>
                songs.append(item['track']['artists'][0]['name']  + " : " + item['track']['name'])
        return json.dumps(songs)
    
    if __name__ == '__main__':
        app.run(port = PORT,debug = True)
    

    Run it

    python full_code.py
    

    Then open URL by browser

    http://localhost:3000/login
    

    Result enter image description here

    Simple Version

    Using spotipy

    Save as simple_code.py file name.

    import spotipy
    from spotipy.oauth2 import SpotifyOAuth
    
    PORT = 3000 # replace <your redirect port>
    REDIRECT_URI = 'http://localhost:{}/callback'.format(PORT) # my configuration is 'http://localhost:3000/callback' in dashboard
    CLIENT_ID = '<your client id>'
    CLIENT_SECRET = '<your client secret>'
    PLAYLIST_ID = '37i9dQZF1DX0tnKPLNG9Ld' # <your playlist id>
    
    sp = spotipy.Spotify(
        auth_manager = SpotifyOAuth(
            client_id = CLIENT_ID,
            client_secret = CLIENT_SECRET,
            redirect_uri = REDIRECT_URI,
            # You can add your required scopes
            scope=['user-read-currently-playing','playlist-modify-private']))
    
    def Get_Playlist(playlist_id):
        # get playlist API call
        results = sp.playlist(playlist_id)
        for item in results['tracks']['items']:
            if (item is not None and item['track']['artists'][0] is not None):
                # artists name : song title
                print(item['track']['artists'][0]['name']  + "\t" + " : " + item['track']['name'])
    
    Get_Playlist(PLAYLIST_ID)
    

    Run it

    python simple_code.py
    

    Result

    enter image description here