spotifywebapiPython 1.0.50__py3-none-any.whl → 1.0.52__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 (27) hide show
  1. {spotifywebapiPython-1.0.50.dist-info → spotifywebapiPython-1.0.52.dist-info}/METADATA +1 -1
  2. {spotifywebapiPython-1.0.50.dist-info → spotifywebapiPython-1.0.52.dist-info}/RECORD +27 -25
  3. spotifywebapipython/const.py +1 -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 +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 +111 -3
  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/models/__init__.py +2 -0
  18. spotifywebapipython/models/device.py +50 -0
  19. spotifywebapipython/models/spotifyconnectdevice.py +93 -0
  20. spotifywebapipython/models/spotifyconnectdevices.py +240 -0
  21. spotifywebapipython/models/zeroconfdiscoveryresult.py +13 -5
  22. spotifywebapipython/spotifyclient.py +144 -36
  23. spotifywebapipython/zeroconfapi/zeroconfgetinfo.py +32 -0
  24. spotifywebapipython/zeroconfapi/zeroconfresponse.py +24 -0
  25. {spotifywebapiPython-1.0.50.dist-info → spotifywebapiPython-1.0.52.dist-info}/LICENSE +0 -0
  26. {spotifywebapiPython-1.0.50.dist-info → spotifywebapiPython-1.0.52.dist-info}/WHEEL +0 -0
  27. {spotifywebapiPython-1.0.50.dist-info → spotifywebapiPython-1.0.52.dist-info}/top_level.txt +0 -0
@@ -5946,7 +5946,7 @@ class SpotifyClient:
5946
5946
  self,
5947
5947
  verifyUserContext:bool=False,
5948
5948
  delay:float=0.50,
5949
- ) -> None:
5949
+ ) -> str:
5950
5950
  """
5951
5951
  Activates all Spotify Connect player devices, and (optionally) switches the active user
5952
5952
  context to the current user context.
@@ -5963,6 +5963,9 @@ class SpotifyClient:
5963
5963
  another command is issued.
5964
5964
  Default is 0.50; value range is 0 - 10.
5965
5965
 
5966
+ Returns:
5967
+ A string that contains status text.
5968
+
5966
5969
  Raises:
5967
5970
  SpotifyWebApiError:
5968
5971
  If the Spotify Web API request was for a non-authorization service
@@ -6015,40 +6018,38 @@ class SpotifyClient:
6015
6018
 
6016
6019
  deviceActiveUser:str = None
6017
6020
  deviceIdResult:str = None
6018
-
6019
- # discover Spotify Connect devices on the network, waiting up to the specified timeout
6020
- # for all devices to be discovered. this will return all Spotify Connect devices that
6021
- # are currently powered on, and are registered to Zeroconf / mDNS.
6022
- _logsi.LogVerbose("Discovering Spotify Connect devices on the local network")
6023
- discovery:SpotifyDiscovery = SpotifyDiscovery(self._ZeroconfClient, printToConsole=False)
6024
- discovery.DiscoverDevices(timeout=self._SpotifyConnectDiscoveryTimeout)
6021
+ discoverResult:ZeroconfDiscoveryResult
6022
+ info:ZeroconfGetInfo
6023
+ scDevice:SpotifyConnectDevice
6024
+
6025
+ # get all Spotify Connect available devices on the network.
6026
+ scDevices:SpotifyConnectDevices = self.GetSpotifyConnectDevices()
6025
6027
 
6026
6028
  # process all discovered devices.
6027
- discoverResult:ZeroconfDiscoveryResult
6028
- for discoverResult in discovery.DiscoveryResults:
6029
+ for scDevice in scDevices:
6029
6030
 
6030
- # get the id from the device via the zeroconf API getInfo endpoint, as the id is not
6031
- # returned in the zeroconf discovery result.
6032
- zconn:ZeroconfConnect = ZeroconfConnect(discoverResult.HostIpv4Address,
6033
- discoverResult.HostIpPort,
6034
- discoverResult.SpotifyConnectCPath,
6035
- useSSL=False)
6036
- info:ZeroconfGetInfo = zconn.GetInformation()
6031
+ discoverResult = scDevice.DiscoveryResult
6032
+ info = scDevice.DeviceInfo
6037
6033
 
6038
6034
  # store the currently active user of the device, in case we need to switch users later on.
6039
6035
  deviceActiveUser = info.ActiveUser.lower()
6040
6036
  deviceIdResult = info.DeviceId
6041
6037
 
6042
- status:str = "INACTIVE"
6038
+ status:str = "INACTIVE, "
6043
6039
  if (info.HasActiveUser):
6044
6040
  status = "ACTIVE, "
6045
6041
 
6046
6042
  # did we resolve the device id?
6047
6043
  if deviceIdResult is not None:
6048
6044
 
6045
+ # is this a dynamic device? if so, then we can't control it.
6046
+ if (discoverResult.IsDynamicDevice):
6047
+ _logsi.LogVerbose("Spotify Connect Device id '%s' (%s) is a dynamic device; we cannot control it" % (deviceIdResult, info.RemoteName))
6048
+ status = status + "dynamic device, cannot switch user context"
6049
+
6049
6050
  # does our Spotify Connect user account need to take control of the device?
6050
6051
  # if not, then we are done.
6051
- if (deviceActiveUser == self._SpotifyConnectUsername.lower()): # or (deviceActiveUser == self.UserProfile.Id.lower()):
6052
+ elif (deviceActiveUser == self._SpotifyConnectUsername.lower()): # or (deviceActiveUser == self.UserProfile.Id.lower()):
6052
6053
  _logsi.LogVerbose("Spotify Connect user context '%s' was verified for Device id '%s'; switch not necessary" % (deviceActiveUser, deviceIdResult))
6053
6054
  status = status + "user context switch not needed"
6054
6055
 
@@ -6060,6 +6061,12 @@ class SpotifyClient:
6060
6061
 
6061
6062
  else:
6062
6063
  zcfResult:ZeroconfResponse
6064
+
6065
+ # create a ZeroconfConnect object to access the device.
6066
+ zconn:ZeroconfConnect = ZeroconfConnect(discoverResult.HostIpv4Address,
6067
+ discoverResult.HostIpPort,
6068
+ discoverResult.SpotifyConnectCPath,
6069
+ useSSL=False)
6063
6070
 
6064
6071
  # if a different user context has control of the device then we need to disconnect
6065
6072
  # the current user context before connecting a different user.
@@ -7890,6 +7897,102 @@ class SpotifyClient:
7890
7897
  _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
7891
7898
 
7892
7899
 
7900
+ def GetSpotifyConnectDevices(
7901
+ self,
7902
+ ) -> SpotifyConnectDevices:
7903
+ """
7904
+ Get information about all available Spotify Connect player devices.
7905
+
7906
+ Returns:
7907
+ A `SpotifyConnectDevices` object that contain the discovery results
7908
+ as well as the `getInfo` result for each found device.
7909
+
7910
+ Raises:
7911
+ SpotifyWebApiError:
7912
+ If the Spotify Web API request was for a non-authorization service
7913
+ and the response contains error information.
7914
+ SpotifyZeroconfApiError:
7915
+ If the Spotify Zeroconf API request faild for any reason.
7916
+ SpotifApiError:
7917
+ If the method fails for any other reason.
7918
+
7919
+ This method is similar to the `GetPlayerDevices` method, but it contains ALL
7920
+ available Spotify Connect devices that are known to the local network (versus
7921
+ just the devices known to a specific user).
7922
+
7923
+ It will also call the `GetPlayerDevices` method, in case we have any dynamic devices.
7924
+ Dynamic devices are Spotify Connect devices that are not found in Zeroconf discovery
7925
+ process, but still exist in the player device list. These are usually Spotify Connect
7926
+ web or mobile players with temporary device id's.
7927
+
7928
+ <details>
7929
+ <summary>Sample Code</summary>
7930
+ ```python
7931
+ .. include:: ../docs/include/samplecode/SpotifyClient/GetSpotifyConnectDevices.py
7932
+ ```
7933
+ </details>
7934
+ """
7935
+ apiMethodName:str = 'GetSpotifyConnectDevices'
7936
+ result:SpotifyConnectDevices = SpotifyConnectDevices()
7937
+
7938
+ try:
7939
+
7940
+ # trace.
7941
+ _logsi.EnterMethod(SILevel.Debug, apiMethodName)
7942
+
7943
+ # discover Spotify Connect devices on the network, waiting up to the specified timeout
7944
+ # for all devices to be discovered. this will return all Spotify Connect devices that
7945
+ # are currently powered on, and are registered to Zeroconf / mDNS.
7946
+ _logsi.LogVerbose("Discovering Spotify Connect devices on the local network")
7947
+ discovery:SpotifyDiscovery = SpotifyDiscovery(self._ZeroconfClient, printToConsole=False)
7948
+ discovery.DiscoverDevices(timeout=self._SpotifyConnectDiscoveryTimeout)
7949
+
7950
+ # process all discovered devices.
7951
+ discoverResult:ZeroconfDiscoveryResult
7952
+ for discoverResult in discovery.DiscoveryResults:
7953
+
7954
+ # get the id from the device via the zeroconf API getInfo endpoint, as the id is not
7955
+ # returned in the zeroconf discovery result.
7956
+ zconn:ZeroconfConnect = ZeroconfConnect(discoverResult.HostIpv4Address,
7957
+ discoverResult.HostIpPort,
7958
+ discoverResult.SpotifyConnectCPath,
7959
+ useSSL=False)
7960
+ info:ZeroconfGetInfo = zconn.GetInformation()
7961
+
7962
+ # create new spotify connect device object.
7963
+ scDevice:SpotifyConnectDevice = SpotifyConnectDevice()
7964
+ scDevice.DiscoveryResult = discoverResult
7965
+ scDevice.DeviceInfo = info
7966
+ result.Items.append(scDevice)
7967
+
7968
+ # we will also call the GetPlayerDevices method, in case we have any dynamic devices.
7969
+ # dynamic devices are Spotify Connect devices that are not found in Zeroconf discovery
7970
+ # process, but still exist in the player device list. these are usually Spotify Connect
7971
+ # web or mobile players with temporary device id's.
7972
+ devices:list[Device] = self.GetPlayerDevices(True)
7973
+
7974
+ device:Device
7975
+ for device in devices:
7976
+ if not result.ContainsDeviceId(device.Id):
7977
+ result.AddDynamicDevice(device, self.UserProfile.Id)
7978
+
7979
+ # trace.
7980
+ _logsi.LogArray(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result)
7981
+ return result
7982
+
7983
+ except SpotifyZeroconfApiError: raise # pass handled exceptions on thru
7984
+ except SpotifyApiError: raise # pass handled exceptions on thru
7985
+ except Exception as ex:
7986
+
7987
+ # format unhandled exception.
7988
+ raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
7989
+
7990
+ finally:
7991
+
7992
+ # trace.
7993
+ _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
7994
+
7995
+
7893
7996
  def GetTrack(self,
7894
7997
  trackId:str,
7895
7998
  ) -> Track:
@@ -10185,33 +10288,27 @@ class SpotifyClient:
10185
10288
  # determine if the device value specified is a name (e.g. "Bose-ST10-1") or
10186
10289
  # an id (e.g. "30fbc80e35598f3c242f2120413c943dfd9715fe").
10187
10290
  isDeviceId:bool = SpotifyClient.IsDeviceId(deviceValue)
10291
+
10188
10292
  deviceValueCompare:str = deviceValue.lower()
10189
10293
  deviceActiveUser:str = None
10190
-
10191
- # discover Spotify Connect devices on the network, waiting up to the specified timeout
10192
- # for all devices to be discovered. this will return all Spotify Connect devices that
10193
- # are currently powered on, and are registered to Zeroconf / mDNS.
10194
- _logsi.LogVerbose("Discovering Spotify Connect devices on the local network")
10195
- discovery:SpotifyDiscovery = SpotifyDiscovery(self._ZeroconfClient, printToConsole=False)
10196
- discovery.DiscoverDevices(timeout=self._SpotifyConnectDiscoveryTimeout)
10294
+ discoverResult:ZeroconfDiscoveryResult
10295
+ info:ZeroconfGetInfo
10296
+ scDevice:SpotifyConnectDevice
10297
+
10298
+ # get all Spotify Connect available devices on the network.
10299
+ scDevices:SpotifyConnectDevices = self.GetSpotifyConnectDevices()
10197
10300
 
10198
10301
  # process all discovered devices.
10199
- discoverResult:ZeroconfDiscoveryResult
10200
- for discoverResult in discovery.DiscoveryResults:
10302
+ for scDevice in scDevices:
10201
10303
 
10202
- # get the id from the device via the zeroconf API getInfo endpoint, as the id is not
10203
- # returned in the zeroconf discovery result.
10204
- zconn:ZeroconfConnect = ZeroconfConnect(discoverResult.HostIpv4Address,
10205
- discoverResult.HostIpPort,
10206
- discoverResult.SpotifyConnectCPath,
10207
- useSSL=False)
10208
- info:ZeroconfGetInfo = zconn.GetInformation()
10304
+ discoverResult = scDevice.DiscoveryResult
10305
+ info = scDevice.DeviceInfo
10209
10306
 
10210
10307
  # store the currently active user of the device, in case we need to switch users later on.
10211
10308
  deviceActiveUser = info.ActiveUser.lower()
10212
10309
 
10213
10310
  # are aliases being used (RemoteName is null if so)?
10214
- if info.RemoteName is None:
10311
+ if info.HasAliases:
10215
10312
 
10216
10313
  # if aliases are defined for the device, then we have to check each alias for a match.
10217
10314
  infoAlias:ZeroconfGetInfoAlias
@@ -10244,6 +10341,11 @@ class SpotifyClient:
10244
10341
  # did we resolve the device id?
10245
10342
  if deviceIdResult is not None:
10246
10343
 
10344
+ # is this a dynamic device? if so, then we can't control it.
10345
+ if (discoverResult.IsDynamicDevice):
10346
+ _logsi.LogVerbose("Spotify Connect Device '%s' (%s) is a dynamic device; we cannot control it" % (info.RemoteName, deviceIdResult))
10347
+ break
10348
+
10247
10349
  # did caller request user context switch bypass?
10248
10350
  # if so, then just return the device id.
10249
10351
  if (not verifyUserContext):
@@ -10264,6 +10366,12 @@ class SpotifyClient:
10264
10366
 
10265
10367
  zcfResult:ZeroconfResponse
10266
10368
 
10369
+ # create a ZeroconfConnect object to access the device.
10370
+ zconn:ZeroconfConnect = ZeroconfConnect(discoverResult.HostIpv4Address,
10371
+ discoverResult.HostIpPort,
10372
+ discoverResult.SpotifyConnectCPath,
10373
+ useSSL=False)
10374
+
10267
10375
  # if a different user context has control of the device then we need to disconnect
10268
10376
  # the current user context before connecting a different user.
10269
10377
  if (info.HasActiveUser):
@@ -109,6 +109,14 @@ class ZeroconfGetInfo(ZeroconfResponse):
109
109
  This value will be an empty string if there is no user logged into the device.
110
110
  """
111
111
  return self._ActiveUser
112
+
113
+ @ActiveUser.setter
114
+ def ActiveUser(self, value:str):
115
+ """
116
+ Sets the ActiveUser property value.
117
+ """
118
+ if isinstance(value, str):
119
+ self._ActiveUser = value
112
120
 
113
121
 
114
122
  @property
@@ -158,6 +166,14 @@ class ZeroconfGetInfo(ZeroconfResponse):
158
166
  Unique device ID used for ZeroConf logins (e.g. "30fbc80e35598f3c242f2120413c943dfd9715fe").
159
167
  """
160
168
  return self._DeviceId
169
+
170
+ @DeviceId.setter
171
+ def DeviceId(self, value:str):
172
+ """
173
+ Sets the DeviceId property value.
174
+ """
175
+ if isinstance(value, str):
176
+ self._DeviceId = value
161
177
 
162
178
 
163
179
  @property
@@ -182,6 +198,14 @@ class ZeroconfGetInfo(ZeroconfResponse):
182
198
  - kSpDeviceTypeChromebook Chromebook.
183
199
  """
184
200
  return self._DeviceType
201
+
202
+ @DeviceType.setter
203
+ def DeviceType(self, value:str):
204
+ """
205
+ Sets the DeviceType property value.
206
+ """
207
+ if isinstance(value, str):
208
+ self._DeviceType = value
185
209
 
186
210
 
187
211
  @property
@@ -253,6 +277,14 @@ class ZeroconfGetInfo(ZeroconfResponse):
253
277
  Please refer to the `Aliases` property for more information.
254
278
  """
255
279
  return self._RemoteName
280
+
281
+ @RemoteName.setter
282
+ def RemoteName(self, value:str):
283
+ """
284
+ Sets the RemoteName property value.
285
+ """
286
+ if isinstance(value, str):
287
+ self._RemoteName = value
256
288
 
257
289
 
258
290
  @property
@@ -57,6 +57,14 @@ class ZeroconfResponse:
57
57
  The last error code returned by a Spotify API call or the SpCallbackError() callback (e.g. 0, -119, etc).
58
58
  """
59
59
  return self._SpotifyError
60
+
61
+ @SpotifyError.setter
62
+ def SpotifyError(self, value:int):
63
+ """
64
+ Sets the SpotifyError property value.
65
+ """
66
+ if isinstance(value, int):
67
+ self._SpotifyError = value
60
68
 
61
69
 
62
70
  @property
@@ -65,6 +73,14 @@ class ZeroconfResponse:
65
73
  A code indicating the result of the operation (e.g. 101, 402, etc).
66
74
  """
67
75
  return self._Status
76
+
77
+ @Status.setter
78
+ def Status(self, value:int):
79
+ """
80
+ Sets the Status property value.
81
+ """
82
+ if isinstance(value, int):
83
+ self._Status = value
68
84
 
69
85
 
70
86
  @property
@@ -73,6 +89,14 @@ class ZeroconfResponse:
73
89
  The string describing the status code (e.g. "OK", "ERROR-SPOTIFY-ERROR", etc).
74
90
  """
75
91
  return self._StatusString
92
+
93
+ @StatusString.setter
94
+ def StatusString(self, value:str):
95
+ """
96
+ Sets the StatusString property value.
97
+ """
98
+ if isinstance(value, str):
99
+ self._StatusString = value
76
100
 
77
101
 
78
102
  def ToDictionary(self) -> dict: