spotifywebapiPython 1.0.85__py3-none-any.whl → 1.0.87__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of spotifywebapiPython might be problematic. Click here for more details.

Files changed (22) hide show
  1. {spotifywebapiPython-1.0.85.dist-info → spotifywebapiPython-1.0.87.dist-info}/METADATA +1 -1
  2. {spotifywebapiPython-1.0.85.dist-info → spotifywebapiPython-1.0.87.dist-info}/RECORD +22 -22
  3. spotifywebapipython/const.py +6 -1
  4. spotifywebapipython/docs/__init__.html +14 -2
  5. spotifywebapipython/docs/index.html +2 -2
  6. spotifywebapipython/docs/search.js +1 -1
  7. spotifywebapipython/docs/spotifywebapiPython/const.html +20 -3
  8. spotifywebapipython/docs/spotifywebapiPython/saappmessages.html +2 -2
  9. spotifywebapipython/docs/spotifywebapiPython/sautils.html +2 -2
  10. spotifywebapipython/docs/spotifywebapiPython/spotifyapierror.html +2 -2
  11. spotifywebapipython/docs/spotifywebapiPython/spotifyapimessage.html +2 -2
  12. spotifywebapipython/docs/spotifywebapiPython/spotifyauthtoken.html +2 -2
  13. spotifywebapipython/docs/spotifywebapiPython/spotifyclient.html +71 -4
  14. spotifywebapipython/docs/spotifywebapiPython/spotifydiscovery.html +2 -2
  15. spotifywebapipython/docs/spotifywebapiPython/spotifywebapiauthenticationerror.html +2 -2
  16. spotifywebapipython/docs/spotifywebapiPython/spotifywebapierror.html +2 -2
  17. spotifywebapipython/oauthcli/authclient.py +22 -5
  18. spotifywebapipython/spotifyclient.py +144 -6
  19. spotifywebapipython/zeroconfapi/zeroconfconnect.py +20 -1
  20. {spotifywebapiPython-1.0.85.dist-info → spotifywebapiPython-1.0.87.dist-info}/LICENSE +0 -0
  21. {spotifywebapiPython-1.0.85.dist-info → spotifywebapiPython-1.0.87.dist-info}/WHEEL +0 -0
  22. {spotifywebapiPython-1.0.85.dist-info → spotifywebapiPython-1.0.87.dist-info}/top_level.txt +0 -0
@@ -57,7 +57,8 @@ class AuthClient:
57
57
  tokenProviderId:str=None,
58
58
  tokenProfileId:str=None,
59
59
  tokenStorageDir:str=None,
60
- tokenUpdater:Callable=None
60
+ tokenStorageFile:str=None,
61
+ tokenUpdater:Callable=None,
61
62
  ) -> None:
62
63
  """
63
64
  Initializes a new instance of the class.
@@ -93,9 +94,12 @@ class AuthClient:
93
94
  A null value will default to `Shared`.
94
95
  Default: `Shared`
95
96
  tokenStorageDir (str):
96
- The directory path that will contain the `tokens.json` file.
97
+ The directory path that will contain the Token Cache file.
97
98
  A null value will default to the platform specific storage location:
98
99
  Example for Windows OS = `C:\ProgramData\SpotifyWebApiPython`
100
+ tokenStorageFile (str):
101
+ The filename and extension of the Token Cache file.
102
+ Default is `tokens.json`.
99
103
  tokenUpdater (Callable):
100
104
  A method to call when a token needs to be refreshed by an external provider.
101
105
  The defined method is called with no parameters, and should return a token dictionary.
@@ -110,6 +114,10 @@ class AuthClient:
110
114
  tokenStorageDir = platformdirs.site_config_dir('SpotifyWebApiPython', ensure_exists=True, appauthor=False)
111
115
  os.makedirs(tokenStorageDir, exist_ok=True) # succeeds even if directory exists.
112
116
 
117
+ # verify token storage filename was specified.
118
+ if tokenStorageFile is None:
119
+ tokenStorageFile = 'tokens.json'
120
+
113
121
  # if token providerId not set, then default to shared.
114
122
  if tokenProviderId is None:
115
123
  tokenProviderId = 'Shared'
@@ -128,7 +136,8 @@ class AuthClient:
128
136
  self._Session:OAuth2Session = oauth2Session
129
137
  self._TokenProviderId:str = tokenProviderId
130
138
  self._TokenStorageDir:str = tokenStorageDir
131
- self._TokenStoragePath:str = os.path.join(tokenStorageDir, 'tokens.json')
139
+ self._TokenStorageFile:str = tokenStorageFile
140
+ self._TokenStoragePath:str = os.path.join(tokenStorageDir, tokenStorageFile)
132
141
  self._TokenUpdater:Callable = tokenUpdater
133
142
  self._TokenUrl:str = tokenUrl
134
143
  self._TokenProfileId:str = tokenProfileId
@@ -383,9 +392,10 @@ class AuthClient:
383
392
  @staticmethod
384
393
  def HasTokenForKey(
385
394
  clientId:str=None,
395
+ tokenProviderId:str=None,
386
396
  tokenProfileId:str=None,
387
397
  tokenStorageDir:str=None,
388
- tokenProviderId:str=None,
398
+ tokenStorageFile:str=None,
389
399
  ) -> bool:
390
400
  """
391
401
  Checks if a token exists in the token storage file for the ProviderId \ ClientId key.
@@ -401,6 +411,9 @@ class AuthClient:
401
411
  The directory path that will contain the `tokens.json` file.
402
412
  A null value will default to the platform specific storage location:
403
413
  Example for Windows OS = `C:\ProgramData\SpotifyWebApiPython`
414
+ tokenStorageFile (str):
415
+ The filename and extension of the Token Cache file.
416
+ Default is `tokens.json`.
404
417
 
405
418
  Returns:
406
419
  True if the token was found in the token storage file for the
@@ -419,6 +432,10 @@ class AuthClient:
419
432
  if tokenStorageDir is None:
420
433
  tokenStorageDir = platformdirs.site_config_dir('SpotifyWebApiPython', ensure_exists=True, appauthor=False)
421
434
 
435
+ # verify token storage filename was specified.
436
+ if tokenStorageFile is None:
437
+ tokenStorageFile = 'tokens.json'
438
+
422
439
  # if token providerId not set, then default to shared.
423
440
  if tokenProviderId is None:
424
441
  tokenProviderId = 'Shared'
@@ -428,7 +445,7 @@ class AuthClient:
428
445
  tokenProfileId = 'Shared'
429
446
 
430
447
  # formulate token storage path.
431
- tokenStoragePath:str = os.path.join(tokenStorageDir, 'tokens.json')
448
+ tokenStoragePath:str = os.path.join(tokenStorageDir, tokenStorageFile)
432
449
 
433
450
  # formulate token storage key.
434
451
  tokenKey:str = f'{tokenProviderId}/{clientId}/{tokenProfileId}'
@@ -32,6 +32,7 @@ from .const import (
32
32
  SPOTIFY_DESKTOP_APP_CLIENT_ID,
33
33
  SPOTIFY_DEFAULT_MARKET,
34
34
  SPOTIFY_WEBAPI_URL_BASE,
35
+ SPOTIFYWEBAPIPYTHON_TOKEN_CACHE_FILE,
35
36
  TRACE_METHOD_RESULT,
36
37
  TRACE_METHOD_RESULT_TYPE,
37
38
  TRACE_METHOD_RESULT_TYPE_CACHED,
@@ -77,6 +78,7 @@ class SpotifyClient:
77
78
  def __init__(self,
78
79
  manager:PoolManager=None,
79
80
  tokenStorageDir:str=None,
81
+ tokenStorageFile:str=None,
80
82
  tokenUpdater:Callable=None,
81
83
  zeroconfClient:Zeroconf=None,
82
84
  spotifyConnectUsername:str=None,
@@ -91,9 +93,12 @@ class SpotifyClient:
91
93
  manager (urllib3.PoolManager):
92
94
  The manager for HTTP requests to the device.
93
95
  tokenStorageDir (str):
94
- The directory path that will contain the `tokens.json` file.
96
+ The directory path that will contain the authorization Token Cache file.
95
97
  A null value will default to the platform specific storage location:
96
98
  Example for Windows OS = `C:\ProgramData\SpotifyWebApiPython`
99
+ tokenStorageFile (str):
100
+ The filename and extension of the authorization Token Cache file.
101
+ Default is `SpotifyWebApiPython_tokens.json`.
97
102
  tokenUpdater (Callable):
98
103
  A method to call when a token needs to be refreshed by an external provider.
99
104
  The defined method is called with no parameters, and should return a token dictionary.
@@ -143,15 +148,22 @@ class SpotifyClient:
143
148
  if (spotifyConnectPassword is None) or (not isinstance(spotifyConnectPassword,str)):
144
149
  raise SpotifyApiError(SAAppMessages.ARGUMENT_REQUIRED_ERROR % ("__init__", 'spotifyConnectPassword'), logsi=_logsi)
145
150
 
151
+ # verify token storage filename was specified.
152
+ if tokenStorageFile is None:
153
+ tokenStorageFile = SPOTIFYWEBAPIPYTHON_TOKEN_CACHE_FILE
154
+
155
+ # initialize storage.
146
156
  self._AuthToken:SpotifyAuthToken = None
147
157
  self._AuthClient:AuthClient = None
148
158
  self._ConfigurationCache:dict = {}
159
+ self._DefaultDeviceId:str = None
149
160
  self._Manager:PoolManager = manager
150
161
  self._SpotifyConnectUsername:str = spotifyConnectUsername
151
162
  self._SpotifyConnectPassword:str = spotifyConnectPassword
152
163
  self._SpotifyConnectLoginId:str = spotifyConnectLoginId
153
164
  self._SpotifyConnectDiscoveryTimeout:float = float(spotifyConnectDiscoveryTimeout)
154
165
  self._TokenStorageDir:str = tokenStorageDir
166
+ self._TokenStorageFile:str = tokenStorageFile
155
167
  self._TokenUpdater:Callable = tokenUpdater
156
168
  self._UserProfile:UserProfile = None
157
169
  self._ZeroconfClient = zeroconfClient
@@ -262,6 +274,28 @@ class SpotifyClient:
262
274
  return None
263
275
 
264
276
 
277
+ @property
278
+ def DefaultDeviceId(self):
279
+ """
280
+ Default device id (or name) to use for player transport methods that do not specify a device id and
281
+ there is no active player detected (e.g. "Office", "5d4931f9d0684b625d702eaa24137b2c1d99539c", etc).
282
+
283
+ Set this value to null to use the Spotify player active device.
284
+ """
285
+ return self._DefaultDeviceId
286
+
287
+ @DefaultDeviceId.setter
288
+ def DefaultDeviceId(self, value:str):
289
+ """
290
+ Sets the DefaultDeviceId property value.
291
+ """
292
+ if (value is None) or (isinstance(value,str)):
293
+ if value.strip() == '':
294
+ self._DefaultDeviceId = None
295
+ else:
296
+ self._DefaultDeviceId = value
297
+
298
+
265
299
  @property
266
300
  def Manager(self) -> PoolManager:
267
301
  """
@@ -294,6 +328,14 @@ class SpotifyClient:
294
328
  return self._TokenStorageDir
295
329
 
296
330
 
331
+ @property
332
+ def TokenStorageFile(self) -> str:
333
+ """
334
+ The filename and extension of the authorization token cache file.
335
+ """
336
+ return self._TokenStorageFile
337
+
338
+
297
339
  @property
298
340
  def UserProfile(self) -> UserProfile:
299
341
  """
@@ -949,6 +991,10 @@ class SpotifyClient:
949
991
  apiMethodParms.AppendKeyValue("deviceId", deviceId)
950
992
  _logsi.LogMethodParmList(SILevel.Verbose, "Add item to playback queue", apiMethodParms)
951
993
 
994
+ # if deviceId was not specified, then verify that there is an active player device.
995
+ if deviceId is None:
996
+ deviceId:str = self.VerifyPlayerActiveDeviceId()
997
+
952
998
  # check for device name; convert to an id if a name was supplied.
953
999
  deviceId = self.PlayerConvertDeviceNameToId(deviceId)
954
1000
 
@@ -5963,6 +6009,56 @@ class SpotifyClient:
5963
6009
  _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
5964
6010
 
5965
6011
 
6012
+ def VerifyPlayerActiveDeviceId(self) -> str:
6013
+ """
6014
+ Verifies that there is an active Spotify player device id, and returns the `DefaultDeviceId`
6015
+ value if there is not; otherwise, a null is returned to indicate that the currently active
6016
+ Spotify player will be used.
6017
+
6018
+ Note that if there is no active player and there was no `DefaultDeviceId` defined, then
6019
+ subsequent calls to the Spotify Web API player endpoints will probably fail with a
6020
+ "No Active Device" exception.
6021
+
6022
+ Returns:
6023
+ A device id or null value.
6024
+ """
6025
+ apiMethodName:str = 'VerifyPlayerActiveDeviceId'
6026
+
6027
+ try:
6028
+
6029
+ # trace.
6030
+ _logsi.EnterMethod(SILevel.Debug, apiMethodName)
6031
+ _logsi.LogVerbose("Verifying active Spotify player device id")
6032
+
6033
+ # get current playback state.
6034
+ playState:PlayerPlayState = self.GetPlayerPlaybackState()
6035
+
6036
+ # is there an active device?
6037
+ if (playState.Device.Id is None):
6038
+
6039
+ # no - use the `DefaultDeviceId` property value so the Spotify Web API can
6040
+ # re-activate it prior to playing.
6041
+ if self._DefaultDeviceId is not None:
6042
+ _logsi.LogVerbose("Active Spotify player device was not found - using DefaultDeviceId value: '%s'" % self._DefaultDeviceId)
6043
+ return self._DefaultDeviceId
6044
+
6045
+ # otherwise return null, which will use the active Spotify player device for
6046
+ # subsequent calls to the Spotify Web API player endpoints.
6047
+ return None
6048
+
6049
+ except SpotifyWebApiError: raise # pass handled exceptions on thru
6050
+ except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
6051
+ except Exception as ex:
6052
+
6053
+ # format unhandled exception.
6054
+ raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
6055
+
6056
+ finally:
6057
+
6058
+ # trace.
6059
+ _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
6060
+
6061
+
5966
6062
  def GetPlayerDevice(self,
5967
6063
  deviceId:str,
5968
6064
  refresh:bool=True
@@ -6192,7 +6288,8 @@ class SpotifyClient:
6192
6288
  discoverResult.HostIpPort,
6193
6289
  discoverResult.SpotifyConnectCPath,
6194
6290
  useSSL=False,
6195
- tokenStorageDir=self.TokenStorageDir)
6291
+ tokenStorageDir=self.TokenStorageDir,
6292
+ tokenStorageFile=self.TokenStorageFile)
6196
6293
 
6197
6294
  # if a different user context has control of the device then we need to disconnect
6198
6295
  # the current user context before connecting a different user.
@@ -8252,7 +8349,8 @@ class SpotifyClient:
8252
8349
  discoverResult.HostIpPort,
8253
8350
  discoverResult.SpotifyConnectCPath,
8254
8351
  useSSL=False,
8255
- tokenStorageDir=self.TokenStorageDir)
8352
+ tokenStorageDir=self.TokenStorageDir,
8353
+ tokenStorageFile=self.TokenStorageFile)
8256
8354
 
8257
8355
  # if we did not refresh the device list, then query the device for real-time status; just in
8258
8356
  # case the device was disconnected after the last cache refresh. note that we only do this
@@ -8270,9 +8368,10 @@ class SpotifyClient:
8270
8368
  # check if the Spotify Desktop Application Client oauth2 token is defined.
8271
8369
  hasToken:bool = AuthClient.HasTokenForKey(
8272
8370
  clientId=SPOTIFY_DESKTOP_APP_CLIENT_ID,
8273
- tokenStorageDir=self.TokenStorageDir,
8274
8371
  tokenProviderId='SpotifyWebApiAuthCodePkce',
8275
8372
  tokenProfileId=self._SpotifyConnectLoginId,
8373
+ tokenStorageDir=self.TokenStorageDir,
8374
+ tokenStorageFile=self.TokenStorageFile,
8276
8375
  )
8277
8376
 
8278
8377
  if not hasToken:
@@ -8501,7 +8600,8 @@ class SpotifyClient:
8501
8600
  discoverResult.HostIpPort,
8502
8601
  discoverResult.SpotifyConnectCPath,
8503
8602
  useSSL=False,
8504
- tokenStorageDir=self.TokenStorageDir)
8603
+ tokenStorageDir=self.TokenStorageDir,
8604
+ tokenStorageFile=self.TokenStorageFile)
8505
8605
  info = zconn.GetInformation()
8506
8606
 
8507
8607
  except Exception as ex:
@@ -8516,7 +8616,8 @@ class SpotifyClient:
8516
8616
  discoverResult.HostIpPort,
8517
8617
  discoverResult.SpotifyConnectCPath,
8518
8618
  useSSL=False,
8519
- tokenStorageDir=self.TokenStorageDir)
8619
+ tokenStorageDir=self.TokenStorageDir,
8620
+ tokenStorageFile=self.TokenStorageFile)
8520
8621
  info = zconn.GetInformation()
8521
8622
 
8522
8623
  # update HostIpAddress in discovery result so it knows to use the alias
@@ -10071,6 +10172,10 @@ class SpotifyClient:
10071
10172
  # validations.
10072
10173
  delay = validateDelay(delay, 0.50, 10)
10073
10174
 
10175
+ # if deviceId was not specified, then verify that there is an active player device.
10176
+ if deviceId is None:
10177
+ deviceId:str = self.VerifyPlayerActiveDeviceId()
10178
+
10074
10179
  # check for device name; convert to an id if a name was supplied.
10075
10180
  deviceId = self.PlayerConvertDeviceNameToId(deviceId)
10076
10181
 
@@ -10593,6 +10698,10 @@ class SpotifyClient:
10593
10698
  # validations.
10594
10699
  delay = validateDelay(delay, 0.50, 10)
10595
10700
 
10701
+ # if deviceId was not specified, then verify that there is an active player device.
10702
+ if deviceId is None:
10703
+ deviceId:str = self.VerifyPlayerActiveDeviceId()
10704
+
10596
10705
  # check for device name; convert to an id if a name was supplied.
10597
10706
  deviceId = self.PlayerConvertDeviceNameToId(deviceId)
10598
10707
 
@@ -10690,6 +10799,10 @@ class SpotifyClient:
10690
10799
  # validations.
10691
10800
  delay = validateDelay(delay, 0.50, 10)
10692
10801
 
10802
+ # if deviceId was not specified, then verify that there is an active player device.
10803
+ if deviceId is None:
10804
+ deviceId:str = self.VerifyPlayerActiveDeviceId()
10805
+
10693
10806
  # check for device name; convert to an id if a name was supplied.
10694
10807
  deviceId = self.PlayerConvertDeviceNameToId(deviceId)
10695
10808
 
@@ -10782,6 +10895,10 @@ class SpotifyClient:
10782
10895
  # validations.
10783
10896
  delay = validateDelay(delay, 0.50, 10)
10784
10897
 
10898
+ # if deviceId was not specified, then verify that there is an active player device.
10899
+ if deviceId is None:
10900
+ deviceId:str = self.VerifyPlayerActiveDeviceId()
10901
+
10785
10902
  # check for device name; convert to an id if a name was supplied.
10786
10903
  deviceId = self.PlayerConvertDeviceNameToId(deviceId)
10787
10904
 
@@ -10871,6 +10988,10 @@ class SpotifyClient:
10871
10988
  # validations.
10872
10989
  delay = validateDelay(delay, 0.50, 10)
10873
10990
 
10991
+ # if deviceId was not specified, then verify that there is an active player device.
10992
+ if deviceId is None:
10993
+ deviceId:str = self.VerifyPlayerActiveDeviceId()
10994
+
10874
10995
  # check for device name; convert to an id if a name was supplied.
10875
10996
  deviceId = self.PlayerConvertDeviceNameToId(deviceId)
10876
10997
 
@@ -11082,6 +11203,10 @@ class SpotifyClient:
11082
11203
  # validations.
11083
11204
  delay = validateDelay(delay, 0.50, 10)
11084
11205
 
11206
+ # if deviceId was not specified, then verify that there is an active player device.
11207
+ if deviceId is None:
11208
+ deviceId:str = self.VerifyPlayerActiveDeviceId()
11209
+
11085
11210
  # check for device name; convert to an id if a name was supplied.
11086
11211
  deviceId = self.PlayerConvertDeviceNameToId(deviceId)
11087
11212
 
@@ -11181,6 +11306,10 @@ class SpotifyClient:
11181
11306
  # validations.
11182
11307
  delay = validateDelay(delay, 0.50, 10)
11183
11308
 
11309
+ # if deviceId was not specified, then verify that there is an active player device.
11310
+ if deviceId is None:
11311
+ deviceId:str = self.VerifyPlayerActiveDeviceId()
11312
+
11184
11313
  # check for device name; convert to an id if a name was supplied.
11185
11314
  deviceId = self.PlayerConvertDeviceNameToId(deviceId)
11186
11315
 
@@ -11279,6 +11408,10 @@ class SpotifyClient:
11279
11408
  # validations.
11280
11409
  delay = validateDelay(delay, 0.50, 10)
11281
11410
 
11411
+ # if deviceId was not specified, then verify that there is an active player device.
11412
+ if deviceId is None:
11413
+ deviceId:str = self.VerifyPlayerActiveDeviceId()
11414
+
11282
11415
  # check for device name; convert to an id if a name was supplied.
11283
11416
  deviceId = self.PlayerConvertDeviceNameToId(deviceId)
11284
11417
 
@@ -14438,6 +14571,7 @@ class SpotifyClient:
14438
14571
  clientSecret=clientSecret,
14439
14572
  oauth2Client=WebApplicationClient(client_id=clientId), # required for grant_type = authorization_code
14440
14573
  tokenStorageDir=self._TokenStorageDir,
14574
+ tokenStorageFile=self._TokenStorageFile,
14441
14575
  tokenProviderId='SpotifyWebApiAuthCode',
14442
14576
  tokenProfileId=tokenProfileId,
14443
14577
  tokenUpdater=self._TokenUpdater
@@ -14620,6 +14754,7 @@ class SpotifyClient:
14620
14754
  clientSecret=None, # client_secret not used for authorization code with pkce type
14621
14755
  oauth2Client=WebApplicationClient(client_id=clientId), # required for grant_type = authorization_code
14622
14756
  tokenStorageDir=self._TokenStorageDir,
14757
+ tokenStorageFile=self._TokenStorageFile,
14623
14758
  tokenProviderId='SpotifyWebApiAuthCodePkce',
14624
14759
  tokenProfileId=tokenProfileId,
14625
14760
  tokenUpdater=self._TokenUpdater
@@ -14737,6 +14872,7 @@ class SpotifyClient:
14737
14872
  clientSecret=clientSecret,
14738
14873
  oauth2Client=BackendApplicationClient(client_id=clientId), # required for grant_type = client_credentials
14739
14874
  tokenStorageDir=self._TokenStorageDir,
14875
+ tokenStorageFile=self._TokenStorageFile,
14740
14876
  tokenProviderId='SpotifyWebApiClientCredentials',
14741
14877
  tokenProfileId=tokenProfileId,
14742
14878
  tokenUpdater=self._TokenUpdater
@@ -14835,6 +14971,7 @@ class SpotifyClient:
14835
14971
  scope=token.get('scope'),
14836
14972
  clientId=clientId,
14837
14973
  tokenStorageDir=self._TokenStorageDir,
14974
+ tokenStorageFile=self._TokenStorageFile,
14838
14975
  tokenProviderId='SpotifyWebApiOAuth2Token',
14839
14976
  tokenProfileId=tokenProfileId,
14840
14977
  tokenUpdater=self._TokenUpdater
@@ -14894,6 +15031,7 @@ class SpotifyClient:
14894
15031
  msg:str = 'SpotifyClient:'
14895
15032
  msg = "%s\n ConfigurationCache key count=%d" % (msg, len(self._ConfigurationCache))
14896
15033
  msg = "%s\n TokenStorageDir='%s'" % (msg, self._TokenStorageDir)
15034
+ msg = "%s\n TokenStorageFile='%s'" % (msg, self._TokenStorageFile)
14897
15035
  if self._UserProfile is not None:
14898
15036
  msg = "%s\n User DisplayName='%s' (%s)" % (msg, self._UserProfile.DisplayName, self._UserProfile.Id)
14899
15037
  return msg
@@ -21,6 +21,7 @@ from ..const import (
21
21
  SPOTIFY_API_AUTHORIZE_URL,
22
22
  SPOTIFY_API_TOKEN_URL,
23
23
  SPOTIFY_DESKTOP_APP_CLIENT_ID,
24
+ SPOTIFYWEBAPIPYTHON_TOKEN_CACHE_FILE,
24
25
  TRACE_METHOD_RESULT,
25
26
  TRACE_MSG_DELAY_DEVICE,
26
27
  )
@@ -61,6 +62,7 @@ class ZeroconfConnect:
61
62
  version:str=None,
62
63
  useSSL:bool=False,
63
64
  tokenStorageDir:str=None,
65
+ tokenStorageFile:str=None,
64
66
  tokenAuthInBrowser:bool=False,
65
67
  ) -> None:
66
68
  """
@@ -83,10 +85,13 @@ class ZeroconfConnect:
83
85
  otherwise, False to utilize HTTP.
84
86
  Default is False (HTTP).
85
87
  tokenStorageDir (str):
86
- The directory path that will contain the `tokens.json` cache file.
88
+ The directory path that will contain the Token Cache file.
87
89
  This is used for Spotify Connect devices that utilize the `authorization_code` token type.
88
90
  A null value will default to the platform specific storage location:
89
91
  Example for Windows OS = `C:\ProgramData\SpotifyWebApiPython`
92
+ tokenStorageFile (str):
93
+ The filename and extension of the Token Cache file.
94
+ Default is `SpotifyWebApiPython_tokens.json`.
90
95
  tokenAuthInBrowser (bool):
91
96
  True to allow authorization access token to be authorized if necessary via an
92
97
  interactive browser; otherwise, False.
@@ -103,11 +108,16 @@ class ZeroconfConnect:
103
108
  if (version is None) or (not isinstance(version,str)):
104
109
  version = ZeroconfConnect.SPOTIFY_CONNECT_CLIENT_VERSION_DEFAULT
105
110
 
111
+ # verify token storage filename was specified.
112
+ if tokenStorageFile is None:
113
+ tokenStorageFile = SPOTIFYWEBAPIPYTHON_TOKEN_CACHE_FILE
114
+
106
115
  # initialize storage.
107
116
  self._CPath:str = cpath
108
117
  self._HostIpPort:int = hostIpPort
109
118
  self._HostIpAddress:str = hostIpAddress
110
119
  self._TokenStorageDir:str = tokenStorageDir
120
+ self._TokenStorageFile:str = tokenStorageFile
111
121
  self._TokenAuthInBrowser:str = tokenAuthInBrowser
112
122
  self._UseSSL:bool = useSSL
113
123
  self._Version:str = version
@@ -159,6 +169,14 @@ class ZeroconfConnect:
159
169
  return self._TokenStorageDir
160
170
 
161
171
 
172
+ @property
173
+ def TokenStorageFile(self) -> str:
174
+ """
175
+ The filename and extension of the authorization token cache file.
176
+ """
177
+ return self._TokenStorageFile
178
+
179
+
162
180
  @property
163
181
  def Uri(self) -> str:
164
182
  """
@@ -677,6 +695,7 @@ class ZeroconfConnect:
677
695
  scope=SPOTIFY_SCOPES,
678
696
  clientId=SPOTIFY_DESKTOP_APP_CLIENT_ID,
679
697
  tokenStorageDir=self.TokenStorageDir,
698
+ tokenStorageFile=self.TokenStorageFile,
680
699
  tokenProviderId='SpotifyWebApiAuthCodePkce',
681
700
  tokenProfileId=loginId,
682
701
  )