├── README.md ├── main.py └── templates └── index.html /README.md: -------------------------------------------------------------------------------- 1 | Authorization Code Flow Walkthrough 2 | ======= 3 | 4 | How to do an authorization code flow, through Flask and Python. 5 | 6 | ##Step 1 7 | Fill in your credentials in main.py. This includes the CLIENT_ID and CLIENT_SECRET, which is left blank. You can obtain this by going to [Spotify Developers](https://developer.spotify.com/my-applications/#!/). 8 | 9 | 10 | ##Step 2 11 | Be sure that your redirect uri, inside your application page in the Spotify Developers website is "http://127.0.0.1:8080/callback/q". 12 | 13 | 14 | ##Step 3 15 | To see that it works, simply run the application by running '''python main.py''', and point your browser to http://127.0.0.1:8080. 16 | 17 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import json 2 | from flask import Flask, request, redirect, g, render_template 3 | import requests 4 | from urllib.parse import quote 5 | 6 | # Authentication Steps, paramaters, and responses are defined at https://developer.spotify.com/web-api/authorization-guide/ 7 | # Visit this url to see all the steps, parameters, and expected response. 8 | 9 | 10 | app = Flask(__name__) 11 | 12 | # Client Keys 13 | CLIENT_ID = "" 14 | CLIENT_SECRET = "" 15 | 16 | # Spotify URLS 17 | SPOTIFY_AUTH_URL = "https://accounts.spotify.com/authorize" 18 | SPOTIFY_TOKEN_URL = "https://accounts.spotify.com/api/token" 19 | SPOTIFY_API_BASE_URL = "https://api.spotify.com" 20 | API_VERSION = "v1" 21 | SPOTIFY_API_URL = "{}/{}".format(SPOTIFY_API_BASE_URL, API_VERSION) 22 | 23 | # Server-side Parameters 24 | CLIENT_SIDE_URL = "http://127.0.0.1" 25 | PORT = 8080 26 | REDIRECT_URI = "{}:{}/callback/q".format(CLIENT_SIDE_URL, PORT) 27 | SCOPE = "playlist-modify-public playlist-modify-private" 28 | STATE = "" 29 | SHOW_DIALOG_bool = True 30 | SHOW_DIALOG_str = str(SHOW_DIALOG_bool).lower() 31 | 32 | auth_query_parameters = { 33 | "response_type": "code", 34 | "redirect_uri": REDIRECT_URI, 35 | "scope": SCOPE, 36 | # "state": STATE, 37 | # "show_dialog": SHOW_DIALOG_str, 38 | "client_id": CLIENT_ID 39 | } 40 | 41 | 42 | @app.route("/") 43 | def index(): 44 | # Auth Step 1: Authorization 45 | url_args = "&".join(["{}={}".format(key, quote(val)) for key, val in auth_query_parameters.items()]) 46 | auth_url = "{}/?{}".format(SPOTIFY_AUTH_URL, url_args) 47 | return redirect(auth_url) 48 | 49 | 50 | @app.route("/callback/q") 51 | def callback(): 52 | # Auth Step 4: Requests refresh and access tokens 53 | auth_token = request.args['code'] 54 | code_payload = { 55 | "grant_type": "authorization_code", 56 | "code": str(auth_token), 57 | "redirect_uri": REDIRECT_URI, 58 | 'client_id': CLIENT_ID, 59 | 'client_secret': CLIENT_SECRET, 60 | } 61 | post_request = requests.post(SPOTIFY_TOKEN_URL, data=code_payload) 62 | 63 | # Auth Step 5: Tokens are Returned to Application 64 | response_data = json.loads(post_request.text) 65 | access_token = response_data["access_token"] 66 | refresh_token = response_data["refresh_token"] 67 | token_type = response_data["token_type"] 68 | expires_in = response_data["expires_in"] 69 | 70 | # Auth Step 6: Use the access token to access Spotify API 71 | authorization_header = {"Authorization": "Bearer {}".format(access_token)} 72 | 73 | # Get profile data 74 | user_profile_api_endpoint = "{}/me".format(SPOTIFY_API_URL) 75 | profile_response = requests.get(user_profile_api_endpoint, headers=authorization_header) 76 | profile_data = json.loads(profile_response.text) 77 | 78 | # Get user playlist data 79 | playlist_api_endpoint = "{}/playlists".format(profile_data["href"]) 80 | playlists_response = requests.get(playlist_api_endpoint, headers=authorization_header) 81 | playlist_data = json.loads(playlists_response.text) 82 | 83 | # Combine profile and playlist data to display 84 | display_arr = [profile_data] + playlist_data["items"] 85 | return render_template("index.html", sorted_array=display_arr) 86 | 87 | 88 | if __name__ == "__main__": 89 | app.run(debug=True, port=PORT) 90 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% for item in sorted_array%} 4 |

{{ item }}

5 | {% endfor %} 6 | 7 | --------------------------------------------------------------------------------