spotifywebapiPython 1.0.103__py3-none-any.whl → 1.0.105__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.103.dist-info → spotifywebapiPython-1.0.105.dist-info}/METADATA +1 -1
  2. {spotifywebapiPython-1.0.103.dist-info → spotifywebapiPython-1.0.105.dist-info}/RECORD +22 -22
  3. spotifywebapipython/const.py +1 -1
  4. spotifywebapipython/docs/__init__.html +16 -3
  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 +20 -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 +53 -43
  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/saappmessages.py +6 -1
  18. spotifywebapipython/spotifyclient.py +61 -65
  19. spotifywebapipython/zeroconfapi/zeroconfconnect.py +34 -8
  20. {spotifywebapiPython-1.0.103.dist-info → spotifywebapiPython-1.0.105.dist-info}/LICENSE +0 -0
  21. {spotifywebapiPython-1.0.103.dist-info → spotifywebapiPython-1.0.105.dist-info}/WHEEL +0 -0
  22. {spotifywebapiPython-1.0.103.dist-info → spotifywebapiPython-1.0.105.dist-info}/top_level.txt +0 -0
@@ -6342,25 +6342,32 @@ class SpotifyClient:
6342
6342
  and the response contains error information.
6343
6343
  SpotifyZeroconfApiError:
6344
6344
  If any Spotify Zeroconf API request failed.
6345
- If the `spotifyConnectUsername` argument was not specified for the class contructor.
6346
6345
  SpotifApiError:
6346
+ If the `spotifyConnectLoginId` argument was not specified for the class contructor.
6347
+ If the `spotifyConnectUsername` argument was not specified for the class contructor.
6348
+ If the `spotifyConnectPassword` argument was not specified for the class contructor.
6347
6349
  If the method fails for any other reason.
6348
6350
 
6349
- A Zeroconf discovery process is initiated to search for all Spotify Connect devices connected
6350
- to the local network. A Spotify Zeroconf API `getInfo` call is then issued for each device
6351
- that was found to retrieve device information. A Spotify Zeroconf API `addUser` call is also
6352
- issued for each device that does not have an active user context established, OR if the currently
6353
- active user context does not match the `SpotifyConnectUsername` argument specified on the class
6354
- constructor and the `verifyUserContext` argument is True.
6355
-
6356
- The user context switch is bypassed if the `verifyUserContext` argument is False. If the user context
6357
- is to be switched, then a Disconnect will be issued if a user context is active on the device followed
6358
- by a Connect to the user context specified on the class constructor.
6359
-
6360
- Dynamic Spotify Connect devices are not processed by this method, as they are temporary devices and are
6361
- already active and in the device list. These devices are not found in Zeroconf discovery process, and only
6362
- exist in the player device list. These are usually Spotify Connect web or mobile players with temporary device id's.
6351
+ A Zeroconf discovery process is initiated to search for all Spotify Connect devices connected
6352
+ to the local network. It will then iterate through the returned devices and perform the
6353
+ following on each one:
6354
+ - call Spotify Zeroconf API `getInfo` endpoint to retrieve device information.
6355
+ - call Spotify Zeroconf API `resetUsers` endpoint to disconnect the device. This step is omitted
6356
+ for dynamic devices (see note below). Note that this will force any users that are connected to
6357
+ the device off of the device.
6358
+ - call Spotify Zeroconf API `addUser` endpoint to connect the device. This step is omitted for
6359
+ dynamic devices (see note below). This should "re-awaken" the device if necessary, and make it
6360
+ ready for immediate use.
6361
+
6362
+ Dynamic Spotify Connect devices are not processed by this method, as they are temporary devices and
6363
+ are already active and in the device list. These devices are not found in Zeroconf discovery process,
6364
+ and only exist in the player device list. These are usually Spotify Connect web or mobile players
6365
+ with temporary device id's.
6363
6366
 
6367
+ Note that the SpotifyConnectUsername, SpotifyConnectPassword, and SpotifyConnectLoginId arguments must
6368
+ be specified on the class contructor in order to use this method. They are all required in order to
6369
+ reactivate a Spotify Connect device.
6370
+
6364
6371
  <details>
6365
6372
  <summary>Sample Code</summary>
6366
6373
  ```python
@@ -6378,14 +6385,10 @@ class SpotifyClient:
6378
6385
 
6379
6386
  # trace.
6380
6387
  apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
6381
- apiMethodParms.AppendKeyValue("verifyUserContext", verifyUserContext)
6388
+ apiMethodParms.AppendKeyValue("verifyUserContext (deprecated)", verifyUserContext)
6382
6389
  apiMethodParms.AppendKeyValue("delay", delay)
6383
6390
  _logsi.LogMethodParmList(SILevel.Verbose, "Activating Spotify Connect Player Devices", apiMethodParms)
6384
6391
 
6385
- # validation - ensure spotify connect user context was specified on the class constructor.
6386
- if (self._SpotifyConnectUsername is None):
6387
- raise SpotifyZeroconfApiError(SAAppMessages.ARGUMENT_REQUIRED_ERROR % (apiMethodName, 'SpotifyConnectUsername'), logsi=_logsi)
6388
-
6389
6392
  # validations.
6390
6393
  delay = validateDelay(delay, 0.25, 10)
6391
6394
  if (not isinstance(verifyUserContext, bool)):
@@ -6422,24 +6425,10 @@ class SpotifyClient:
6422
6425
 
6423
6426
  # is this a dynamic device? if so, then there is no need to activate it as it's already active.
6424
6427
  if (discoverResult.IsDynamicDevice):
6428
+
6425
6429
  _logsi.LogVerbose("Activation not required for dynamic Spotify Connect device: '%s'" % (scDevice.Title))
6426
- status = status + "dynamic device, cannot switch user context"
6427
-
6428
- # does our Spotify Connect user account need to take control of the device?
6429
- # if not, then we are done.
6430
- # this takes into account if the device is in the available device list, as well
6431
- # as if the active user is not our user context.
6432
- elif (info.IsInDeviceList == True) \
6433
- and ((deviceActiveUser == self._SpotifyConnectUsername.lower()) or (deviceActiveUser == self.UserProfile.Id.lower())):
6434
- _logsi.LogVerbose("User context '%s' was verified for Spotify Connect device '%s'; switch not necessary" % (deviceActiveUser, scDevice.Title))
6435
- status = status + "user context switch not needed"
6430
+ status = status + "dynamic device, cannot switch user context; "
6436
6431
 
6437
- # did caller request user context switch bypass?
6438
- # if so, then just return the device id.
6439
- elif (info.HasActiveUser) and (not verifyUserContext):
6440
- _logsi.LogVerbose("User context '%s' will be used for Spotify Connect device '%s', as user chose to bypass user context switch" % (deviceActiveUser, scDevice.Title))
6441
- status = status + "caller bypassed user context switch"
6442
-
6443
6432
  else:
6444
6433
 
6445
6434
  zcfResult:ZeroconfResponse
@@ -6462,19 +6451,21 @@ class SpotifyClient:
6462
6451
  if (info.BrandDisplayName != 'librespot'):
6463
6452
  _logsi.LogVerbose("Issuing Disconnect to Spotify Connect device '%s' for current user context '%s'" % (scDevice.Title, deviceActiveUser))
6464
6453
  zcfResult = zconn.Disconnect(delay)
6465
- status = status + 'disconnected from user context "%s";' % deviceActiveUser
6454
+ status = status + 'disconnected from user context "%s"; ' % deviceActiveUser
6455
+ else:
6456
+ status = status + 'disconnect bypassed for librespot device; '
6466
6457
 
6467
6458
  # connect the device to OUR Spotify Connect user context.
6468
6459
  # note that the result here only indicates that the connect was submitted - NOT that it was successful!
6469
- _logsi.LogVerbose("Issuing Connect to Spotify Connect device '%s' for user context '%s'" % (scDevice.Title, self._SpotifyConnectUsername))
6460
+ _logsi.LogVerbose("Issuing Connect to Spotify Connect device '%s' for user context '%s'" % (scDevice.Title, self._SpotifyConnectLoginId))
6470
6461
  zcfResult = zconn.Connect(self._SpotifyConnectUsername, self._SpotifyConnectPassword, self._SpotifyConnectLoginId, delay=delay)
6471
- status = status + 'connected to user context "%s"' % self._SpotifyConnectUsername
6462
+ status = status + 'connected to user context "%s"; ' % self._SpotifyConnectLoginId
6472
6463
 
6473
6464
  # indicate device was reconnected.
6474
6465
  scDevice.WasReConnected = True
6475
6466
 
6476
6467
  # trace.
6477
- _logsi.LogVerbose("User context switch from '%s' to '%s' was requested for Spotify Connect device '%s'" % (deviceActiveUser, self._SpotifyConnectUsername, scDevice.Title))
6468
+ _logsi.LogVerbose("User context switched from '%s' to '%s' for Spotify Connect device '%s'" % (deviceActiveUser, self._SpotifyConnectLoginId, scDevice.Title))
6478
6469
 
6479
6470
  # append device status to results.
6480
6471
  result = "%s%s\n" % (result, MSG_RESULT % (info.RemoteName, info.DeviceId, info.ActiveUser, status))
@@ -8728,6 +8719,9 @@ class SpotifyClient:
8728
8719
  SpotifyZeroconfApiError:
8729
8720
  If any Spotify Zeroconf API request failed.
8730
8721
  SpotifApiError:
8722
+ If the `spotifyConnectLoginId` argument was not specified for the class contructor.
8723
+ If the `spotifyConnectUsername` argument was not specified for the class contructor.
8724
+ If the `spotifyConnectPassword` argument was not specified for the class contructor.
8731
8725
  If the method fails for any other reason.
8732
8726
 
8733
8727
  The Spotify Connect discovery list is searched for the specified device value; the search will
@@ -8773,6 +8767,11 @@ class SpotifyClient:
8773
8767
  _logsi.LogVerbose("deviceValue not specified; active Spotify Player will be used")
8774
8768
  return None
8775
8769
 
8770
+ # was a Spotify Connect loginId specified on the class constructor?
8771
+ # if not, then we cannot re-activate devices!
8772
+ if (self._SpotifyConnectLoginId is None):
8773
+ raise SpotifyApiError(SAAppMessages.MSG_SPOTIFY_ACTIVATE_CREDENTIAL_REQUIRED % ("SpotifyConnectLoginId"), logsi=_logsi)
8774
+
8776
8775
  # validations.
8777
8776
  delay = validateDelay(delay, 0.25, 10)
8778
8777
  verifyTimeout = validateDelay(verifyTimeout, 5, 10)
@@ -8876,7 +8875,7 @@ class SpotifyClient:
8876
8875
  )
8877
8876
 
8878
8877
  if not hasToken:
8879
- _logsi.LogVerbose("Spotify Desktop Application Client oauth2 token was not found for Spotify LogiId: '%s'" % (self._SpotifyConnectLoginId))
8878
+ _logsi.LogVerbose("Spotify Desktop Application Client oauth2 token was not found for Spotify LoginId: '%s'" % (self._SpotifyConnectLoginId))
8880
8879
  break
8881
8880
 
8882
8881
  # store the currently active user of the device, in case we need to switch users later on.
@@ -8894,13 +8893,6 @@ class SpotifyClient:
8894
8893
 
8895
8894
  zcfResult:ZeroconfResponse
8896
8895
 
8897
- # was a Spotify Connect user account specified on the class constructor?
8898
- # if not, then we cannot re-activate the device!
8899
- if (self._SpotifyConnectUsername is None):
8900
- raise SpotifyApiError("A SpotifyConnectUsername parameter was not supplied; could not reactivate Spotify Connect device '%s'" % (deviceResult.Title), logsi=_logsi)
8901
- #_logsi.LogVerbose("A SpotifyConnectUsername parameter was not supplied; could not reactivate Spotify Connect device '%s'" % (deviceResult.Title))
8902
- break
8903
-
8904
8896
  # disconnect the device.
8905
8897
  # we will bypass disconnects for librespot devices (e.g. spotifyd, etc), as the
8906
8898
  # Spotify Connect Zeroconf `resetUsers` endpoint is not implemented and will
@@ -8911,14 +8903,14 @@ class SpotifyClient:
8911
8903
 
8912
8904
  # connect the device to OUR Spotify Connect user context.
8913
8905
  # note that the result here only indicates that the connect was submitted - NOT that it was successful!
8914
- _logsi.LogVerbose("Issuing Connect to Spotify Connect device '%s' for user context '%s'" % (deviceResult.Title, self._SpotifyConnectUsername))
8906
+ _logsi.LogVerbose("Issuing Connect to Spotify Connect device '%s' for user context '%s'" % (deviceResult.Title, self._SpotifyConnectLoginId))
8915
8907
  zcfResult = zconn.Connect(self._SpotifyConnectUsername, self._SpotifyConnectPassword, self._SpotifyConnectLoginId)
8916
8908
 
8917
8909
  # indicate device was reconnected.
8918
8910
  deviceResult.WasReConnected = True
8919
8911
 
8920
8912
  # trace.
8921
- _logsi.LogVerbose("User context switch from '%s' to '%s' was requested for Spotify Connect device: '%s'" % (deviceActiveUser, self._SpotifyConnectUsername, deviceResult.Title))
8913
+ _logsi.LogVerbose("User context switched from '%s' to '%s' for Spotify Connect device: '%s'" % (deviceActiveUser, self._SpotifyConnectLoginId, deviceResult.Title))
8922
8914
 
8923
8915
  loopTotalDelay:float = 0
8924
8916
  LOOP_DELAY:float = 0.25
@@ -11385,17 +11377,18 @@ class SpotifyClient:
11385
11377
  relativePositionMS:int=0,
11386
11378
  ) -> None:
11387
11379
  """
11388
- Seeks to the given position in the user's currently playing track for the specified
11389
- Spotify Connect device.
11380
+ Seeks to the given absolute or relative position in the user's currently playing track
11381
+ for the specified Spotify Connect device.
11390
11382
 
11391
11383
  This method requires the `user-modify-playback-state` scope.
11392
11384
 
11393
11385
  Args:
11394
11386
  positionMS (int):
11395
- The position in milliseconds to seek to; must be a positive number.
11387
+ The absolute position in milliseconds to seek to; must be a positive number or
11388
+ zero if the `relativePositionMS` argument is specified.
11396
11389
  Passing in a position that is greater than the length of the track will cause the
11397
- player to start playing the next song.
11398
- Example: `25000`
11390
+ player to start playing the next song.
11391
+ Example = `25000` to start playing at the 25 second mark.
11399
11392
  deviceId (str):
11400
11393
  The id or name of the device this command is targeting.
11401
11394
  If not supplied, the user's currently active device is the target.
@@ -11407,10 +11400,10 @@ class SpotifyClient:
11407
11400
  another command is issued.
11408
11401
  Default is 0.50; value range is 0 - 10.
11409
11402
  relativePositionMS (int):
11410
- The relative position in milliseconds to seek to; can be a positive or negative number.
11411
- Passing in a positive relative position that causes the position to be greater than the
11412
- length of the track will cause the player to start playing the next song.
11413
- Example: `25000`
11403
+ The relative position in milliseconds to seek to; can be a positive or negative number,
11404
+ or zero if the `positionMS` argument is specified.
11405
+ Example = `-10000` to seek behind by 10 seconds.
11406
+ Example = `10000` to seek ahead by 10 seconds.
11414
11407
 
11415
11408
  Raises:
11416
11409
  SpotifyWebApiError:
@@ -11423,12 +11416,15 @@ class SpotifyClient:
11423
11416
 
11424
11417
  The order of execution is not guaranteed when you use this API with other Player API endpoints.
11425
11418
 
11419
+ If using relative positioning, the `positionMS` argument must be zero (or null); the `positionMS`
11420
+ argument takes precedence if it and the `relativePositionMS` argument are specified. A positive
11421
+ relative position that causes the seek position to be greater than the length of the track will
11422
+ cause the player to start playing the next song. A negative relative position that causes the
11423
+ seek position to be less than zero will cause the player to start playing the track from the beginning.
11424
+
11426
11425
  Note that the `relativePositionMS` functionality is not defined by the Spotify Web API. This
11427
- argument was added to this API to support "skip" seeking. A positive relative position that causes
11428
- the seek position to be greater than the length of the track will cause the player to start playing
11429
- the next song. A negative relative position that causes the seek position to be less than zero
11430
- will cause the player to start playing the track from the beginning.
11431
-
11426
+ argument was added to this API to support "skip" seeking.
11427
+
11432
11428
  <details>
11433
11429
  <summary>Sample Code</summary>
11434
11430
  ```python
@@ -11470,7 +11466,7 @@ class SpotifyClient:
11470
11466
  deviceId = self.PlayerConvertDeviceNameToId(deviceId)
11471
11467
 
11472
11468
  # was relative seeking specified?
11473
- if (relativePositionMS != 0) and (positionMS == 0):
11469
+ if (relativePositionMS != 0) and ((positionMS is None) or (positionMS <= 0)):
11474
11470
 
11475
11471
  # get current track position.
11476
11472
  playState:PlayerPlayState = self.GetPlayerPlaybackState()
@@ -408,10 +408,6 @@ class ZeroconfConnect:
408
408
  _logsi.LogMethodParmList(SILevel.Verbose, "Connecting device to Spotify Connect (ip=%s)" % self._HostIpAddress, apiMethodParms)
409
409
 
410
410
  # validations.
411
- if (username is None) or (not isinstance(username,str)):
412
- raise SpotifyApiError(SAAppMessages.ARGUMENT_REQUIRED_ERROR % (apiMethodName, 'username'), logsi=_logsi)
413
- if (password is None) or (not isinstance(password,str)):
414
- raise SpotifyApiError(SAAppMessages.ARGUMENT_REQUIRED_ERROR % (apiMethodName, 'password'), logsi=_logsi)
415
411
  delay = validateDelay(delay, 0.50, 10)
416
412
 
417
413
  # get the current device id from the device via Spotify ZeroConf API `getInfo` endpoint.
@@ -551,10 +547,6 @@ class ZeroconfConnect:
551
547
  'Connection': 'close'
552
548
  }
553
549
 
554
- # create credentials and builder objects.
555
- credentials:Credentials = Credentials(username, password, AuthenticationTypes.USER_PASS)
556
- builder = BlobBuilder(credentials, info.DeviceId, info.PublicKey)
557
-
558
550
  # set defaults used by most manufacturers - we will tailor these in the
559
551
  # logic below for specific manufacturers / devices as required.
560
552
  # - exclude origin device information from the addUser request.
@@ -569,6 +561,16 @@ class ZeroconfConnect:
569
561
  # special processing for librespot, spotifyd.
570
562
  if info.ModelDisplayName == 'librespot':
571
563
 
564
+ # trace.
565
+ _logsi.LogVerbose("Spotify Connect token type is '%s' - using librespot authorization credentials to connect: '%s' (ip=%s)" % (info.TokenType, info.RemoteName, self._HostIpAddress))
566
+
567
+ # validations.
568
+ # note that userid and password are not needed by librespot, as both of those
569
+ # are contained in the librespot credentials object. we only need the loginId
570
+ # value for the credentials lookup.
571
+ if (loginId is None) or (not isinstance(loginId,str)):
572
+ raise SpotifyApiError(SAAppMessages.MSG_SPOTIFY_ACTIVATE_CREDENTIAL_REQUIRED % ("SpotifyConnectLoginId"), logsi=_logsi)
573
+
572
574
  # we will use credentials from a librespot credentials.json file.
573
575
  # this requires that the user copy the "credentials.json" file from the
574
576
  # librespot cache location (e.g. "/home/user/.cache/spotifyd/credentials.json", etc)
@@ -601,6 +603,18 @@ class ZeroconfConnect:
601
603
  # trace.
602
604
  _logsi.LogVerbose("Spotify Connect token type is '%s' - using Spotify Desktop Client OAuth2 token to connect: '%s' (ip=%s)" % (info.TokenType, info.RemoteName, self._HostIpAddress))
603
605
 
606
+ # validations.
607
+ if (loginId is None) or (not isinstance(loginId,str)):
608
+ raise SpotifyApiError(SAAppMessages.MSG_SPOTIFY_ACTIVATE_CREDENTIAL_REQUIRED % ("SpotifyConnectLoginId"), logsi=_logsi)
609
+ if (username is None) or (not isinstance(username,str)):
610
+ raise SpotifyApiError(SAAppMessages.MSG_SPOTIFY_ACTIVATE_CREDENTIAL_REQUIRED % ("SpotifyConnectUsername"), logsi=_logsi)
611
+ if (password is None) or (not isinstance(password,str)):
612
+ raise SpotifyApiError(SAAppMessages.MSG_SPOTIFY_ACTIVATE_CREDENTIAL_REQUIRED % ("SpotifyConnectPassword"), logsi=_logsi)
613
+
614
+ # create credentials and builder objects.
615
+ credentials:Credentials = Credentials(username, password, AuthenticationTypes.USER_PASS)
616
+ builder = BlobBuilder(credentials, info.DeviceId, info.PublicKey)
617
+
604
618
  # set defaults used by token type "authorization_code".
605
619
  # - set the clientKey value to null, as it is not used to encrypt / decrypt anything.
606
620
  # - include origin device information in the addUser request.
@@ -617,6 +631,18 @@ class ZeroconfConnect:
617
631
  # trace.
618
632
  _logsi.LogVerbose("Spotify Connect token type is '%s' - using Spotify username and password to connect: '%s' (ip=%s)" % (info.TokenType, info.RemoteName, self._HostIpAddress))
619
633
 
634
+ # validations.
635
+ if (loginId is None) or (not isinstance(loginId,str)):
636
+ raise SpotifyApiError(SAAppMessages.MSG_SPOTIFY_ACTIVATE_CREDENTIAL_REQUIRED % ("SpotifyConnectLoginId"), logsi=_logsi)
637
+ if (username is None) or (not isinstance(username,str)):
638
+ raise SpotifyApiError(SAAppMessages.MSG_SPOTIFY_ACTIVATE_CREDENTIAL_REQUIRED % ("SpotifyConnectUsername"), logsi=_logsi)
639
+ if (password is None) or (not isinstance(password,str)):
640
+ raise SpotifyApiError(SAAppMessages.MSG_SPOTIFY_ACTIVATE_CREDENTIAL_REQUIRED % ("SpotifyConnectPassword"), logsi=_logsi)
641
+
642
+ # create credentials and builder objects.
643
+ credentials:Credentials = Credentials(username, password, AuthenticationTypes.USER_PASS)
644
+ builder = BlobBuilder(credentials, info.DeviceId, info.PublicKey)
645
+
620
646
  # set defaults used by this token type:
621
647
  # - clientKey should be the getInfo response PublicKey (base64 encoded).
622
648
  # - exclude origin device information from the addUser request.