spotifywebapiPython 1.0.122__py3-none-any.whl → 1.0.124__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 (21) hide show
  1. {spotifywebapiPython-1.0.122.dist-info → spotifywebapiPython-1.0.124.dist-info}/METADATA +1 -1
  2. {spotifywebapiPython-1.0.122.dist-info → spotifywebapiPython-1.0.124.dist-info}/RECORD +21 -21
  3. spotifywebapipython/const.py +1 -1
  4. spotifywebapipython/docs/__init__.html +15 -2
  5. spotifywebapipython/docs/index.html +2 -2
  6. spotifywebapipython/docs/search.js +1 -1
  7. spotifywebapipython/docs/spotifywebapipython/const.html +3 -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 +6 -5
  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/spotifyclient.py +135 -32
  18. spotifywebapipython/zeroconfapi/zeroconfresponse.py +1 -1
  19. {spotifywebapiPython-1.0.122.dist-info → spotifywebapiPython-1.0.124.dist-info}/LICENSE +0 -0
  20. {spotifywebapiPython-1.0.122.dist-info → spotifywebapiPython-1.0.124.dist-info}/WHEEL +0 -0
  21. {spotifywebapiPython-1.0.122.dist-info → spotifywebapiPython-1.0.124.dist-info}/top_level.txt +0 -0
@@ -2333,7 +2333,13 @@ class SpotifyClient:
2333
2333
  apiMethodParms.AppendKeyValue("collaborative", collaborative)
2334
2334
  apiMethodParms.AppendKeyValue("imagePath", imagePath)
2335
2335
  _logsi.LogMethodParmList(SILevel.Verbose, "Create an empty playlist for a user", apiMethodParms)
2336
-
2336
+
2337
+ # validations.
2338
+ if (public is None):
2339
+ public = True
2340
+ if (collaborative is None):
2341
+ collaborative = False
2342
+
2337
2343
  # if userId is not supplied, then use profile value.
2338
2344
  if userId is None or len(userId.strip()) == 0:
2339
2345
  userId = self.UserProfile.Id
@@ -2489,7 +2495,7 @@ class SpotifyClient:
2489
2495
  public (bool):
2490
2496
  If true the playlist will be included in user's public playlists, if false it
2491
2497
  will remain private.
2492
- Default = True.
2498
+ Default is True.
2493
2499
 
2494
2500
  Raises:
2495
2501
  SpotifyWebApiError:
@@ -2515,6 +2521,10 @@ class SpotifyClient:
2515
2521
  apiMethodParms.AppendKeyValue("playlistId", playlistId)
2516
2522
  apiMethodParms.AppendKeyValue("public", public)
2517
2523
  _logsi.LogMethodParmList(SILevel.Verbose, "Add the current user as a follower of a playlist", apiMethodParms)
2524
+
2525
+ # validations.
2526
+ if (public is None):
2527
+ public = True
2518
2528
 
2519
2529
  # if playlistId not specified, then return currently playing playlist id value.
2520
2530
  if (playlistId is None) or (len(playlistId.strip()) == 0):
@@ -2863,10 +2873,12 @@ class SpotifyClient:
2863
2873
  # append page of items to final results.
2864
2874
  item:AlbumSaved
2865
2875
  for item in pageObj.Items:
2866
- result.Items.append(item)
2867
- result.Limit = result.ItemsCount
2868
- if result.ItemsCount >= limitTotal:
2869
- break
2876
+ # sometimes spotify api returns items with no information; discard these!
2877
+ if (item.Album is not None) and (item.Album.Uri is not None):
2878
+ result.Items.append(item)
2879
+ result.Limit = result.ItemsCount
2880
+ if result.ItemsCount >= limitTotal:
2881
+ break
2870
2882
 
2871
2883
  # anymore pages to process? if not, then exit the loop.
2872
2884
  if not self._CheckForNextPageWithOffset(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
@@ -4996,6 +5008,10 @@ class SpotifyClient:
4996
5008
  apiMethodParms.AppendKeyValue("locale", locale)
4997
5009
  _logsi.LogMethodParmList(SILevel.Verbose, "Get a single category used to tag items in Spotify", apiMethodParms)
4998
5010
 
5011
+ # validations.
5012
+ if (refresh is None):
5013
+ refresh = True
5014
+
4999
5015
  # can we use a cached value?
5000
5016
  cacheKey:str = "GetBrowseCategorys"
5001
5017
  if (not refresh) and (cacheKey in self._ConfigurationCache):
@@ -5287,6 +5303,10 @@ class SpotifyClient:
5287
5303
  apiMethodParms.AppendKeyValue("refresh", refresh)
5288
5304
  _logsi.LogMethodParmList(SILevel.Verbose, "Get a sorted list of ALL browse categories", apiMethodParms)
5289
5305
 
5306
+ # validations.
5307
+ if (refresh is None):
5308
+ refresh = True
5309
+
5290
5310
  # can we use the cached value?
5291
5311
  if (not refresh) and (apiMethodName in self._ConfigurationCache):
5292
5312
 
@@ -5584,6 +5604,10 @@ class SpotifyClient:
5584
5604
  apiMethodParms.AppendKeyValue("ignoreResponseErrors", ignoreResponseErrors)
5585
5605
  _logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for a single audiobook chapter", apiMethodParms)
5586
5606
 
5607
+ # validations.
5608
+ if (ignoreResponseErrors is None):
5609
+ ignoreResponseErrors = False
5610
+
5587
5611
  # ensure market was either supplied or implied; default if neither.
5588
5612
  market = self._ValidateMarket(market)
5589
5613
 
@@ -5946,10 +5970,12 @@ class SpotifyClient:
5946
5970
  # append page of items to final results.
5947
5971
  item:EpisodeSaved
5948
5972
  for item in pageObj.Items:
5949
- result.Items.append(item)
5950
- result.Limit = result.ItemsCount
5951
- if result.ItemsCount >= limitTotal:
5952
- break
5973
+ # sometimes spotify api returns items with no information; discard these!
5974
+ if (item.Episode is not None) and (item.Episode.Uri is not None):
5975
+ result.Items.append(item)
5976
+ result.Limit = result.ItemsCount
5977
+ if result.ItemsCount >= limitTotal:
5978
+ break
5953
5979
 
5954
5980
  # anymore pages to process? if not, then exit the loop.
5955
5981
  if not self._CheckForNextPageWithOffset(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
@@ -6337,6 +6363,10 @@ class SpotifyClient:
6337
6363
  # api endpoint no longer supported by Spotify as of 2024/11/27.
6338
6364
  raise SpotifyApiError(SAAppMessages.MSG_SPOTIFY_DEPRECATED_ENDPOINT % apiMethodName)
6339
6365
 
6366
+ # validations.
6367
+ if (refresh is None):
6368
+ refresh = True
6369
+
6340
6370
  # can we use the cached value?
6341
6371
  if (not refresh) and (apiMethodName in self._ConfigurationCache):
6342
6372
 
@@ -6456,6 +6486,10 @@ class SpotifyClient:
6456
6486
  _logsi.EnterMethod(SILevel.Debug, apiMethodName)
6457
6487
  _logsi.LogVerbose("Get a sorted list of available markets (country codes)")
6458
6488
 
6489
+ # validations.
6490
+ if (refresh is None):
6491
+ refresh = True
6492
+
6459
6493
  # can we use the cached value?
6460
6494
  if (not refresh) and (apiMethodName in self._ConfigurationCache):
6461
6495
 
@@ -6596,6 +6630,8 @@ class SpotifyClient:
6596
6630
  _logsi.LogMethodParmList(SILevel.Verbose, "Get user's available Spotify Connect player device", apiMethodParms)
6597
6631
 
6598
6632
  # validations.
6633
+ if (refresh is None):
6634
+ refresh = True
6599
6635
  if deviceId is None:
6600
6636
  return None
6601
6637
  deviceId = deviceId.lower() # prepare for compare
@@ -6873,6 +6909,10 @@ class SpotifyClient:
6873
6909
  apiMethodParms.AppendKeyValue("refresh", refresh)
6874
6910
  _logsi.LogMethodParmList(SILevel.Verbose, "Checking Spotify Connect Player device for name", apiMethodParms)
6875
6911
 
6912
+ # validations.
6913
+ if (refresh is None):
6914
+ refresh = False
6915
+
6876
6916
  # if nothing specified then just use it as-is.
6877
6917
  if (value is None) or (len(value.strip()) == 0):
6878
6918
  _logsi.LogVerbose("Device ID not specified; active device will be used")
@@ -6982,6 +7022,8 @@ class SpotifyClient:
6982
7022
  _logsi.LogMethodParmList(SILevel.Verbose, "Get user's available Spotify Connect player devices", apiMethodParms)
6983
7023
 
6984
7024
  # validations.
7025
+ if (refresh is None):
7026
+ refresh = True
6985
7027
  if sortResult is None:
6986
7028
  sortResult = True
6987
7029
 
@@ -7220,6 +7262,10 @@ class SpotifyClient:
7220
7262
  """
7221
7263
  result:str = None
7222
7264
 
7265
+ # validations.
7266
+ if (ignoreResponseErrors is None):
7267
+ ignoreResponseErrors = False
7268
+
7223
7269
  # get nowplaying status.
7224
7270
  nowPlaying:PlayerPlayState = self.GetPlayerNowPlaying(market, additionalTypes='episode')
7225
7271
 
@@ -8864,10 +8910,12 @@ class SpotifyClient:
8864
8910
  # append page of items to final results.
8865
8911
  item:ShowSaved
8866
8912
  for item in pageObj.Items:
8867
- result.Items.append(item)
8868
- result.Limit = result.ItemsCount
8869
- if result.ItemsCount >= limitTotal:
8870
- break
8913
+ # sometimes spotify api returns items with no information; discard these!
8914
+ if (item.Show is not None) and (item.Show.Uri is not None):
8915
+ result.Items.append(item)
8916
+ result.Limit = result.ItemsCount
8917
+ if result.ItemsCount >= limitTotal:
8918
+ break
8871
8919
 
8872
8920
  # anymore pages to process? if not, then exit the loop.
8873
8921
  if not self._CheckForNextPageWithOffset(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
@@ -9046,7 +9094,8 @@ class SpotifyClient:
9046
9094
  Default is 5; value range is 0 - 10.
9047
9095
  refreshDeviceList (bool):
9048
9096
  True to refresh the Spotify Connect device list; otherwise, False to use the
9049
- Spotify Connect device list cache.
9097
+ Spotify Connect device list cache.
9098
+ Default is False.
9050
9099
  activateDevice (bool):
9051
9100
  True to activate the device if necessary; otherwise, False.
9052
9101
  Default is True.
@@ -9098,6 +9147,8 @@ class SpotifyClient:
9098
9147
  apiMethodParms:SIMethodParmListContext = None
9099
9148
  deviceResultId:str = None
9100
9149
  deviceResult:SpotifyConnectDevice = None
9150
+
9151
+ DELAY_DISCONNECT:float = 0.350
9101
9152
 
9102
9153
  try:
9103
9154
 
@@ -9126,6 +9177,10 @@ class SpotifyClient:
9126
9177
  verifyTimeout = validateDelay(verifyTimeout, 5, 10)
9127
9178
  if (not isinstance(verifyUserContext, bool)):
9128
9179
  verifyUserContext = True
9180
+ if (activateDevice is None):
9181
+ activateDevice = True
9182
+ if (refreshDeviceList is None):
9183
+ refreshDeviceList = False
9129
9184
 
9130
9185
  # determine if the device value specified is a name (e.g. "Bose-ST10-1") or
9131
9186
  # an id (e.g. "30fbc80e35598f3c242f2120413c943dfd9715fe", "48b677ca-ef9b-516f-b702-93bf2e8c67ba").
@@ -9139,6 +9194,12 @@ class SpotifyClient:
9139
9194
 
9140
9195
  # get all available Spotify Connect devices on the network.
9141
9196
  scDevices:SpotifyConnectDevices = self.GetSpotifyConnectDevices(refresh=refreshDeviceList)
9197
+
9198
+ # if we refreshed the device list, then give the device(s) a little time to disconnect so that
9199
+ # a new connection can be established (if required).
9200
+ if (refreshDeviceList):
9201
+ _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE % DELAY_DISCONNECT)
9202
+ time.sleep(DELAY_DISCONNECT)
9142
9203
 
9143
9204
  # process all discovered devices.
9144
9205
  for scDevice in scDevices:
@@ -9239,7 +9300,17 @@ class SpotifyClient:
9239
9300
  if (not activateDevice):
9240
9301
  _logsi.LogVerbose("Activation not requested for Spotify Connect device: '%s'" % (deviceResult.Title))
9241
9302
  break
9242
-
9303
+
9304
+ # does the device need to be activated?
9305
+ # check for the device in the available device list.
9306
+ # if we find it, then there is no need to activate it and we are done.
9307
+ # note - if another user is controlling the device, then it will not be in the active device list
9308
+ # for the current user!
9309
+ device:Device = self.GetPlayerDevice(deviceResultId, refresh=True)
9310
+ if device is not None:
9311
+ _logsi.LogVerbose("Spotify Connect device '%s' is already in the available device list; no need to re-activate" % (deviceResult.Title))
9312
+ break
9313
+
9243
9314
  zcfResult:ZeroconfResponse
9244
9315
 
9245
9316
  # disconnect the device.
@@ -9255,7 +9326,8 @@ class SpotifyClient:
9255
9326
  # some devices only support a single connection on the spotify connect
9256
9327
  # zeroconf webserver, so we have to give it a little time to process the
9257
9328
  # disconnect command before we try to call the Connect method.
9258
- time.sleep(0.350)
9329
+ _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE % DELAY_DISCONNECT)
9330
+ time.sleep(DELAY_DISCONNECT)
9259
9331
 
9260
9332
  # connect the device to OUR Spotify Connect user context.
9261
9333
  # note that the result here only indicates that the connect was submitted - NOT that it was successful!
@@ -9396,6 +9468,8 @@ class SpotifyClient:
9396
9468
  _logsi.LogMethodParmList(SILevel.Verbose, "Get available Spotify Connect devices", apiMethodParms)
9397
9469
 
9398
9470
  # validations.
9471
+ if refresh is None:
9472
+ refresh = True
9399
9473
  if sortResult is None:
9400
9474
  sortResult = True
9401
9475
 
@@ -9865,10 +9939,12 @@ class SpotifyClient:
9865
9939
  # append page of items to final results.
9866
9940
  item:TrackSaved
9867
9941
  for item in pageObj.Items:
9868
- result.Items.append(item)
9869
- result.Limit = result.ItemsCount
9870
- if result.ItemsCount >= limitTotal:
9871
- break
9942
+ # sometimes spotify api returns items with no information; discard these!
9943
+ if (item.Track is not None) and (item.Track.Uri is not None):
9944
+ result.Items.append(item)
9945
+ result.Limit = result.ItemsCount
9946
+ if result.ItemsCount >= limitTotal:
9947
+ break
9872
9948
 
9873
9949
  # anymore pages to process? if not, then exit the loop.
9874
9950
  if not self._CheckForNextPageWithOffset(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
@@ -10571,6 +10647,10 @@ class SpotifyClient:
10571
10647
  apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
10572
10648
  _logsi.LogMethodParmList(SILevel.Verbose, "Get profile information about the current user", apiMethodParms)
10573
10649
 
10650
+ # validations.
10651
+ if (refresh is None):
10652
+ refresh = True
10653
+
10574
10654
  # can we use the cached value?
10575
10655
  if (not refresh) and (apiMethodName in self._ConfigurationCache):
10576
10656
 
@@ -11328,12 +11408,13 @@ class SpotifyClient:
11328
11408
 
11329
11409
  # validations.
11330
11410
  delay = validateDelay(delay, 0.50, 10)
11411
+ if (resolveDeviceId is None):
11412
+ resolveDeviceId = True
11331
11413
 
11332
11414
  # has the device id been resolved?
11333
11415
  if (resolveDeviceId):
11334
11416
 
11335
- # no - ensure the specified device id / name is active and available, and
11336
- # the user context is set correctly.
11417
+ # no - ensure the specified device id / name is active and available.
11337
11418
  scDevice = self.GetSpotifyConnectDevice(
11338
11419
  deviceId,
11339
11420
  refreshDeviceList=False,
@@ -11457,6 +11538,10 @@ class SpotifyClient:
11457
11538
 
11458
11539
  # validations.
11459
11540
  delay = validateDelay(delay, 0.50, 10)
11541
+ if (shuffle is None):
11542
+ shuffle = True
11543
+ if (resolveDeviceId is None):
11544
+ resolveDeviceId = True
11460
11545
 
11461
11546
  # get current users favorite tracks.
11462
11547
  tracks:TrackPageSaved = self.GetTrackFavorites(limitTotal=limitTotal)
@@ -11473,8 +11558,7 @@ class SpotifyClient:
11473
11558
  # has the device id been resolved?
11474
11559
  if (resolveDeviceId):
11475
11560
 
11476
- # no - ensure the specified device id / name is active and available, and
11477
- # the user context is set correctly.
11561
+ # no - ensure the specified device id / name is active and available.
11478
11562
  scDevice = self.GetSpotifyConnectDevice(
11479
11563
  deviceId,
11480
11564
  refreshDeviceList=False,
@@ -11586,6 +11670,8 @@ class SpotifyClient:
11586
11670
 
11587
11671
  # validations.
11588
11672
  delay = validateDelay(delay, 0.50, 10)
11673
+ if (resolveDeviceId is None):
11674
+ resolveDeviceId = True
11589
11675
 
11590
11676
  # build a list of all item uri's.
11591
11677
  # remove any leading / trailing spaces in case user put a space between the items.
@@ -11600,8 +11686,7 @@ class SpotifyClient:
11600
11686
  # has the device id been resolved?
11601
11687
  if (resolveDeviceId):
11602
11688
 
11603
- # no - ensure the specified device id / name is active and available, and
11604
- # the user context is set correctly.
11689
+ # no - ensure the specified device id / name is active and available.
11605
11690
  scDevice = self.GetSpotifyConnectDevice(
11606
11691
  deviceId,
11607
11692
  refreshDeviceList=False,
@@ -12335,7 +12420,7 @@ class SpotifyClient:
12335
12420
  The shuffle mode to set:
12336
12421
  - `True` - Shuffle user's playback.
12337
12422
  - `False` - Do not shuffle user's playback.
12338
- Default: `False`
12423
+ Default is False
12339
12424
  deviceId (str):
12340
12425
  The id or name of the device this command is targeting.
12341
12426
  If not supplied, the user's currently active device is the target.
@@ -12600,9 +12685,14 @@ class SpotifyClient:
12600
12685
 
12601
12686
  # validations.
12602
12687
  delay = validateDelay(delay, 0.50, 10)
12603
-
12604
- # ensure the specified device id / name is active and available, and
12605
- # the user context is set correctly.
12688
+ if (play is None):
12689
+ play = True
12690
+ if (refreshDeviceList is None):
12691
+ refreshDeviceList = True
12692
+ if (forceActivateDevice is None):
12693
+ forceActivateDevice = True
12694
+
12695
+ # ensure the specified device id / name is active and available.
12606
12696
  scDevice = self.GetSpotifyConnectDevice(
12607
12697
  deviceId,
12608
12698
  refreshDeviceList=refreshDeviceList,
@@ -12627,7 +12717,7 @@ class SpotifyClient:
12627
12717
  {
12628
12718
  'device_ids': [deviceId]
12629
12719
  }
12630
- if play is not None:
12720
+ if (play is not None):
12631
12721
  reqData['play'] = play
12632
12722
 
12633
12723
  # execute spotify web api request.
@@ -12640,6 +12730,13 @@ class SpotifyClient:
12640
12730
  if delay > 0:
12641
12731
  _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE % delay)
12642
12732
  time.sleep(delay)
12733
+
12734
+ # if forceActivateDevice=True, then we need to resume play manually if play=True
12735
+ # was specified; this is due to the device losing its current status since it
12736
+ # was being forcefully activated (e.g. disconnected and reconnected).
12737
+ if (forceActivateDevice) and (play):
12738
+ _logsi.LogVerbose('Resuming play on device that was forcefully activated')
12739
+ self.PlayerMediaResume()
12643
12740
 
12644
12741
  # process results.
12645
12742
  # no results to process - this is pass or fail.
@@ -12721,6 +12818,8 @@ class SpotifyClient:
12721
12818
 
12722
12819
  # validations.
12723
12820
  delay = validateDelay(delay, 0.50, 10)
12821
+ if (play is None):
12822
+ play = False
12724
12823
 
12725
12824
  # get current Spotify Connect player state.
12726
12825
  result = self.GetPlayerPlaybackState()
@@ -15684,6 +15783,8 @@ class SpotifyClient:
15684
15783
  if scope is not None:
15685
15784
  if (not isinstance(scope, list)) and (not isinstance(scope, str)):
15686
15785
  raise SpotifyApiError(SAAppMessages.ARGUMENT_TYPE_ERROR % (apiMethodName, 'scope', 'list', type(scope).__name__), logsi=_logsi)
15786
+ if (forceAuthorize is None):
15787
+ forceAuthorize = False
15687
15788
 
15688
15789
  # create oauth provider for spotify authentication code with pkce.
15689
15790
  self._AuthClient:AuthClient = AuthClient(
@@ -15867,6 +15968,8 @@ class SpotifyClient:
15867
15968
  if scope is not None:
15868
15969
  if (not isinstance(scope, list)) and (not isinstance(scope, str)):
15869
15970
  raise SpotifyApiError(SAAppMessages.ARGUMENT_TYPE_ERROR % (apiMethodName, 'scope', 'list', type(scope).__name__), logsi=_logsi)
15971
+ if (forceAuthorize is None):
15972
+ forceAuthorize = False
15870
15973
 
15871
15974
  # create oauth provider for spotify authentication code with pkce.
15872
15975
  self._AuthClient:AuthClient = AuthClient(
@@ -49,7 +49,7 @@ class ZeroconfResponse:
49
49
  @property
50
50
  def ResponseSource(self) -> str:
51
51
  """
52
- Response source string (e.g. "").
52
+ Response source string (e.g. "", "eSDK", etc).
53
53
  """
54
54
  return self._ResponseSource
55
55