spotifywebapiPython 1.0.50__py3-none-any.whl → 1.0.51__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 (25) hide show
  1. {spotifywebapiPython-1.0.50.dist-info → spotifywebapiPython-1.0.51.dist-info}/METADATA +1 -1
  2. {spotifywebapiPython-1.0.50.dist-info → spotifywebapiPython-1.0.51.dist-info}/RECORD +25 -23
  3. spotifywebapipython/const.py +1 -1
  4. spotifywebapipython/docs/__init__.html +8 -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 +99 -2
  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 +137 -0
  21. spotifywebapipython/models/zeroconfdiscoveryresult.py +0 -5
  22. spotifywebapipython/spotifyclient.py +81 -0
  23. {spotifywebapiPython-1.0.50.dist-info → spotifywebapiPython-1.0.51.dist-info}/LICENSE +0 -0
  24. {spotifywebapiPython-1.0.50.dist-info → spotifywebapiPython-1.0.51.dist-info}/WHEEL +0 -0
  25. {spotifywebapiPython-1.0.50.dist-info → spotifywebapiPython-1.0.51.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,93 @@
1
+ # external package imports.
2
+ from zeroconf import ServiceInfo
3
+
4
+ # our package imports.
5
+ from ..sautils import export
6
+ from .zeroconfdiscoveryresult import ZeroconfDiscoveryResult
7
+ from spotifywebapipython.zeroconfapi.zeroconfgetinfo import ZeroconfGetInfo
8
+
9
+ @export
10
+ class SpotifyConnectDevice():
11
+ """
12
+ Spotify Connect Device object.
13
+
14
+ Information about the Spotify Connect device, which is a combination of the
15
+ `ZeroconfDiscoveryResult` and `ZeroconfGetInfo` classes.
16
+ """
17
+
18
+ def __init__(self) -> None:
19
+ """
20
+ Initializes a new instance of the class.
21
+ """
22
+ self._DiscoveryResult:ZeroconfDiscoveryResult = None
23
+ self._DeviceInfo:ZeroconfGetInfo = None
24
+
25
+
26
+ def __repr__(self) -> str:
27
+ return self.ToString()
28
+
29
+
30
+ def __str__(self) -> str:
31
+ return self.ToString()
32
+
33
+
34
+ @property
35
+ def DiscoveryResult(self) -> ZeroconfDiscoveryResult:
36
+ """
37
+ Information about the Zeroconf entry for a SpotifyConnect device as found by Zeroconf (mDNS).
38
+ """
39
+ return self._DiscoveryResult
40
+
41
+ @DiscoveryResult.setter
42
+ def DiscoveryResult(self, value:ZeroconfDiscoveryResult):
43
+ """
44
+ Sets the DiscoveryResult property value.
45
+ """
46
+ if isinstance(value, ZeroconfDiscoveryResult):
47
+ self._DiscoveryResult = value
48
+
49
+
50
+ @property
51
+ def DeviceInfo(self) -> ZeroconfGetInfo:
52
+ """
53
+ Spotify Zeroconf API GetInfo response object.
54
+ """
55
+ return self._DeviceInfo
56
+
57
+ @DeviceInfo.setter
58
+ def DeviceInfo(self, value:ZeroconfGetInfo):
59
+ """
60
+ Sets the DeviceInfo property value.
61
+ """
62
+ if isinstance(value, ZeroconfGetInfo):
63
+ self._DeviceInfo = value
64
+
65
+
66
+ def ToDictionary(self) -> dict:
67
+ """
68
+ Returns a dictionary representation of the class.
69
+ """
70
+ result:dict = \
71
+ {
72
+ 'DeviceInfo': self._DeviceInfo.ToDictionary(),
73
+ 'DiscoveryResult': self._DiscoveryResult.ToDictionary(),
74
+ }
75
+ return result
76
+
77
+
78
+ def ToString(self, includeTitle:bool=True) -> str:
79
+ """
80
+ Returns a displayable string representation of the class.
81
+
82
+ Args:
83
+ includeTitle (str):
84
+ True to include the class name title prefix.
85
+ """
86
+ msg:str = ''
87
+ if includeTitle:
88
+ msg = 'Device: "%s" (%s)' % (self._DiscoveryResult.DeviceName, self._DeviceInfo.DeviceId)
89
+
90
+ # build result.
91
+ msg = '%s\n %s\n' % (msg, str(self._DeviceInfo.ToString(True)))
92
+ msg = '%s\n %s\n' % (msg, str(self._DiscoveryResult.ToString(True)))
93
+ return msg
@@ -0,0 +1,137 @@
1
+ # external package imports.
2
+ from typing import Iterator
3
+
4
+ # our package imports.
5
+ from ..sautils import export
6
+ from .device import Device
7
+ from .spotifyconnectdevice import SpotifyConnectDevice
8
+ from spotifywebapipython.zeroconfapi import ZeroconfGetInfo, ZeroconfGetInfoAlias
9
+
10
+ @export
11
+ class SpotifyConnectDevices():
12
+ """
13
+ Spotify Connect Devices collection.
14
+ """
15
+
16
+ def __init__(self) -> None:
17
+ """
18
+ Initializes a new instance of the class.
19
+ """
20
+ self._Items:list[SpotifyConnectDevice] = []
21
+
22
+
23
+ def __getitem__(self, key) -> SpotifyConnectDevice:
24
+ return self._Presets[key]
25
+
26
+
27
+ def __iter__(self) -> Iterator:
28
+ return iter(self._Items)
29
+
30
+
31
+ def __len__(self) -> int:
32
+ return len(self._Items)
33
+
34
+
35
+ def __repr__(self) -> str:
36
+ return self.ToString()
37
+
38
+
39
+ def __str__(self) -> str:
40
+ return self.ToString()
41
+
42
+
43
+ @property
44
+ def Items(self) -> list[SpotifyConnectDevice]:
45
+ """
46
+ Array of `SpotifyConnectDevice` objects.
47
+ """
48
+ return self._Items
49
+
50
+
51
+ @property
52
+ def ItemsCount(self) -> int:
53
+ """
54
+ Number of objects in the `Items` property array.
55
+ """
56
+ if self._Items is not None:
57
+ return len(self._Items)
58
+ return 0
59
+
60
+
61
+ def GetDeviceList(self) -> list[Device]:
62
+ """
63
+ Returns a list of `Device` objects that can be used to build a selection list
64
+ of available devices.
65
+
66
+ Note that the `Device` object has the following properties populated:
67
+ Id, Name, IsActive, Type.
68
+ """
69
+ result:list[Device] = []
70
+
71
+ # process all discovered devices.
72
+ scDevice:SpotifyConnectDevice
73
+ for scDevice in self._Items:
74
+
75
+ # map device information details.
76
+ info:ZeroconfGetInfo = scDevice.DeviceInfo
77
+
78
+ # create new mock device.
79
+ device = Device()
80
+ device.IsActive = info.HasActiveUser
81
+ device.Type = info.DeviceType
82
+
83
+ # are aliases being used (RemoteName is null if so)?
84
+ if info.RemoteName is None:
85
+
86
+ # if aliases are defined, then use the alias details.
87
+ infoAlias:ZeroconfGetInfoAlias
88
+ for infoAlias in info.Aliases:
89
+ device.Id = infoAlias.Id
90
+ device.Name = infoAlias.Name
91
+
92
+ else:
93
+
94
+ # if no aliases then use the remote name and id.
95
+ device.Id = info.DeviceId
96
+ device.Name = info.RemoteName
97
+
98
+ # append device to results.
99
+ result.append(device)
100
+
101
+ # sort items on Name property, ascending order.
102
+ if len(result) > 0:
103
+ result.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
104
+
105
+ return result
106
+
107
+
108
+ def ToDictionary(self) -> dict:
109
+ """
110
+ Returns a dictionary representation of the class.
111
+ """
112
+ result:dict = \
113
+ {
114
+ 'ItemsCount': self.ItemsCount,
115
+ 'Items': [ item.ToDictionary() for item in self._Items ],
116
+ }
117
+
118
+ return result
119
+
120
+
121
+ def ToString(self, includeItems:bool=False) -> str:
122
+ """
123
+ Returns a displayable string representation of the class.
124
+
125
+ Args:
126
+ includeItems (bool):
127
+ True to include the Items collection of objects; otherwise, False
128
+ to only return base properties.
129
+ """
130
+ msg:str = 'Items Count=%s' % (str(self.ItemsCount))
131
+
132
+ if (includeItems):
133
+ item:SpotifyConnectDevice
134
+ for item in self._Items:
135
+ msg = "%s\n- %s" % (msg, item.ToString(True))
136
+
137
+ return msg
@@ -16,11 +16,6 @@ class ZeroconfDiscoveryResult:
16
16
  def __init__(self) -> None:
17
17
  """
18
18
  Initializes a new instance of the class.
19
-
20
- Args:
21
- root (dict):
22
- Spotify Web API JSON response in dictionary format, used to load object
23
- attributes; otherwise, None to not load attributes.
24
19
  """
25
20
  self._DeviceName:str = None
26
21
  self._Domain:str = '.'
@@ -7890,6 +7890,87 @@ class SpotifyClient:
7890
7890
  _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
7891
7891
 
7892
7892
 
7893
+ def GetSpotifyConnectDevices(
7894
+ self,
7895
+ ) -> SpotifyConnectDevices:
7896
+ """
7897
+ Get information about all available Spotify Connect player devices.
7898
+
7899
+ Returns:
7900
+ A `SpotifyConnectDevices` object that contain the discovery results
7901
+ as well as the `getInfo` result for each found device.
7902
+
7903
+ Raises:
7904
+ SpotifyWebApiError:
7905
+ If the Spotify Web API request was for a non-authorization service
7906
+ and the response contains error information.
7907
+ SpotifyZeroconfApiError:
7908
+ If the Spotify Zeroconf API request faild for any reason.
7909
+ SpotifApiError:
7910
+ If the method fails for any other reason.
7911
+
7912
+ This method is similar to the `GetPlayerDevices` method, but it contains ALL
7913
+ available Spotify Connect devices that are known to the local network (versus
7914
+ just the devices known to a specific user).
7915
+
7916
+ <details>
7917
+ <summary>Sample Code</summary>
7918
+ ```python
7919
+ .. include:: ../docs/include/samplecode/SpotifyClient/GetSpotifyConnectDevices.py
7920
+ ```
7921
+ </details>
7922
+ """
7923
+ apiMethodName:str = 'GetSpotifyConnectDevices'
7924
+ result:SpotifyConnectDevices = SpotifyConnectDevices()
7925
+
7926
+ try:
7927
+
7928
+ # trace.
7929
+ _logsi.EnterMethod(SILevel.Debug, apiMethodName)
7930
+ _logsi.LogVerbose("Get all available Spotify Connect devices")
7931
+
7932
+ # discover Spotify Connect devices on the network, waiting up to the specified timeout
7933
+ # for all devices to be discovered. this will return all Spotify Connect devices that
7934
+ # are currently powered on, and are registered to Zeroconf / mDNS.
7935
+ _logsi.LogVerbose("Discovering Spotify Connect devices on the local network")
7936
+ discovery:SpotifyDiscovery = SpotifyDiscovery(self._ZeroconfClient, printToConsole=False)
7937
+ discovery.DiscoverDevices(timeout=self._SpotifyConnectDiscoveryTimeout)
7938
+
7939
+ # process all discovered devices.
7940
+ discoverResult:ZeroconfDiscoveryResult
7941
+ for discoverResult in discovery.DiscoveryResults:
7942
+
7943
+ # get the id from the device via the zeroconf API getInfo endpoint, as the id is not
7944
+ # returned in the zeroconf discovery result.
7945
+ zconn:ZeroconfConnect = ZeroconfConnect(discoverResult.HostIpv4Address,
7946
+ discoverResult.HostIpPort,
7947
+ discoverResult.SpotifyConnectCPath,
7948
+ useSSL=False)
7949
+ info:ZeroconfGetInfo = zconn.GetInformation()
7950
+
7951
+ # create new spotify connect device object.
7952
+ scDevice:SpotifyConnectDevice = SpotifyConnectDevice()
7953
+ scDevice.DiscoveryResult = discoverResult
7954
+ scDevice.DeviceInfo = info
7955
+ result.Items.append(scDevice)
7956
+
7957
+ # trace.
7958
+ _logsi.LogArray(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result)
7959
+ return result
7960
+
7961
+ except SpotifyZeroconfApiError: raise # pass handled exceptions on thru
7962
+ except SpotifyApiError: raise # pass handled exceptions on thru
7963
+ except Exception as ex:
7964
+
7965
+ # format unhandled exception.
7966
+ raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
7967
+
7968
+ finally:
7969
+
7970
+ # trace.
7971
+ _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
7972
+
7973
+
7893
7974
  def GetTrack(self,
7894
7975
  trackId:str,
7895
7976
  ) -> Track: