0
# Authentication
1
2
Spotipy supports multiple OAuth2 flows for authenticating with the Spotify Web API. Choose the appropriate flow based on your application type and requirements.
3
4
## Capabilities
5
6
### Client Credentials Flow
7
8
For server-to-server authentication without user interaction. Provides access to public Spotify data only.
9
10
```python { .api }
11
class SpotifyClientCredentials:
12
def __init__(self, client_id=None, client_secret=None, proxies=None,
13
requests_session=True, requests_timeout=None, cache_handler=None):
14
"""
15
Client Credentials flow for app-only authentication.
16
17
Args:
18
client_id (str, optional): Spotify client ID (from environment if not provided)
19
client_secret (str, optional): Spotify client secret (from environment if not provided)
20
proxies (dict, optional): Proxy configuration
21
requests_session (bool or requests.Session): HTTP session configuration
22
requests_timeout (int, optional): Request timeout in seconds
23
cache_handler (CacheHandler, optional): Token cache handler instance
24
"""
25
26
def validate_token(self, token_info):
27
"""
28
Validate and refresh token if necessary.
29
30
Args:
31
token_info (dict): Token information dictionary
32
33
Returns:
34
dict: Valid token information or None if invalid
35
"""
36
37
def get_access_token(self, as_dict=True):
38
"""
39
Get access token for client credentials flow.
40
41
Args:
42
as_dict (bool): Return full token info dict if True, token string if False
43
44
Returns:
45
dict or str: Token information or token string
46
"""
47
```
48
49
### Authorization Code Flow
50
51
For user authentication with full access to user data and actions. Requires user consent.
52
53
```python { .api }
54
class SpotifyOAuth:
55
def __init__(self, client_id=None, client_secret=None, redirect_uri=None,
56
state=None, scope=None, cache_path=None, username=None,
57
proxies=None, requests_session=True, show_dialog=False,
58
requests_timeout=None, open_browser=True, cache_handler=None):
59
"""
60
Authorization Code flow for user authentication.
61
62
Args:
63
client_id (str, optional): Spotify client ID
64
client_secret (str, optional): Spotify client secret
65
redirect_uri (str, optional): Redirect URI registered with Spotify app
66
state (str, optional): State value for CSRF protection
67
scope (str or list, optional): Requested permission scopes
68
cache_path (str, optional): Path for token cache file (deprecated, use cache_handler)
69
username (str, optional): Username for cache file naming
70
proxies (dict, optional): Proxy configuration
71
requests_session (bool or requests.Session): HTTP session configuration
72
show_dialog (bool): Force consent dialog display (default: False)
73
requests_timeout (int, optional): Request timeout in seconds
74
open_browser (bool): Automatically open browser for authorization (default: True)
75
cache_handler (CacheHandler, optional): Token cache handler instance
76
"""
77
78
def validate_token(self, token_info):
79
"""
80
Validate token and refresh if necessary.
81
82
Args:
83
token_info (dict): Token information dictionary
84
85
Returns:
86
dict: Valid token information or None if invalid
87
"""
88
89
def get_access_token(self, code=None, as_dict=True, check_cache=True):
90
"""
91
Get access token using authorization code.
92
93
Args:
94
code (str, optional): Authorization code from callback
95
as_dict (bool): Return full token info dict if True, token string if False
96
check_cache (bool): Check cache for existing valid token
97
98
Returns:
99
dict or str: Token information or token string
100
"""
101
102
def refresh_access_token(self, refresh_token):
103
"""
104
Refresh access token using refresh token.
105
106
Args:
107
refresh_token (str): Refresh token from previous authorization
108
109
Returns:
110
dict: New token information
111
"""
112
113
def get_authorization_url(self):
114
"""
115
Get authorization URL for user consent.
116
117
Returns:
118
str: Authorization URL for user to visit
119
"""
120
121
def get_auth_response(self, open_browser=None):
122
"""
123
Get authorization response from user.
124
125
Args:
126
open_browser (bool, optional): Override open_browser setting
127
128
Returns:
129
str: Authorization code from user consent
130
"""
131
132
def parse_response_code(self, url):
133
"""
134
Parse authorization code from callback URL.
135
136
Args:
137
url (str): Callback URL containing authorization code
138
139
Returns:
140
str: Authorization code
141
"""
142
143
def parse_auth_response_url(self, url):
144
"""
145
Parse complete auth response from callback URL.
146
147
Args:
148
url (str): Callback URL from authorization
149
150
Returns:
151
str: Authorization code
152
"""
153
154
@property
155
def cache_handler(self):
156
"""Get current cache handler."""
157
158
@cache_handler.setter
159
def cache_handler(self, cache_handler):
160
"""Set cache handler."""
161
```
162
163
### PKCE Flow
164
165
Enhanced security flow using Proof Key for Code Exchange, recommended for mobile and single-page applications.
166
167
```python { .api }
168
class SpotifyPKCE:
169
def __init__(self, client_id=None, redirect_uri=None, state=None, scope=None,
170
cache_path=None, username=None, proxies=None, requests_session=True,
171
show_dialog=False, requests_timeout=None, open_browser=True,
172
cache_handler=None):
173
"""
174
PKCE flow for enhanced security authentication.
175
176
Args:
177
client_id (str, optional): Spotify client ID
178
redirect_uri (str, optional): Redirect URI registered with Spotify app
179
state (str, optional): State value for CSRF protection
180
scope (str or list, optional): Requested permission scopes
181
cache_path (str, optional): Path for token cache file (deprecated)
182
username (str, optional): Username for cache file naming
183
proxies (dict, optional): Proxy configuration
184
requests_session (bool or requests.Session): HTTP session configuration
185
show_dialog (bool): Force consent dialog display (default: False)
186
requests_timeout (int, optional): Request timeout in seconds
187
open_browser (bool): Automatically open browser for authorization (default: True)
188
cache_handler (CacheHandler, optional): Token cache handler instance
189
"""
190
191
def validate_token(self, token_info):
192
"""Validate token and refresh if necessary."""
193
194
def get_access_token(self, code=None, as_dict=True, check_cache=True):
195
"""Get access token using authorization code with PKCE."""
196
197
def refresh_access_token(self, refresh_token):
198
"""Refresh access token using refresh token."""
199
200
def get_authorization_url(self):
201
"""Get authorization URL with PKCE parameters."""
202
203
def get_auth_response(self, open_browser=None):
204
"""Get authorization response from user."""
205
206
def parse_response_code(self, url):
207
"""Parse authorization code from callback URL."""
208
209
def parse_auth_response_url(self, url):
210
"""Parse complete auth response from callback URL."""
211
```
212
213
### Implicit Grant Flow (Deprecated)
214
215
Legacy flow for client-side applications. Use PKCE flow instead for new applications.
216
217
```python { .api }
218
class SpotifyImplicitGrant:
219
def __init__(self, client_id=None, redirect_uri=None, state=None, scope=None,
220
cache_path=None, username=None, requests_session=True,
221
show_dialog=False, requests_timeout=None, cache_handler=None):
222
"""
223
Implicit Grant flow (deprecated - use PKCE instead).
224
225
Args:
226
client_id (str, optional): Spotify client ID
227
redirect_uri (str, optional): Redirect URI registered with Spotify app
228
state (str, optional): State value for CSRF protection
229
scope (str or list, optional): Requested permission scopes
230
cache_path (str, optional): Path for token cache file (deprecated)
231
username (str, optional): Username for cache file naming
232
requests_session (bool or requests.Session): HTTP session configuration
233
show_dialog (bool): Force consent dialog display (default: False)
234
requests_timeout (int, optional): Request timeout in seconds
235
cache_handler (CacheHandler, optional): Token cache handler instance
236
"""
237
238
def validate_token(self, token_info):
239
"""Validate token (no refresh available in implicit flow)."""
240
241
def get_access_token(self, response=None, as_dict=True, check_cache=True):
242
"""Get access token from implicit grant response."""
243
244
def get_authorization_url(self):
245
"""Get authorization URL for implicit grant."""
246
247
def get_auth_response(self):
248
"""Get authorization response from user."""
249
250
def parse_response_token(self, url):
251
"""Parse access token from callback URL fragment."""
252
```
253
254
## Usage Examples
255
256
### Client Credentials (App-Only)
257
258
```python
259
import spotipy
260
from spotipy.oauth2 import SpotifyClientCredentials
261
262
# Using environment variables SPOTIPY_CLIENT_ID and SPOTIPY_CLIENT_SECRET
263
client_credentials_manager = SpotifyClientCredentials()
264
265
# Or providing credentials explicitly
266
client_credentials_manager = SpotifyClientCredentials(
267
client_id="your_client_id",
268
client_secret="your_client_secret"
269
)
270
271
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
272
273
# Now you can access public Spotify data
274
results = sp.search(q='artist:radiohead', type='artist', limit=1)
275
artist = results['artists']['items'][0]
276
print(f"Artist: {artist['name']}")
277
print(f"Followers: {artist['followers']['total']}")
278
```
279
280
### Authorization Code Flow (User Authentication)
281
282
```python
283
import spotipy
284
from spotipy.oauth2 import SpotifyOAuth
285
286
# Define required scopes
287
scope = "user-read-private user-read-email user-library-read user-top-read"
288
289
# Initialize OAuth manager
290
auth_manager = SpotifyOAuth(
291
client_id="your_client_id",
292
client_secret="your_client_secret",
293
redirect_uri="http://localhost:8080/callback",
294
scope=scope,
295
show_dialog=True # Force consent dialog
296
)
297
298
sp = spotipy.Spotify(auth_manager=auth_manager)
299
300
# Access user's private data
301
user = sp.current_user()
302
print(f"User: {user['display_name']}")
303
print(f"Followers: {user['followers']['total']}")
304
305
# Get user's saved tracks
306
saved_tracks = sp.current_user_saved_tracks(limit=10)
307
print("\\nRecent saved tracks:")
308
for item in saved_tracks['items']:
309
track = item['track']
310
print(f" {track['name']} by {track['artists'][0]['name']}")
311
```
312
313
### PKCE Flow (Enhanced Security)
314
315
```python
316
import spotipy
317
from spotipy.oauth2 import SpotifyPKCE
318
319
scope = "user-read-private user-read-playback-state user-modify-playback-state"
320
321
auth_manager = SpotifyPKCE(
322
client_id="your_client_id",
323
redirect_uri="http://localhost:8080/callback",
324
scope=scope
325
)
326
327
sp = spotipy.Spotify(auth_manager=auth_manager)
328
329
# Control playback (requires premium account)
330
devices = sp.devices()
331
if devices['devices']:
332
device_id = devices['devices'][0]['id']
333
sp.start_playback(device_id=device_id)
334
print("Playback started!")
335
```
336
337
### Custom Cache Handler
338
339
```python
340
from spotipy.oauth2 import SpotifyOAuth
341
from spotipy.cache_handler import CacheFileHandler
342
343
# Custom cache location
344
cache_handler = CacheFileHandler(cache_path=".spotify_cache", username="myuser")
345
346
auth_manager = SpotifyOAuth(
347
client_id="your_client_id",
348
client_secret="your_client_secret",
349
redirect_uri="http://localhost:8080/callback",
350
scope="user-library-read",
351
cache_handler=cache_handler
352
)
353
354
sp = spotipy.Spotify(auth_manager=auth_manager)
355
```
356
357
### Manual Token Management
358
359
```python
360
from spotipy.oauth2 import SpotifyOAuth
361
362
auth_manager = SpotifyOAuth(
363
client_id="your_client_id",
364
client_secret="your_client_secret",
365
redirect_uri="http://localhost:8080/callback",
366
scope="user-library-read"
367
)
368
369
# Get authorization URL
370
auth_url = auth_manager.get_authorization_url()
371
print(f"Please visit: {auth_url}")
372
373
# Get authorization code from user
374
auth_code = input("Enter the authorization code: ")
375
376
# Exchange code for token
377
token_info = auth_manager.get_access_token(auth_code)
378
print(f"Access token: {token_info['access_token']}")
379
380
# Use token with Spotify client
381
sp = spotipy.Spotify(auth=token_info['access_token'])
382
```
383
384
## Available Scopes
385
386
Common OAuth scopes for different functionality:
387
388
- **User Profile**: `user-read-private`, `user-read-email`
389
- **Library**: `user-library-read`, `user-library-modify`
390
- **Playlists**: `playlist-read-private`, `playlist-read-collaborative`, `playlist-modify-private`, `playlist-modify-public`
391
- **Playback**: `user-read-playback-state`, `user-modify-playback-state`, `user-read-currently-playing`
392
- **Following**: `user-follow-read`, `user-follow-modify`
393
- **Top Content**: `user-top-read`
394
- **Recently Played**: `user-read-recently-played`
395
- **Streaming**: `streaming` (Web Playback SDK only)
396
- **Images**: `ugc-image-upload` (playlist cover images)
397
398
Combine scopes using spaces: `"user-read-private user-library-read playlist-modify-public"`
399
400
## Environment Variables
401
402
Set these environment variables to avoid hardcoding credentials:
403
404
```bash
405
export SPOTIPY_CLIENT_ID='your_client_id'
406
export SPOTIPY_CLIENT_SECRET='your_client_secret'
407
export SPOTIPY_REDIRECT_URI='http://localhost:8080/callback'
408
```
409
410
## Error Handling
411
412
Authentication errors are raised as `SpotifyOauthError` exceptions:
413
414
```python
415
from spotipy.exceptions import SpotifyOauthError
416
417
try:
418
sp = spotipy.Spotify(auth_manager=auth_manager)
419
user = sp.current_user()
420
except SpotifyOauthError as e:
421
print(f"OAuth Error: {e}")
422
print(f"Error: {e.error}")
423
print(f"Description: {e.error_description}")
424
```