spotifywebapiPython 1.0.26__py3-none-any.whl → 1.0.28__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.
- {spotifywebapiPython-1.0.26.dist-info → spotifywebapiPython-1.0.28.dist-info}/METADATA +1 -1
- {spotifywebapiPython-1.0.26.dist-info → spotifywebapiPython-1.0.28.dist-info}/RECORD +24 -24
- spotifywebapipython/const.py +26 -2
- spotifywebapipython/docs/__init__.html +27 -3
- spotifywebapipython/docs/index.html +2 -2
- spotifywebapipython/docs/search.js +1 -1
- spotifywebapipython/docs/spotifywebapiPython/const.html +75 -3
- spotifywebapipython/docs/spotifywebapiPython/saappmessages.html +4 -4
- spotifywebapipython/docs/spotifywebapiPython/sautils.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifyapierror.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifyapimessage.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifyauthtoken.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifyclient.html +2113 -331
- spotifywebapipython/docs/spotifywebapiPython/spotifydiscovery.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifywebapiauthenticationerror.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifywebapierror.html +2 -2
- spotifywebapipython/models/category.py +11 -0
- spotifywebapipython/models/pageobject.py +77 -4
- spotifywebapipython/models/searchresponse.py +86 -50
- spotifywebapipython/saappmessages.py +3 -3
- spotifywebapipython/spotifyclient.py +2938 -364
- {spotifywebapiPython-1.0.26.dist-info → spotifywebapiPython-1.0.28.dist-info}/LICENSE +0 -0
- {spotifywebapiPython-1.0.26.dist-info → spotifywebapiPython-1.0.28.dist-info}/WHEEL +0 -0
- {spotifywebapiPython-1.0.26.dist-info → spotifywebapiPython-1.0.28.dist-info}/top_level.txt +0 -0
|
@@ -3,7 +3,6 @@ import base64
|
|
|
3
3
|
import json
|
|
4
4
|
from io import BytesIO
|
|
5
5
|
from oauthlib.oauth2 import BackendApplicationClient, WebApplicationClient
|
|
6
|
-
#from requests import Response
|
|
7
6
|
from typing import Tuple, Callable
|
|
8
7
|
from urllib3 import PoolManager, Timeout, HTTPResponse
|
|
9
8
|
from urllib.parse import urlencode
|
|
@@ -12,7 +11,7 @@ from urllib.parse import urlencode
|
|
|
12
11
|
from .oauthcli import AuthClient
|
|
13
12
|
from .models import *
|
|
14
13
|
from .models import UserProfile as UserProfileCurrentUser
|
|
15
|
-
from .sautils import export
|
|
14
|
+
from .sautils import export, GetUnixTimestampMSFromUtcNow
|
|
16
15
|
from .saappmessages import SAAppMessages
|
|
17
16
|
from .spotifyapierror import SpotifyApiError
|
|
18
17
|
from .spotifyapimessage import SpotifyApiMessage
|
|
@@ -22,12 +21,16 @@ from .spotifywebapierror import SpotifyWebApiError
|
|
|
22
21
|
from .const import (
|
|
23
22
|
SPOTIFY_API_AUTHORIZE_URL,
|
|
24
23
|
SPOTIFY_API_TOKEN_URL,
|
|
24
|
+
SPOTIFY_DEFAULT_MARKET,
|
|
25
25
|
SPOTIFY_WEBAPI_URL_BASE,
|
|
26
26
|
TRACE_METHOD_RESULT,
|
|
27
27
|
TRACE_METHOD_RESULT_TYPE,
|
|
28
28
|
TRACE_METHOD_RESULT_TYPE_CACHED,
|
|
29
|
+
TRACE_METHOD_RESULT_TYPE_PAGE,
|
|
29
30
|
TRACE_MSG_AUTHTOKEN_CREATE,
|
|
31
|
+
TRACE_MSG_AUTOPAGING_NEXT,
|
|
30
32
|
TRACE_MSG_USERPROFILE,
|
|
33
|
+
TRACE_WARN_SPOTIFY_SEARCH_NO_MARKET,
|
|
31
34
|
)
|
|
32
35
|
|
|
33
36
|
CACHE_SOURCE_CACHED:str = "cached"
|
|
@@ -231,6 +234,51 @@ class SpotifyClient:
|
|
|
231
234
|
return self._UserProfile
|
|
232
235
|
|
|
233
236
|
|
|
237
|
+
def _CheckForNextPage(self,
|
|
238
|
+
pageObj:PageObject,
|
|
239
|
+
resultItemsCount,
|
|
240
|
+
limit:int,
|
|
241
|
+
limitTotal:int,
|
|
242
|
+
urlParms:dict,
|
|
243
|
+
) -> bool:
|
|
244
|
+
"""
|
|
245
|
+
Modifies paging object and urlParms to point to the next page of data, if one
|
|
246
|
+
can be accessed.
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
False if there are no more pages to process;
|
|
250
|
+
otherwise, True to safely process the next page of results.
|
|
251
|
+
"""
|
|
252
|
+
# anymore page results?
|
|
253
|
+
if (pageObj.Next is None) or (resultItemsCount >= limitTotal) or (pageObj.Offset >= limitTotal):
|
|
254
|
+
# no - all pages were processed, or limit total reached.
|
|
255
|
+
return False
|
|
256
|
+
else:
|
|
257
|
+
# yes - prepare to retrieve the next page of results.
|
|
258
|
+
# if next page potential item count exceeds limit total, then limit to the difference.
|
|
259
|
+
pageObj.Offset = pageObj.Offset + pageObj.Limit
|
|
260
|
+
if (pageObj.Offset + pageObj.Limit) > limitTotal:
|
|
261
|
+
pageObj.Limit = limitTotal - pageObj.Offset
|
|
262
|
+
|
|
263
|
+
# the following can occur if the Spotify Web API does not return any items but has
|
|
264
|
+
# the 'next' value set to point to the next page of data. I noticed this happens
|
|
265
|
+
# when the API cannot resolve a market (or country code) value (e.g. the UserProfile
|
|
266
|
+
# Country property is not set and no market argument was supplied). Regardless, we
|
|
267
|
+
# will check for it here in case.
|
|
268
|
+
if pageObj.Limit <= 0:
|
|
269
|
+
pageObj.Limit = limit
|
|
270
|
+
|
|
271
|
+
# modify paging-related request parameters for next page of items.
|
|
272
|
+
urlParms['limit'] = pageObj.Limit
|
|
273
|
+
urlParms['offset'] = pageObj.Offset
|
|
274
|
+
|
|
275
|
+
# trace.
|
|
276
|
+
_logsi.LogVerbose(TRACE_MSG_AUTOPAGING_NEXT % pageObj.PagingInfo)
|
|
277
|
+
|
|
278
|
+
# indicate next page can be processed.
|
|
279
|
+
return True
|
|
280
|
+
|
|
281
|
+
|
|
234
282
|
def _CheckResponseForErrors(self, msg:SpotifyApiMessage, response:HTTPResponse) -> None:
|
|
235
283
|
"""
|
|
236
284
|
Checks the Spotify Web API response for errors.
|
|
@@ -397,6 +445,35 @@ class SpotifyClient:
|
|
|
397
445
|
msg.ResponseData = responseData
|
|
398
446
|
|
|
399
447
|
|
|
448
|
+
def _ValidateMarket(self,
|
|
449
|
+
market:str,
|
|
450
|
+
) -> str:
|
|
451
|
+
"""
|
|
452
|
+
Validates that a market (aka country code) value has either been supplied, or exists
|
|
453
|
+
in the UserProfile.Country value and returns a value of 'US' if not supplied; otherwise,
|
|
454
|
+
the market aregument value is returned.
|
|
455
|
+
|
|
456
|
+
If a market argument was not specified and the user profile does not have a country code
|
|
457
|
+
set, then it causes the Spotify Web API search to return odd results. For example, the
|
|
458
|
+
items collection will return no items, but the `total` and `next` values are populated
|
|
459
|
+
like there are more results. It's almost like it found the results, but it won't return
|
|
460
|
+
the actual items due to market / country restrictions or something.
|
|
461
|
+
"""
|
|
462
|
+
# if user profile contains a country value then spotify web api will use it if no
|
|
463
|
+
# market argument was supplied.
|
|
464
|
+
if (self.UserProfile.Country is not None):
|
|
465
|
+
return market
|
|
466
|
+
|
|
467
|
+
# if a non-null and non-empty string was supplied then assume it's a valid market.
|
|
468
|
+
# we will let the Spotify Web API tell us if it's not a valid code.
|
|
469
|
+
if (market is not None and len(market.strip()) > 0):
|
|
470
|
+
return market
|
|
471
|
+
|
|
472
|
+
# otherwise, defult the value.
|
|
473
|
+
_logsi.LogVerbose("A market value was not supplied for the request, and the user profile did not contain a country code value (e.g. public access token is in effect). Defaulting value to '%s'." % SPOTIFY_DEFAULT_MARKET)
|
|
474
|
+
return SPOTIFY_DEFAULT_MARKET
|
|
475
|
+
|
|
476
|
+
|
|
400
477
|
def MakeRequest(self, method:str, msg:SpotifyApiMessage) -> int:
|
|
401
478
|
"""
|
|
402
479
|
Performs a generic Spotify Web API request.
|
|
@@ -2117,6 +2194,9 @@ class SpotifyClient:
|
|
|
2117
2194
|
apiMethodParms.AppendKeyValue("market", market)
|
|
2118
2195
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for a single album", apiMethodParms)
|
|
2119
2196
|
|
|
2197
|
+
# ensure market was either supplied or implied; default if neither.
|
|
2198
|
+
market = self._ValidateMarket(market)
|
|
2199
|
+
|
|
2120
2200
|
# build spotify web api request parameters.
|
|
2121
2201
|
urlParms:dict = {}
|
|
2122
2202
|
if market is not None:
|
|
@@ -2152,6 +2232,7 @@ class SpotifyClient:
|
|
|
2152
2232
|
limit:int=20,
|
|
2153
2233
|
offset:int=0,
|
|
2154
2234
|
market:str=None,
|
|
2235
|
+
limitTotal:int=None
|
|
2155
2236
|
) -> AlbumPageSaved:
|
|
2156
2237
|
"""
|
|
2157
2238
|
Get a list of the albums saved in the current Spotify user's 'Your Library'.
|
|
@@ -2160,10 +2241,10 @@ class SpotifyClient:
|
|
|
2160
2241
|
|
|
2161
2242
|
Args:
|
|
2162
2243
|
limit (int):
|
|
2163
|
-
The maximum number of items to return.
|
|
2244
|
+
The maximum number of items to return in a page of items.
|
|
2164
2245
|
Default: 20, Range: 1 to 50.
|
|
2165
2246
|
offset (int):
|
|
2166
|
-
The index of the first item to return.
|
|
2247
|
+
The page index offset of the first item to return.
|
|
2167
2248
|
Use with limit to get the next set of items.
|
|
2168
2249
|
Default: 0 (the first item).
|
|
2169
2250
|
market (str):
|
|
@@ -2174,6 +2255,12 @@ class SpotifyClient:
|
|
|
2174
2255
|
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
2175
2256
|
Users can view the country that is associated with their account in the account settings.
|
|
2176
2257
|
Example: `ES`
|
|
2258
|
+
limitTotal (int):
|
|
2259
|
+
The maximum number of items to return for the request.
|
|
2260
|
+
If specified, this argument overrides the limit and offset argument values
|
|
2261
|
+
and paging is automatically used to retrieve all available items up to the
|
|
2262
|
+
maximum number specified.
|
|
2263
|
+
Default: None (disabled)
|
|
2177
2264
|
|
|
2178
2265
|
Returns:
|
|
2179
2266
|
An `AlbumPageSaved` object that contains saved album information.
|
|
@@ -2186,11 +2273,17 @@ class SpotifyClient:
|
|
|
2186
2273
|
If the method fails for any other reason.
|
|
2187
2274
|
|
|
2188
2275
|
<details>
|
|
2189
|
-
<summary>Sample Code</summary>
|
|
2276
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
2190
2277
|
```python
|
|
2191
2278
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetAlbumFavorites.py
|
|
2192
2279
|
```
|
|
2193
2280
|
</details>
|
|
2281
|
+
<details>
|
|
2282
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
2283
|
+
```python
|
|
2284
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetAlbumFavorites_AutoPaging.py
|
|
2285
|
+
```
|
|
2286
|
+
</details>
|
|
2194
2287
|
"""
|
|
2195
2288
|
apiMethodName:str = 'GetAlbumFavorites'
|
|
2196
2289
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -2202,6 +2295,8 @@ class SpotifyClient:
|
|
|
2202
2295
|
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
2203
2296
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
2204
2297
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
2298
|
+
apiMethodParms.AppendKeyValue("market", market)
|
|
2299
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
2205
2300
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the user's album favorites", apiMethodParms)
|
|
2206
2301
|
|
|
2207
2302
|
# validations.
|
|
@@ -2209,6 +2304,19 @@ class SpotifyClient:
|
|
|
2209
2304
|
limit = 20
|
|
2210
2305
|
if offset is None:
|
|
2211
2306
|
offset = 0
|
|
2307
|
+
if not isinstance(limitTotal, int):
|
|
2308
|
+
limitTotal = 0
|
|
2309
|
+
|
|
2310
|
+
# are we auto-paging? if so, then use max limit.
|
|
2311
|
+
if limitTotal > 0:
|
|
2312
|
+
limit = 50
|
|
2313
|
+
#limit = 2 # TEST TODO
|
|
2314
|
+
if limit > limitTotal:
|
|
2315
|
+
limit = limitTotal
|
|
2316
|
+
result = AlbumPageSaved()
|
|
2317
|
+
|
|
2318
|
+
# ensure market was either supplied or implied; default if neither.
|
|
2319
|
+
market = self._ValidateMarket(market)
|
|
2212
2320
|
|
|
2213
2321
|
# build spotify web api request parameters.
|
|
2214
2322
|
urlParms:dict = \
|
|
@@ -2219,15 +2327,49 @@ class SpotifyClient:
|
|
|
2219
2327
|
if market is not None:
|
|
2220
2328
|
urlParms['market'] = market
|
|
2221
2329
|
|
|
2222
|
-
#
|
|
2223
|
-
|
|
2224
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
2225
|
-
msg.UrlParameters = urlParms
|
|
2226
|
-
self.MakeRequest('GET', msg)
|
|
2330
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
2331
|
+
while True:
|
|
2227
2332
|
|
|
2228
|
-
|
|
2229
|
-
|
|
2333
|
+
# execute spotify web api request.
|
|
2334
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/albums')
|
|
2335
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
2336
|
+
msg.UrlParameters = urlParms
|
|
2337
|
+
self.MakeRequest('GET', msg)
|
|
2338
|
+
|
|
2339
|
+
# process results.
|
|
2340
|
+
pageObj = AlbumPageSaved(root=msg.ResponseData)
|
|
2230
2341
|
|
|
2342
|
+
# trace.
|
|
2343
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
2344
|
+
|
|
2345
|
+
# was limit total argument specified?
|
|
2346
|
+
if (limitTotal <= 0):
|
|
2347
|
+
|
|
2348
|
+
# no - just return the initial page of results.
|
|
2349
|
+
result = pageObj
|
|
2350
|
+
break
|
|
2351
|
+
|
|
2352
|
+
else:
|
|
2353
|
+
|
|
2354
|
+
# append page of items to final results.
|
|
2355
|
+
item:AlbumSaved
|
|
2356
|
+
for item in pageObj.Items:
|
|
2357
|
+
result.Items.append(item)
|
|
2358
|
+
result.Limit = result.ItemsCount
|
|
2359
|
+
if result.ItemsCount >= limitTotal:
|
|
2360
|
+
break
|
|
2361
|
+
|
|
2362
|
+
# anymore pages to process? if not, then exit the loop.
|
|
2363
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
2364
|
+
break
|
|
2365
|
+
|
|
2366
|
+
# update result object with final paging details.
|
|
2367
|
+
result.Total = pageObj.Total
|
|
2368
|
+
|
|
2369
|
+
# sort items on Name property, ascending order.
|
|
2370
|
+
if len(result.Items) > 0:
|
|
2371
|
+
result.Items.sort(key=lambda x: (x.Album.Name or "").lower(), reverse=False)
|
|
2372
|
+
|
|
2231
2373
|
# trace.
|
|
2232
2374
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
2233
2375
|
return result
|
|
@@ -2249,6 +2391,7 @@ class SpotifyClient:
|
|
|
2249
2391
|
limit:int=20,
|
|
2250
2392
|
offset:int=0,
|
|
2251
2393
|
country:str=None,
|
|
2394
|
+
limitTotal:int=None
|
|
2252
2395
|
) -> AlbumPageSimplified:
|
|
2253
2396
|
"""
|
|
2254
2397
|
Get a list of new album releases featured in Spotify (shown, for example, on a
|
|
@@ -2256,10 +2399,10 @@ class SpotifyClient:
|
|
|
2256
2399
|
|
|
2257
2400
|
Args:
|
|
2258
2401
|
limit (int):
|
|
2259
|
-
The maximum number of items to return.
|
|
2402
|
+
The maximum number of items to return in a page of items.
|
|
2260
2403
|
Default: 20, Range: 1 to 50.
|
|
2261
2404
|
offset (int):
|
|
2262
|
-
The index of the first item to return.
|
|
2405
|
+
The page index offset of the first item to return.
|
|
2263
2406
|
Use with limit to get the next set of items.
|
|
2264
2407
|
Default: 0 (the first item).
|
|
2265
2408
|
country (str):
|
|
@@ -2267,6 +2410,12 @@ class SpotifyClient:
|
|
|
2267
2410
|
Provide this parameter if you want the list of returned items to be relevant to a
|
|
2268
2411
|
particular country. If omitted, the returned items will be relevant to all countries.
|
|
2269
2412
|
Example: `SE`
|
|
2413
|
+
limitTotal (int):
|
|
2414
|
+
The maximum number of items to return for the request.
|
|
2415
|
+
If specified, this argument overrides the limit and offset argument values
|
|
2416
|
+
and paging is automatically used to retrieve all available items up to the
|
|
2417
|
+
maximum number specified.
|
|
2418
|
+
Default: None (disabled)
|
|
2270
2419
|
|
|
2271
2420
|
Returns:
|
|
2272
2421
|
An `AlbumPageSimplified` object that contains simplified album information.
|
|
@@ -2279,11 +2428,17 @@ class SpotifyClient:
|
|
|
2279
2428
|
If the method fails for any other reason.
|
|
2280
2429
|
|
|
2281
2430
|
<details>
|
|
2282
|
-
<summary>Sample Code</summary>
|
|
2431
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
2283
2432
|
```python
|
|
2284
2433
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetAlbumNewReleases.py
|
|
2285
2434
|
```
|
|
2286
2435
|
</details>
|
|
2436
|
+
<details>
|
|
2437
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
2438
|
+
```python
|
|
2439
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetAlbumNewReleases_AutoPaging.py
|
|
2440
|
+
```
|
|
2441
|
+
</details>
|
|
2287
2442
|
"""
|
|
2288
2443
|
apiMethodName:str = 'GetAlbumNewReleases'
|
|
2289
2444
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -2296,6 +2451,7 @@ class SpotifyClient:
|
|
|
2296
2451
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
2297
2452
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
2298
2453
|
apiMethodParms.AppendKeyValue("country", country)
|
|
2454
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
2299
2455
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of new album releases", apiMethodParms)
|
|
2300
2456
|
|
|
2301
2457
|
# validations.
|
|
@@ -2303,6 +2459,16 @@ class SpotifyClient:
|
|
|
2303
2459
|
limit = 20
|
|
2304
2460
|
if offset is None:
|
|
2305
2461
|
offset = 0
|
|
2462
|
+
if not isinstance(limitTotal, int):
|
|
2463
|
+
limitTotal = 0
|
|
2464
|
+
|
|
2465
|
+
# are we auto-paging? if so, then use max limit.
|
|
2466
|
+
if limitTotal > 0:
|
|
2467
|
+
limit = 50
|
|
2468
|
+
#limit = 2 # TEST TODO
|
|
2469
|
+
if limit > limitTotal:
|
|
2470
|
+
limit = limitTotal
|
|
2471
|
+
result = AlbumPageSimplified()
|
|
2306
2472
|
|
|
2307
2473
|
# build spotify web api request parameters.
|
|
2308
2474
|
urlParms:dict = \
|
|
@@ -2313,16 +2479,50 @@ class SpotifyClient:
|
|
|
2313
2479
|
if country is not None:
|
|
2314
2480
|
urlParms['country'] = country
|
|
2315
2481
|
|
|
2316
|
-
#
|
|
2317
|
-
|
|
2318
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
2319
|
-
msg.UrlParameters = urlParms
|
|
2320
|
-
self.MakeRequest('GET', msg)
|
|
2482
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
2483
|
+
while True:
|
|
2321
2484
|
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2485
|
+
# execute spotify web api request.
|
|
2486
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/browse/new-releases')
|
|
2487
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
2488
|
+
msg.UrlParameters = urlParms
|
|
2489
|
+
self.MakeRequest('GET', msg)
|
|
2490
|
+
|
|
2491
|
+
# process results.
|
|
2492
|
+
item:dict = msg.ResponseData.get('albums', None)
|
|
2493
|
+
if item is not None:
|
|
2494
|
+
pageObj = AlbumPageSimplified(root=item)
|
|
2495
|
+
|
|
2496
|
+
# trace.
|
|
2497
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
2498
|
+
|
|
2499
|
+
# was limit total argument specified?
|
|
2500
|
+
if (limitTotal <= 0):
|
|
2501
|
+
|
|
2502
|
+
# no - just return the initial page of results.
|
|
2503
|
+
result = pageObj
|
|
2504
|
+
break
|
|
2505
|
+
|
|
2506
|
+
else:
|
|
2507
|
+
|
|
2508
|
+
# append page of items to final results.
|
|
2509
|
+
item:AlbumSimplified
|
|
2510
|
+
for item in pageObj.Items:
|
|
2511
|
+
result.Items.append(item)
|
|
2512
|
+
result.Limit = result.ItemsCount
|
|
2513
|
+
if result.ItemsCount >= limitTotal:
|
|
2514
|
+
break
|
|
2515
|
+
|
|
2516
|
+
# anymore pages to process? if not, then exit the loop.
|
|
2517
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
2518
|
+
break
|
|
2519
|
+
|
|
2520
|
+
# update result object with final paging details.
|
|
2521
|
+
result.Total = pageObj.Total
|
|
2522
|
+
|
|
2523
|
+
# sort items on Name property, ascending order.
|
|
2524
|
+
if len(result.Items) > 0:
|
|
2525
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
2326
2526
|
|
|
2327
2527
|
# trace.
|
|
2328
2528
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -2391,6 +2591,9 @@ class SpotifyClient:
|
|
|
2391
2591
|
apiMethodParms.AppendKeyValue("market", market)
|
|
2392
2592
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for multiple albums", apiMethodParms)
|
|
2393
2593
|
|
|
2594
|
+
# ensure market was either supplied or implied; default if neither.
|
|
2595
|
+
market = self._ValidateMarket(market)
|
|
2596
|
+
|
|
2394
2597
|
# build spotify web api request parameters.
|
|
2395
2598
|
urlParms:dict = \
|
|
2396
2599
|
{
|
|
@@ -2432,6 +2635,7 @@ class SpotifyClient:
|
|
|
2432
2635
|
limit:int=20,
|
|
2433
2636
|
offset:int=0,
|
|
2434
2637
|
market:str=None,
|
|
2638
|
+
limitTotal:int=None
|
|
2435
2639
|
) -> TrackPageSimplified:
|
|
2436
2640
|
"""
|
|
2437
2641
|
Get Spotify catalog information about an album's tracks.
|
|
@@ -2443,7 +2647,7 @@ class SpotifyClient:
|
|
|
2443
2647
|
The Spotify ID of the album.
|
|
2444
2648
|
Example: `6vc9OTcyd3hyzabCmsdnwE`
|
|
2445
2649
|
limit (int):
|
|
2446
|
-
The maximum number of items to return.
|
|
2650
|
+
The maximum number of items to return in a page of items.
|
|
2447
2651
|
Default: 20, Range: 1 to 50.
|
|
2448
2652
|
offset (int):
|
|
2449
2653
|
The index of the first item to return; use with limit to get the next set of items.
|
|
@@ -2456,6 +2660,12 @@ class SpotifyClient:
|
|
|
2456
2660
|
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
2457
2661
|
Users can view the country that is associated with their account in the account settings.
|
|
2458
2662
|
Example: `ES`
|
|
2663
|
+
limitTotal (int):
|
|
2664
|
+
The maximum number of items to return for the request.
|
|
2665
|
+
If specified, this argument overrides the limit and offset argument values
|
|
2666
|
+
and paging is automatically used to retrieve all available items up to the
|
|
2667
|
+
maximum number specified.
|
|
2668
|
+
Default: None (disabled)
|
|
2459
2669
|
|
|
2460
2670
|
Returns:
|
|
2461
2671
|
A `TrackPageSimplified` object that contains simplified track information for the albumId.
|
|
@@ -2468,11 +2678,17 @@ class SpotifyClient:
|
|
|
2468
2678
|
If the method fails for any other reason.
|
|
2469
2679
|
|
|
2470
2680
|
<details>
|
|
2471
|
-
<summary>Sample Code</summary>
|
|
2681
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
2472
2682
|
```python
|
|
2473
2683
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetAlbumTracks.py
|
|
2474
2684
|
```
|
|
2475
2685
|
</details>
|
|
2686
|
+
<details>
|
|
2687
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
2688
|
+
```python
|
|
2689
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetAlbumTracks_AutoPaging.py
|
|
2690
|
+
```
|
|
2691
|
+
</details>
|
|
2476
2692
|
"""
|
|
2477
2693
|
apiMethodName:str = 'GetAlbumTracks'
|
|
2478
2694
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -2486,6 +2702,7 @@ class SpotifyClient:
|
|
|
2486
2702
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
2487
2703
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
2488
2704
|
apiMethodParms.AppendKeyValue("market", market)
|
|
2705
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
2489
2706
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information about an album's tracks", apiMethodParms)
|
|
2490
2707
|
|
|
2491
2708
|
# validations.
|
|
@@ -2493,6 +2710,19 @@ class SpotifyClient:
|
|
|
2493
2710
|
limit = 20
|
|
2494
2711
|
if offset is None:
|
|
2495
2712
|
offset = 0
|
|
2713
|
+
if not isinstance(limitTotal, int):
|
|
2714
|
+
limitTotal = 0
|
|
2715
|
+
|
|
2716
|
+
# are we auto-paging? if so, then use max limit.
|
|
2717
|
+
if limitTotal > 0:
|
|
2718
|
+
limit = 50
|
|
2719
|
+
#limit = 2 # TEST TODO
|
|
2720
|
+
if limit > limitTotal:
|
|
2721
|
+
limit = limitTotal
|
|
2722
|
+
result = TrackPageSimplified()
|
|
2723
|
+
|
|
2724
|
+
# ensure market was either supplied or implied; default if neither.
|
|
2725
|
+
market = self._ValidateMarket(market)
|
|
2496
2726
|
|
|
2497
2727
|
# build spotify web api request parameters.
|
|
2498
2728
|
urlParms:dict = \
|
|
@@ -2503,14 +2733,46 @@ class SpotifyClient:
|
|
|
2503
2733
|
if market is not None:
|
|
2504
2734
|
urlParms['market'] = market
|
|
2505
2735
|
|
|
2506
|
-
#
|
|
2507
|
-
|
|
2508
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
2509
|
-
msg.UrlParameters = urlParms
|
|
2510
|
-
self.MakeRequest('GET', msg)
|
|
2736
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
2737
|
+
while True:
|
|
2511
2738
|
|
|
2512
|
-
|
|
2513
|
-
|
|
2739
|
+
# execute spotify web api request.
|
|
2740
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/albums/{id}/tracks'.format(id=albumId))
|
|
2741
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
2742
|
+
msg.UrlParameters = urlParms
|
|
2743
|
+
self.MakeRequest('GET', msg)
|
|
2744
|
+
|
|
2745
|
+
# process results.
|
|
2746
|
+
pageObj = TrackPageSimplified(root=msg.ResponseData)
|
|
2747
|
+
|
|
2748
|
+
# trace.
|
|
2749
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
2750
|
+
|
|
2751
|
+
# was limit total argument specified?
|
|
2752
|
+
if (limitTotal <= 0):
|
|
2753
|
+
|
|
2754
|
+
# no - just return the initial page of results.
|
|
2755
|
+
result = pageObj
|
|
2756
|
+
break
|
|
2757
|
+
|
|
2758
|
+
else:
|
|
2759
|
+
|
|
2760
|
+
# append page of items to final results.
|
|
2761
|
+
item:TrackSimplified
|
|
2762
|
+
for item in pageObj.Items:
|
|
2763
|
+
result.Items.append(item)
|
|
2764
|
+
result.Limit = result.ItemsCount
|
|
2765
|
+
if result.ItemsCount >= limitTotal:
|
|
2766
|
+
break
|
|
2767
|
+
|
|
2768
|
+
# anymore pages to process? if not, then exit the loop.
|
|
2769
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
2770
|
+
break
|
|
2771
|
+
|
|
2772
|
+
# update result object with final paging details.
|
|
2773
|
+
result.Total = pageObj.Total
|
|
2774
|
+
|
|
2775
|
+
# do not sort items, as they are in playable order.
|
|
2514
2776
|
|
|
2515
2777
|
# trace.
|
|
2516
2778
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -2538,7 +2800,7 @@ class SpotifyClient:
|
|
|
2538
2800
|
Args:
|
|
2539
2801
|
artistId (str):
|
|
2540
2802
|
The Spotify ID of the artist.
|
|
2541
|
-
Example: `
|
|
2803
|
+
Example: `6APm8EjxOHSYM5B4i3vT3q`
|
|
2542
2804
|
|
|
2543
2805
|
Returns:
|
|
2544
2806
|
An `Artist` object that contains the artist details.
|
|
@@ -2598,22 +2860,23 @@ class SpotifyClient:
|
|
|
2598
2860
|
include_groups:str='album',
|
|
2599
2861
|
limit:int=20,
|
|
2600
2862
|
offset:int=0,
|
|
2601
|
-
market:str=None
|
|
2602
|
-
|
|
2863
|
+
market:str=None,
|
|
2864
|
+
limitTotal:int=None
|
|
2865
|
+
) -> AlbumPageSimplified:
|
|
2603
2866
|
"""
|
|
2604
2867
|
Get Spotify catalog information about an artist's albums.
|
|
2605
2868
|
|
|
2606
2869
|
Args:
|
|
2607
2870
|
artistId (str):
|
|
2608
2871
|
The Spotify ID of the artist.
|
|
2609
|
-
Example: `
|
|
2872
|
+
Example: `6APm8EjxOHSYM5B4i3vT3q`
|
|
2610
2873
|
include_groups (str):
|
|
2611
2874
|
A comma-separated list of keywords that will be used to filter the response.
|
|
2612
2875
|
If not supplied, all album types will be returned.
|
|
2613
2876
|
Valid values are: `album`, `single`, `appears_on`, `compilation`
|
|
2614
2877
|
Example: `single,appears_on`
|
|
2615
2878
|
limit (int):
|
|
2616
|
-
The maximum number of items to return.
|
|
2879
|
+
The maximum number of items to return in a page of items.
|
|
2617
2880
|
Default: 20, Range: 1 to 50.
|
|
2618
2881
|
offset (int):
|
|
2619
2882
|
The index of the first item to return; use with limit to get the next set of items.
|
|
@@ -2626,9 +2889,15 @@ class SpotifyClient:
|
|
|
2626
2889
|
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
2627
2890
|
Users can view the country that is associated with their account in the account settings.
|
|
2628
2891
|
Example: `ES`
|
|
2892
|
+
limitTotal (int):
|
|
2893
|
+
The maximum number of items to return for the request.
|
|
2894
|
+
If specified, this argument overrides the limit and offset argument values
|
|
2895
|
+
and paging is automatically used to retrieve all available items up to the
|
|
2896
|
+
maximum number specified.
|
|
2897
|
+
Default: None (disabled)
|
|
2629
2898
|
|
|
2630
2899
|
Returns:
|
|
2631
|
-
|
|
2900
|
+
An `AlbumPageSimplified` object of matching results.
|
|
2632
2901
|
|
|
2633
2902
|
Raises:
|
|
2634
2903
|
SpotifyWebApiError:
|
|
@@ -2638,11 +2907,17 @@ class SpotifyClient:
|
|
|
2638
2907
|
If the method fails for any other reason.
|
|
2639
2908
|
|
|
2640
2909
|
<details>
|
|
2641
|
-
<summary>Sample Code</summary>
|
|
2910
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
2642
2911
|
```python
|
|
2643
2912
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetArtistAlbums.py
|
|
2644
2913
|
```
|
|
2645
2914
|
</details>
|
|
2915
|
+
<details>
|
|
2916
|
+
<summary>Sample Code - auto Paging</summary>
|
|
2917
|
+
```python
|
|
2918
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetArtistAlbums_AutoPaging.py
|
|
2919
|
+
```
|
|
2920
|
+
</details>
|
|
2646
2921
|
"""
|
|
2647
2922
|
apiMethodName:str = 'GetArtistAlbums'
|
|
2648
2923
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -2657,6 +2932,7 @@ class SpotifyClient:
|
|
|
2657
2932
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
2658
2933
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
2659
2934
|
apiMethodParms.AppendKeyValue("market", market)
|
|
2935
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
2660
2936
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information about an artist's albums", apiMethodParms)
|
|
2661
2937
|
|
|
2662
2938
|
# validations.
|
|
@@ -2664,6 +2940,19 @@ class SpotifyClient:
|
|
|
2664
2940
|
limit = 20
|
|
2665
2941
|
if offset is None:
|
|
2666
2942
|
offset = 0
|
|
2943
|
+
if not isinstance(limitTotal, int):
|
|
2944
|
+
limitTotal = 0
|
|
2945
|
+
|
|
2946
|
+
# are we auto-paging? if so, then use max limit.
|
|
2947
|
+
if limitTotal > 0:
|
|
2948
|
+
limit = 50
|
|
2949
|
+
#limit = 5 # TEST TODO
|
|
2950
|
+
if limit > limitTotal:
|
|
2951
|
+
limit = limitTotal
|
|
2952
|
+
result = AlbumPageSimplified()
|
|
2953
|
+
|
|
2954
|
+
# ensure market was either supplied or implied; default if neither.
|
|
2955
|
+
market = self._ValidateMarket(market)
|
|
2667
2956
|
|
|
2668
2957
|
# build spotify web api request parameters.
|
|
2669
2958
|
urlParms:dict = \
|
|
@@ -2675,14 +2964,48 @@ class SpotifyClient:
|
|
|
2675
2964
|
if market is not None:
|
|
2676
2965
|
urlParms['market'] = market
|
|
2677
2966
|
|
|
2678
|
-
#
|
|
2679
|
-
|
|
2680
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
2681
|
-
msg.UrlParameters = urlParms
|
|
2682
|
-
self.MakeRequest('GET', msg)
|
|
2967
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
2968
|
+
while True:
|
|
2683
2969
|
|
|
2684
|
-
|
|
2685
|
-
|
|
2970
|
+
# execute spotify web api request.
|
|
2971
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/artists/{id}/albums'.format(id=artistId))
|
|
2972
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
2973
|
+
msg.UrlParameters = urlParms
|
|
2974
|
+
self.MakeRequest('GET', msg)
|
|
2975
|
+
|
|
2976
|
+
# process results.
|
|
2977
|
+
pageObj = AlbumPageSimplified(root=msg.ResponseData)
|
|
2978
|
+
|
|
2979
|
+
# trace.
|
|
2980
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
2981
|
+
|
|
2982
|
+
# was limit total argument specified?
|
|
2983
|
+
if (limitTotal <= 0):
|
|
2984
|
+
|
|
2985
|
+
# no - just return the initial page of results.
|
|
2986
|
+
result = pageObj
|
|
2987
|
+
break
|
|
2988
|
+
|
|
2989
|
+
else:
|
|
2990
|
+
|
|
2991
|
+
# append page of items to final results.
|
|
2992
|
+
item:AlbumSimplified
|
|
2993
|
+
for item in pageObj.Items:
|
|
2994
|
+
result.Items.append(item)
|
|
2995
|
+
result.Limit = result.ItemsCount
|
|
2996
|
+
if result.ItemsCount >= limitTotal:
|
|
2997
|
+
break
|
|
2998
|
+
|
|
2999
|
+
# anymore pages to process? if not, then exit the loop.
|
|
3000
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
3001
|
+
break
|
|
3002
|
+
|
|
3003
|
+
# update result object with final paging details.
|
|
3004
|
+
result.Total = pageObj.Total
|
|
3005
|
+
|
|
3006
|
+
# sort items on Name property, ascending order.
|
|
3007
|
+
if len(result.Items) > 0:
|
|
3008
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
2686
3009
|
|
|
2687
3010
|
# trace.
|
|
2688
3011
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -2711,7 +3034,7 @@ class SpotifyClient:
|
|
|
2711
3034
|
Args:
|
|
2712
3035
|
artistId (str):
|
|
2713
3036
|
The Spotify ID of the artist.
|
|
2714
|
-
Example: `
|
|
3037
|
+
Example: `6APm8EjxOHSYM5B4i3vT3q`
|
|
2715
3038
|
|
|
2716
3039
|
Returns:
|
|
2717
3040
|
A list of `Artist` objects that contain the artist details.
|
|
@@ -2845,6 +3168,7 @@ class SpotifyClient:
|
|
|
2845
3168
|
def GetArtistsFollowed(self,
|
|
2846
3169
|
after:str=None,
|
|
2847
3170
|
limit:int=20,
|
|
3171
|
+
limitTotal:int=None
|
|
2848
3172
|
) -> ArtistPage:
|
|
2849
3173
|
"""
|
|
2850
3174
|
Get the current user's followed artists.
|
|
@@ -2853,10 +3177,16 @@ class SpotifyClient:
|
|
|
2853
3177
|
after (str):
|
|
2854
3178
|
The last artist ID retrieved from the previous request, or null for
|
|
2855
3179
|
the first request.
|
|
2856
|
-
Example: `
|
|
3180
|
+
Example: `6APm8EjxOHSYM5B4i3vT3q`
|
|
2857
3181
|
limit (int):
|
|
2858
|
-
The maximum number of items to return.
|
|
3182
|
+
The maximum number of items to return in a page of items.
|
|
2859
3183
|
Default: 20, Range: 1 to 50.
|
|
3184
|
+
limitTotal (int):
|
|
3185
|
+
The maximum number of items to return for the request.
|
|
3186
|
+
If specified, this argument overrides the limit and offset argument values
|
|
3187
|
+
and paging is automatically used to retrieve all available items up to the
|
|
3188
|
+
maximum number specified.
|
|
3189
|
+
Default: None (disabled)
|
|
2860
3190
|
|
|
2861
3191
|
Returns:
|
|
2862
3192
|
An `ArtistPage` object of matching results.
|
|
@@ -2869,11 +3199,17 @@ class SpotifyClient:
|
|
|
2869
3199
|
If the method fails for any other reason.
|
|
2870
3200
|
|
|
2871
3201
|
<details>
|
|
2872
|
-
<summary>Sample Code</summary>
|
|
3202
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
2873
3203
|
```python
|
|
2874
3204
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetArtistsFollowed.py
|
|
2875
3205
|
```
|
|
2876
3206
|
</details>
|
|
3207
|
+
<details>
|
|
3208
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
3209
|
+
```python
|
|
3210
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetArtistsFollowed_AutoPaging.py
|
|
3211
|
+
```
|
|
3212
|
+
</details>
|
|
2877
3213
|
"""
|
|
2878
3214
|
apiMethodName:str = 'GetArtistsFollowed'
|
|
2879
3215
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -2885,8 +3221,23 @@ class SpotifyClient:
|
|
|
2885
3221
|
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
2886
3222
|
apiMethodParms.AppendKeyValue("after", after)
|
|
2887
3223
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
3224
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
2888
3225
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get the current user's followed artists", apiMethodParms)
|
|
2889
3226
|
|
|
3227
|
+
# validations.
|
|
3228
|
+
if limit is None:
|
|
3229
|
+
limit = 20
|
|
3230
|
+
if not isinstance(limitTotal, int):
|
|
3231
|
+
limitTotal = 0
|
|
3232
|
+
|
|
3233
|
+
# are we auto-paging? if so, then use max limit.
|
|
3234
|
+
if limitTotal > 0:
|
|
3235
|
+
limit = 50
|
|
3236
|
+
#limit = 5 # TEST TODO
|
|
3237
|
+
if limit > limitTotal:
|
|
3238
|
+
limit = limitTotal
|
|
3239
|
+
result = ArtistPage()
|
|
3240
|
+
|
|
2890
3241
|
# build spotify web api request parameters.
|
|
2891
3242
|
urlParms:dict = \
|
|
2892
3243
|
{
|
|
@@ -2896,16 +3247,62 @@ class SpotifyClient:
|
|
|
2896
3247
|
if after is not None:
|
|
2897
3248
|
urlParms['after'] = after
|
|
2898
3249
|
|
|
2899
|
-
#
|
|
2900
|
-
|
|
2901
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
2902
|
-
msg.UrlParameters = urlParms
|
|
2903
|
-
self.MakeRequest('GET', msg)
|
|
3250
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
3251
|
+
while True:
|
|
2904
3252
|
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
3253
|
+
# execute spotify web api request.
|
|
3254
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/following')
|
|
3255
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
3256
|
+
msg.UrlParameters = urlParms
|
|
3257
|
+
self.MakeRequest('GET', msg)
|
|
3258
|
+
|
|
3259
|
+
# process results.
|
|
3260
|
+
item:dict = msg.ResponseData.get('artists',{})
|
|
3261
|
+
if item is not None:
|
|
3262
|
+
pageObj = ArtistPage(root=item)
|
|
3263
|
+
|
|
3264
|
+
# trace.
|
|
3265
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
3266
|
+
|
|
3267
|
+
# was limit total argument specified?
|
|
3268
|
+
if (limitTotal <= 0):
|
|
3269
|
+
|
|
3270
|
+
# no - just return the initial page of results.
|
|
3271
|
+
result = pageObj
|
|
3272
|
+
break
|
|
3273
|
+
|
|
3274
|
+
else:
|
|
3275
|
+
|
|
3276
|
+
# append page of items to final results.
|
|
3277
|
+
item:Artist
|
|
3278
|
+
for item in pageObj.Items:
|
|
3279
|
+
result.Items.append(item)
|
|
3280
|
+
result.Limit = result.ItemsCount
|
|
3281
|
+
if result.ItemsCount >= limitTotal:
|
|
3282
|
+
break
|
|
3283
|
+
|
|
3284
|
+
# anymore page results?
|
|
3285
|
+
if (pageObj.Next is None) or (result.ItemsCount >= limitTotal):
|
|
3286
|
+
# no - all pages were processed, or limit total reached.
|
|
3287
|
+
break
|
|
3288
|
+
else:
|
|
3289
|
+
# yes - retrieve the next page of results.
|
|
3290
|
+
pageObj.CursorAfter = item.Id
|
|
3291
|
+
|
|
3292
|
+
# modify paging-related request parameters for next page of items.
|
|
3293
|
+
urlParms['limit'] = pageObj.Limit
|
|
3294
|
+
urlParms['after'] = pageObj.CursorAfter
|
|
3295
|
+
|
|
3296
|
+
# trace.
|
|
3297
|
+
_logsi.LogVerbose(TRACE_MSG_AUTOPAGING_NEXT % pageObj.PagingInfo)
|
|
3298
|
+
|
|
3299
|
+
# update result object with final paging details.
|
|
3300
|
+
result.Total = pageObj.Total
|
|
3301
|
+
result.CursorAfter = pageObj.CursorAfter
|
|
3302
|
+
|
|
3303
|
+
# sort items on Name property, ascending order.
|
|
3304
|
+
if len(result.Items) > 0:
|
|
3305
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
2909
3306
|
|
|
2910
3307
|
# trace.
|
|
2911
3308
|
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -2934,7 +3331,7 @@ class SpotifyClient:
|
|
|
2934
3331
|
Args:
|
|
2935
3332
|
artistId (str):
|
|
2936
3333
|
The Spotify ID of the artist.
|
|
2937
|
-
Example: `
|
|
3334
|
+
Example: `6APm8EjxOHSYM5B4i3vT3q`
|
|
2938
3335
|
market (str):
|
|
2939
3336
|
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
2940
3337
|
is available in that market will be returned. If a valid user access token is specified
|
|
@@ -2973,6 +3370,9 @@ class SpotifyClient:
|
|
|
2973
3370
|
apiMethodParms.AppendKeyValue("market", market)
|
|
2974
3371
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information about an artist's top tracks", apiMethodParms)
|
|
2975
3372
|
|
|
3373
|
+
# ensure market was either supplied or implied; default if neither.
|
|
3374
|
+
market = self._ValidateMarket(market)
|
|
3375
|
+
|
|
2976
3376
|
# build spotify web api request parameters.
|
|
2977
3377
|
urlParms:dict = {}
|
|
2978
3378
|
if market is not None:
|
|
@@ -3062,6 +3462,9 @@ class SpotifyClient:
|
|
|
3062
3462
|
apiMethodParms.AppendKeyValue("market", market)
|
|
3063
3463
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for a single audiobook", apiMethodParms)
|
|
3064
3464
|
|
|
3465
|
+
# ensure market was either supplied or implied; default if neither.
|
|
3466
|
+
market = self._ValidateMarket(market)
|
|
3467
|
+
|
|
3065
3468
|
# build spotify web api request parameters.
|
|
3066
3469
|
urlParms:dict = {}
|
|
3067
3470
|
if market is not None:
|
|
@@ -3097,7 +3500,8 @@ class SpotifyClient:
|
|
|
3097
3500
|
audiobookId:str,
|
|
3098
3501
|
limit:int=20,
|
|
3099
3502
|
offset:int=0,
|
|
3100
|
-
market:str=None
|
|
3503
|
+
market:str=None,
|
|
3504
|
+
limitTotal:int=None
|
|
3101
3505
|
) -> ChapterPageSimplified:
|
|
3102
3506
|
"""
|
|
3103
3507
|
Get Spotify catalog information about an audiobook's chapters.
|
|
@@ -3109,7 +3513,7 @@ class SpotifyClient:
|
|
|
3109
3513
|
The Spotify ID for the audiobook.
|
|
3110
3514
|
Example: `74aydHJKgYz3AIq3jjBSv1`
|
|
3111
3515
|
limit (int):
|
|
3112
|
-
The maximum number of items to return.
|
|
3516
|
+
The maximum number of items to return in a page of items.
|
|
3113
3517
|
Default: 20, Range: 1 to 50.
|
|
3114
3518
|
offset (int):
|
|
3115
3519
|
The index of the first item to return; use with limit to get the next set of items.
|
|
@@ -3122,6 +3526,12 @@ class SpotifyClient:
|
|
|
3122
3526
|
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
3123
3527
|
Users can view the country that is associated with their account in the account settings.
|
|
3124
3528
|
Example: `ES`
|
|
3529
|
+
limitTotal (int):
|
|
3530
|
+
The maximum number of items to return for the request.
|
|
3531
|
+
If specified, this argument overrides the limit and offset argument values
|
|
3532
|
+
and paging is automatically used to retrieve all available items up to the
|
|
3533
|
+
maximum number specified.
|
|
3534
|
+
Default: None (disabled)
|
|
3125
3535
|
|
|
3126
3536
|
Returns:
|
|
3127
3537
|
A `ChapterPageSimplified` object that contains simplified track information for the audiobookId.
|
|
@@ -3134,11 +3544,17 @@ class SpotifyClient:
|
|
|
3134
3544
|
If the method fails for any other reason.
|
|
3135
3545
|
|
|
3136
3546
|
<details>
|
|
3137
|
-
<summary>Sample Code</summary>
|
|
3547
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
3138
3548
|
```python
|
|
3139
3549
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetAudiobookChapters.py
|
|
3140
3550
|
```
|
|
3141
3551
|
</details>
|
|
3552
|
+
<details>
|
|
3553
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
3554
|
+
```python
|
|
3555
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetAudiobookChapters_AutoPaging.py
|
|
3556
|
+
```
|
|
3557
|
+
</details>
|
|
3142
3558
|
"""
|
|
3143
3559
|
apiMethodName:str = 'GetAudiobookChapters'
|
|
3144
3560
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -3152,6 +3568,7 @@ class SpotifyClient:
|
|
|
3152
3568
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
3153
3569
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
3154
3570
|
apiMethodParms.AppendKeyValue("market", market)
|
|
3571
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
3155
3572
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information about an audiobook's chapters", apiMethodParms)
|
|
3156
3573
|
|
|
3157
3574
|
# validations.
|
|
@@ -3159,6 +3576,19 @@ class SpotifyClient:
|
|
|
3159
3576
|
limit = 20
|
|
3160
3577
|
if offset is None:
|
|
3161
3578
|
offset = 0
|
|
3579
|
+
if not isinstance(limitTotal, int):
|
|
3580
|
+
limitTotal = 0
|
|
3581
|
+
|
|
3582
|
+
# are we auto-paging? if so, then use max limit.
|
|
3583
|
+
if limitTotal > 0:
|
|
3584
|
+
limit = 50
|
|
3585
|
+
#limit = 2 # TEST TODO
|
|
3586
|
+
if limit > limitTotal:
|
|
3587
|
+
limit = limitTotal
|
|
3588
|
+
result = ChapterPageSimplified()
|
|
3589
|
+
|
|
3590
|
+
# ensure market was either supplied or implied; default if neither.
|
|
3591
|
+
market = self._ValidateMarket(market)
|
|
3162
3592
|
|
|
3163
3593
|
# build spotify web api request parameters.
|
|
3164
3594
|
urlParms:dict = \
|
|
@@ -3169,14 +3599,46 @@ class SpotifyClient:
|
|
|
3169
3599
|
if market is not None:
|
|
3170
3600
|
urlParms['market'] = market
|
|
3171
3601
|
|
|
3172
|
-
#
|
|
3173
|
-
|
|
3174
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
3175
|
-
msg.UrlParameters = urlParms
|
|
3176
|
-
self.MakeRequest('GET', msg)
|
|
3602
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
3603
|
+
while True:
|
|
3177
3604
|
|
|
3178
|
-
|
|
3179
|
-
|
|
3605
|
+
# execute spotify web api request.
|
|
3606
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/audiobooks/{id}/chapters'.format(id=audiobookId))
|
|
3607
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
3608
|
+
msg.UrlParameters = urlParms
|
|
3609
|
+
self.MakeRequest('GET', msg)
|
|
3610
|
+
|
|
3611
|
+
# process results.
|
|
3612
|
+
pageObj = ChapterPageSimplified(root=msg.ResponseData)
|
|
3613
|
+
|
|
3614
|
+
# trace.
|
|
3615
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
3616
|
+
|
|
3617
|
+
# was limit total argument specified?
|
|
3618
|
+
if (limitTotal <= 0):
|
|
3619
|
+
|
|
3620
|
+
# no - just return the initial page of results.
|
|
3621
|
+
result = pageObj
|
|
3622
|
+
break
|
|
3623
|
+
|
|
3624
|
+
else:
|
|
3625
|
+
|
|
3626
|
+
# append page of items to final results.
|
|
3627
|
+
item:ChapterSimplified
|
|
3628
|
+
for item in pageObj.Items:
|
|
3629
|
+
result.Items.append(item)
|
|
3630
|
+
result.Limit = result.ItemsCount
|
|
3631
|
+
if result.ItemsCount >= limitTotal:
|
|
3632
|
+
break
|
|
3633
|
+
|
|
3634
|
+
# anymore pages to process? if not, then exit the loop.
|
|
3635
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
3636
|
+
break
|
|
3637
|
+
|
|
3638
|
+
# update result object with final paging details.
|
|
3639
|
+
result.Total = pageObj.Total
|
|
3640
|
+
|
|
3641
|
+
# no sorting, as chapters are in playable order.
|
|
3180
3642
|
|
|
3181
3643
|
# trace.
|
|
3182
3644
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -3198,6 +3660,7 @@ class SpotifyClient:
|
|
|
3198
3660
|
def GetAudiobookFavorites(self,
|
|
3199
3661
|
limit:int=20,
|
|
3200
3662
|
offset:int=0,
|
|
3663
|
+
limitTotal:int=None
|
|
3201
3664
|
) -> AudiobookPageSimplified:
|
|
3202
3665
|
"""
|
|
3203
3666
|
Get a list of the audiobooks saved in the current Spotify user's 'Your Library'.
|
|
@@ -3206,12 +3669,18 @@ class SpotifyClient:
|
|
|
3206
3669
|
|
|
3207
3670
|
Args:
|
|
3208
3671
|
limit (int):
|
|
3209
|
-
The maximum number of items to return.
|
|
3672
|
+
The maximum number of items to return in a page of items.
|
|
3210
3673
|
Default: 20, Range: 1 to 50.
|
|
3211
3674
|
offset (int):
|
|
3212
|
-
The index of the first item to return.
|
|
3675
|
+
The page index offset of the first item to return.
|
|
3213
3676
|
Use with limit to get the next set of items.
|
|
3214
3677
|
Default: 0 (the first item).
|
|
3678
|
+
limitTotal (int):
|
|
3679
|
+
The maximum number of items to return for the request.
|
|
3680
|
+
If specified, this argument overrides the limit and offset argument values
|
|
3681
|
+
and paging is automatically used to retrieve all available items up to the
|
|
3682
|
+
maximum number specified.
|
|
3683
|
+
Default: None (disabled)
|
|
3215
3684
|
|
|
3216
3685
|
Returns:
|
|
3217
3686
|
An `AudiobookPageSimplified` object that contains saved audiobook information.
|
|
@@ -3224,11 +3693,17 @@ class SpotifyClient:
|
|
|
3224
3693
|
If the method fails for any other reason.
|
|
3225
3694
|
|
|
3226
3695
|
<details>
|
|
3227
|
-
<summary>Sample Code</summary>
|
|
3696
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
3228
3697
|
```python
|
|
3229
3698
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetAudiobookFavorites.py
|
|
3230
3699
|
```
|
|
3231
3700
|
</details>
|
|
3701
|
+
<details>
|
|
3702
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
3703
|
+
```python
|
|
3704
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetAudiobookFavorites_AutoPaging.py
|
|
3705
|
+
```
|
|
3706
|
+
</details>
|
|
3232
3707
|
"""
|
|
3233
3708
|
apiMethodName:str = 'GetAudiobookFavorites'
|
|
3234
3709
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -3240,6 +3715,7 @@ class SpotifyClient:
|
|
|
3240
3715
|
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
3241
3716
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
3242
3717
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
3718
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
3243
3719
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the users audiobook favorites", apiMethodParms)
|
|
3244
3720
|
|
|
3245
3721
|
# validations.
|
|
@@ -3247,6 +3723,16 @@ class SpotifyClient:
|
|
|
3247
3723
|
limit = 20
|
|
3248
3724
|
if offset is None:
|
|
3249
3725
|
offset = 0
|
|
3726
|
+
if not isinstance(limitTotal, int):
|
|
3727
|
+
limitTotal = 0
|
|
3728
|
+
|
|
3729
|
+
# are we auto-paging? if so, then use max limit.
|
|
3730
|
+
if limitTotal > 0:
|
|
3731
|
+
limit = 50
|
|
3732
|
+
#limit = 2 # TEST TODO
|
|
3733
|
+
if limit > limitTotal:
|
|
3734
|
+
limit = limitTotal
|
|
3735
|
+
result = AudiobookPageSimplified()
|
|
3250
3736
|
|
|
3251
3737
|
# build spotify web api request parameters.
|
|
3252
3738
|
urlParms:dict = \
|
|
@@ -3255,15 +3741,49 @@ class SpotifyClient:
|
|
|
3255
3741
|
'offset': offset,
|
|
3256
3742
|
}
|
|
3257
3743
|
|
|
3258
|
-
#
|
|
3259
|
-
|
|
3260
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
3261
|
-
msg.UrlParameters = urlParms
|
|
3262
|
-
self.MakeRequest('GET', msg)
|
|
3744
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
3745
|
+
while True:
|
|
3263
3746
|
|
|
3264
|
-
|
|
3265
|
-
|
|
3747
|
+
# execute spotify web api request.
|
|
3748
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/audiobooks')
|
|
3749
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
3750
|
+
msg.UrlParameters = urlParms
|
|
3751
|
+
self.MakeRequest('GET', msg)
|
|
3752
|
+
|
|
3753
|
+
# process results.
|
|
3754
|
+
pageObj = AudiobookPageSimplified(root=msg.ResponseData)
|
|
3266
3755
|
|
|
3756
|
+
# trace.
|
|
3757
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
3758
|
+
|
|
3759
|
+
# was limit total argument specified?
|
|
3760
|
+
if (limitTotal <= 0):
|
|
3761
|
+
|
|
3762
|
+
# no - just return the initial page of results.
|
|
3763
|
+
result = pageObj
|
|
3764
|
+
break
|
|
3765
|
+
|
|
3766
|
+
else:
|
|
3767
|
+
|
|
3768
|
+
# append page of items to final results.
|
|
3769
|
+
item:AudiobookSimplified
|
|
3770
|
+
for item in pageObj.Items:
|
|
3771
|
+
result.Items.append(item)
|
|
3772
|
+
result.Limit = result.ItemsCount
|
|
3773
|
+
if result.ItemsCount >= limitTotal:
|
|
3774
|
+
break
|
|
3775
|
+
|
|
3776
|
+
# anymore pages to process? if not, then exit the loop.
|
|
3777
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
3778
|
+
break
|
|
3779
|
+
|
|
3780
|
+
# update result object with final paging details.
|
|
3781
|
+
result.Total = pageObj.Total
|
|
3782
|
+
|
|
3783
|
+
# sort items on Name property, ascending order.
|
|
3784
|
+
if len(result.Items) > 0:
|
|
3785
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
3786
|
+
|
|
3267
3787
|
# trace.
|
|
3268
3788
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
3269
3789
|
return result
|
|
@@ -3336,6 +3856,9 @@ class SpotifyClient:
|
|
|
3336
3856
|
apiMethodParms.AppendKeyValue("market", market)
|
|
3337
3857
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for multiple audiobooks", apiMethodParms)
|
|
3338
3858
|
|
|
3859
|
+
# ensure market was either supplied or implied; default if neither.
|
|
3860
|
+
market = self._ValidateMarket(market)
|
|
3861
|
+
|
|
3339
3862
|
# build spotify web api request parameters.
|
|
3340
3863
|
urlParms:dict = \
|
|
3341
3864
|
{
|
|
@@ -3490,21 +4013,22 @@ class SpotifyClient:
|
|
|
3490
4013
|
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
3491
4014
|
|
|
3492
4015
|
|
|
3493
|
-
def
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
4016
|
+
def GetBrowseCategorys(self,
|
|
4017
|
+
limit:int=20,
|
|
4018
|
+
offset:int=0,
|
|
4019
|
+
country:str=None,
|
|
4020
|
+
locale:str=None,
|
|
4021
|
+
limitTotal:int=None
|
|
4022
|
+
) -> CategoryPage:
|
|
3499
4023
|
"""
|
|
3500
4024
|
Get a page of categories used to tag items in Spotify.
|
|
3501
4025
|
|
|
3502
4026
|
Args:
|
|
3503
4027
|
limit (int):
|
|
3504
|
-
The maximum number of items to return.
|
|
3505
|
-
Default:
|
|
4028
|
+
The maximum number of items to return in a page of items.
|
|
4029
|
+
Default: 20, Range: 1 to 50.
|
|
3506
4030
|
offset (int):
|
|
3507
|
-
The index of the first item to return.
|
|
4031
|
+
The page index offset of the first item to return.
|
|
3508
4032
|
Use with limit to get the next set of items.
|
|
3509
4033
|
Default: 0 (the first item).
|
|
3510
4034
|
country (str):
|
|
@@ -3522,6 +4046,12 @@ class SpotifyClient:
|
|
|
3522
4046
|
the country parameter, may give odd results if not carefully matched. For example country=`SE` and
|
|
3523
4047
|
locale=`de_DE` will return a list of categories relevant to Sweden but as German language strings.
|
|
3524
4048
|
Example: `sv_SE`
|
|
4049
|
+
limitTotal (int):
|
|
4050
|
+
The maximum number of items to return for the request.
|
|
4051
|
+
If specified, this argument overrides the limit and offset argument values
|
|
4052
|
+
and paging is automatically used to retrieve all available items up to the
|
|
4053
|
+
maximum number specified.
|
|
4054
|
+
Default: None (disabled)
|
|
3525
4055
|
|
|
3526
4056
|
Returns:
|
|
3527
4057
|
A `CategoryPage` object that contains a page of category details.
|
|
@@ -3534,13 +4064,19 @@ class SpotifyClient:
|
|
|
3534
4064
|
If the method fails for any other reason.
|
|
3535
4065
|
|
|
3536
4066
|
<details>
|
|
3537
|
-
<summary>Sample Code</summary>
|
|
4067
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
4068
|
+
```python
|
|
4069
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetBrowseCategorys.py
|
|
4070
|
+
```
|
|
4071
|
+
</details>
|
|
4072
|
+
<details>
|
|
4073
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
3538
4074
|
```python
|
|
3539
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/
|
|
4075
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetBrowseCategorys_AutoPaging.py
|
|
3540
4076
|
```
|
|
3541
4077
|
</details>
|
|
3542
4078
|
"""
|
|
3543
|
-
apiMethodName:str = '
|
|
4079
|
+
apiMethodName:str = 'GetBrowseCategorys'
|
|
3544
4080
|
apiMethodParms:SIMethodParmListContext = None
|
|
3545
4081
|
result:CategoryPage = None
|
|
3546
4082
|
|
|
@@ -3552,13 +4088,24 @@ class SpotifyClient:
|
|
|
3552
4088
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
3553
4089
|
apiMethodParms.AppendKeyValue("country", country)
|
|
3554
4090
|
apiMethodParms.AppendKeyValue("locale", locale)
|
|
4091
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
3555
4092
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a page of categories used to tag items in Spotify", apiMethodParms)
|
|
3556
4093
|
|
|
3557
4094
|
# validations.
|
|
3558
4095
|
if limit is None:
|
|
3559
|
-
limit =
|
|
4096
|
+
limit = 20
|
|
3560
4097
|
if offset is None:
|
|
3561
4098
|
offset = 0
|
|
4099
|
+
if not isinstance(limitTotal, int):
|
|
4100
|
+
limitTotal = 0
|
|
4101
|
+
|
|
4102
|
+
# are we auto-paging? if so, then use max limit.
|
|
4103
|
+
if limitTotal > 0:
|
|
4104
|
+
limit = 50
|
|
4105
|
+
#limit = 2 # TEST TODO
|
|
4106
|
+
if limit > limitTotal:
|
|
4107
|
+
limit = limitTotal
|
|
4108
|
+
result = CategoryPage()
|
|
3562
4109
|
|
|
3563
4110
|
# build spotify web api request parameters.
|
|
3564
4111
|
urlParms:dict = \
|
|
@@ -3571,16 +4118,50 @@ class SpotifyClient:
|
|
|
3571
4118
|
if locale is not None:
|
|
3572
4119
|
urlParms['locale'] = str(locale)
|
|
3573
4120
|
|
|
3574
|
-
#
|
|
3575
|
-
|
|
3576
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
3577
|
-
msg.UrlParameters = urlParms
|
|
3578
|
-
self.MakeRequest('GET', msg)
|
|
4121
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
4122
|
+
while True:
|
|
3579
4123
|
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
4124
|
+
# execute spotify web api request.
|
|
4125
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/browse/categories')
|
|
4126
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
4127
|
+
msg.UrlParameters = urlParms
|
|
4128
|
+
self.MakeRequest('GET', msg)
|
|
4129
|
+
|
|
4130
|
+
# process results.
|
|
4131
|
+
item:dict = msg.ResponseData.get('categories',None)
|
|
4132
|
+
if item is not None:
|
|
4133
|
+
pageObj = CategoryPage(root=item)
|
|
4134
|
+
|
|
4135
|
+
# trace.
|
|
4136
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
4137
|
+
|
|
4138
|
+
# was limit total argument specified?
|
|
4139
|
+
if (limitTotal <= 0):
|
|
4140
|
+
|
|
4141
|
+
# no - just return the initial page of results.
|
|
4142
|
+
result = pageObj
|
|
4143
|
+
break
|
|
4144
|
+
|
|
4145
|
+
else:
|
|
4146
|
+
|
|
4147
|
+
# append page of items to final results.
|
|
4148
|
+
item:Category
|
|
4149
|
+
for item in pageObj.Items:
|
|
4150
|
+
result.Items.append(item)
|
|
4151
|
+
result.Limit = result.ItemsCount
|
|
4152
|
+
if result.ItemsCount >= limitTotal:
|
|
4153
|
+
break
|
|
4154
|
+
|
|
4155
|
+
# anymore pages to process? if not, then exit the loop.
|
|
4156
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
4157
|
+
break
|
|
4158
|
+
|
|
4159
|
+
# update result object with final paging details.
|
|
4160
|
+
result.Total = pageObj.Total
|
|
4161
|
+
|
|
4162
|
+
# sort items on Name property, ascending order.
|
|
4163
|
+
if len(result.Items) > 0:
|
|
4164
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
3584
4165
|
|
|
3585
4166
|
# trace.
|
|
3586
4167
|
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -3599,11 +4180,11 @@ class SpotifyClient:
|
|
|
3599
4180
|
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
3600
4181
|
|
|
3601
4182
|
|
|
3602
|
-
def
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
4183
|
+
def GetBrowseCategorysList(self,
|
|
4184
|
+
country:str=None,
|
|
4185
|
+
locale:str=None,
|
|
4186
|
+
refresh:bool=True,
|
|
4187
|
+
) -> list[Category]:
|
|
3607
4188
|
"""
|
|
3608
4189
|
Get a sorted list of ALL categories used to tag items in Spotify.
|
|
3609
4190
|
|
|
@@ -3644,11 +4225,11 @@ class SpotifyClient:
|
|
|
3644
4225
|
<details>
|
|
3645
4226
|
<summary>Sample Code</summary>
|
|
3646
4227
|
```python
|
|
3647
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/
|
|
4228
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetBrowseCategorysList.py
|
|
3648
4229
|
```
|
|
3649
4230
|
</details>
|
|
3650
4231
|
"""
|
|
3651
|
-
apiMethodName:str = '
|
|
4232
|
+
apiMethodName:str = 'GetBrowseCategorysList'
|
|
3652
4233
|
apiMethodParms:SIMethodParmListContext = None
|
|
3653
4234
|
result:list[Category] = []
|
|
3654
4235
|
cacheDesc:str = CACHE_SOURCE_CURRENT
|
|
@@ -3659,6 +4240,7 @@ class SpotifyClient:
|
|
|
3659
4240
|
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
3660
4241
|
apiMethodParms.AppendKeyValue("country", country)
|
|
3661
4242
|
apiMethodParms.AppendKeyValue("locale", locale)
|
|
4243
|
+
apiMethodParms.AppendKeyValue("refresh", refresh)
|
|
3662
4244
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a sorted list of ALL browse categories", apiMethodParms)
|
|
3663
4245
|
|
|
3664
4246
|
# can we use the cached value?
|
|
@@ -3669,29 +4251,14 @@ class SpotifyClient:
|
|
|
3669
4251
|
|
|
3670
4252
|
else:
|
|
3671
4253
|
|
|
3672
|
-
# get
|
|
3673
|
-
pageObj:CategoryPage = self.
|
|
3674
|
-
|
|
3675
|
-
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
3676
|
-
while True:
|
|
3677
|
-
|
|
3678
|
-
# add category details to return list.
|
|
3679
|
-
category:Category
|
|
3680
|
-
for category in pageObj.Items:
|
|
3681
|
-
result.append(category)
|
|
3682
|
-
|
|
3683
|
-
# anymore page results?
|
|
3684
|
-
if pageObj.Next is None:
|
|
3685
|
-
# no - all pages were processed.
|
|
3686
|
-
break
|
|
3687
|
-
else:
|
|
3688
|
-
# yes - retrieve the next page of results.
|
|
3689
|
-
pageObj = self.GetBrowseCategorysPage(country=country, locale=locale, offset=pageObj.Offset + pageObj.Limit, limit=pageObj.Limit)
|
|
4254
|
+
# get all categories (return list is already sorted).
|
|
4255
|
+
pageObj:CategoryPage = self.GetBrowseCategorys(country=country, locale=locale, limitTotal=1000)
|
|
3690
4256
|
|
|
3691
|
-
#
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
4257
|
+
# add category details to return list.
|
|
4258
|
+
category:Category
|
|
4259
|
+
for category in pageObj.Items:
|
|
4260
|
+
result.append(category)
|
|
4261
|
+
|
|
3695
4262
|
# update cache.
|
|
3696
4263
|
self._ConfigurationCache[apiMethodName] = result
|
|
3697
4264
|
|
|
@@ -3717,6 +4284,7 @@ class SpotifyClient:
|
|
|
3717
4284
|
limit:int=20,
|
|
3718
4285
|
offset:int=0,
|
|
3719
4286
|
country:str=None,
|
|
4287
|
+
limitTotal:int=None
|
|
3720
4288
|
) -> Tuple[PlaylistPageSimplified, str]:
|
|
3721
4289
|
"""
|
|
3722
4290
|
Get a list of Spotify playlists tagged with a particular category.
|
|
@@ -3726,10 +4294,10 @@ class SpotifyClient:
|
|
|
3726
4294
|
The Spotify category ID for the category.
|
|
3727
4295
|
Example: `dinner`
|
|
3728
4296
|
limit (int):
|
|
3729
|
-
The maximum number of items to return.
|
|
4297
|
+
The maximum number of items to return in a page of items.
|
|
3730
4298
|
Default: 20, Range: 1 to 50.
|
|
3731
4299
|
offset (int):
|
|
3732
|
-
The index of the first item to return.
|
|
4300
|
+
The page index offset of the first item to return.
|
|
3733
4301
|
Use with limit to get the next set of items.
|
|
3734
4302
|
Default: 0 (the first item).
|
|
3735
4303
|
country (str):
|
|
@@ -3737,6 +4305,12 @@ class SpotifyClient:
|
|
|
3737
4305
|
Provide this parameter if you want the list of returned items to be relevant to a
|
|
3738
4306
|
particular country. If omitted, the returned items will be relevant to all countries.
|
|
3739
4307
|
Example: `SE`
|
|
4308
|
+
limitTotal (int):
|
|
4309
|
+
The maximum number of items to return for the request.
|
|
4310
|
+
If specified, this argument overrides the limit and offset argument values
|
|
4311
|
+
and paging is automatically used to retrieve all available items up to the
|
|
4312
|
+
maximum number specified.
|
|
4313
|
+
Default: None (disabled)
|
|
3740
4314
|
|
|
3741
4315
|
Returns:
|
|
3742
4316
|
A tuple of 2 objects:
|
|
@@ -3751,11 +4325,17 @@ class SpotifyClient:
|
|
|
3751
4325
|
If the method fails for any other reason.
|
|
3752
4326
|
|
|
3753
4327
|
<details>
|
|
3754
|
-
<summary>Sample Code</summary>
|
|
4328
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
3755
4329
|
```python
|
|
3756
4330
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetCategoryPlaylists.py
|
|
3757
4331
|
```
|
|
3758
4332
|
</details>
|
|
4333
|
+
<details>
|
|
4334
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
4335
|
+
```python
|
|
4336
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetCategoryPlaylists_AutoPaging.py
|
|
4337
|
+
```
|
|
4338
|
+
</details>
|
|
3759
4339
|
"""
|
|
3760
4340
|
apiMethodName:str = 'GetCategoryPlaylists'
|
|
3761
4341
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -3770,6 +4350,7 @@ class SpotifyClient:
|
|
|
3770
4350
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
3771
4351
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
3772
4352
|
apiMethodParms.AppendKeyValue("country", country)
|
|
4353
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
3773
4354
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of Spotify playlists tagged with a particular category", apiMethodParms)
|
|
3774
4355
|
|
|
3775
4356
|
# validations.
|
|
@@ -3777,6 +4358,16 @@ class SpotifyClient:
|
|
|
3777
4358
|
limit = 20
|
|
3778
4359
|
if offset is None:
|
|
3779
4360
|
offset = 0
|
|
4361
|
+
if not isinstance(limitTotal, int):
|
|
4362
|
+
limitTotal = 0
|
|
4363
|
+
|
|
4364
|
+
# are we auto-paging? if so, then use max limit.
|
|
4365
|
+
if limitTotal > 0:
|
|
4366
|
+
limit = 50
|
|
4367
|
+
#limit = 2 # TEST TODO
|
|
4368
|
+
if limit > limitTotal:
|
|
4369
|
+
limit = limitTotal
|
|
4370
|
+
result = PlaylistPageSimplified()
|
|
3780
4371
|
|
|
3781
4372
|
# build spotify web api request parameters.
|
|
3782
4373
|
urlParms:dict = \
|
|
@@ -3788,18 +4379,52 @@ class SpotifyClient:
|
|
|
3788
4379
|
if country is not None:
|
|
3789
4380
|
urlParms['country'] = str(country)
|
|
3790
4381
|
|
|
3791
|
-
#
|
|
3792
|
-
|
|
3793
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
3794
|
-
msg.UrlParameters = urlParms
|
|
3795
|
-
self.MakeRequest('GET', msg)
|
|
4382
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
4383
|
+
while True:
|
|
3796
4384
|
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
4385
|
+
# execute spotify web api request.
|
|
4386
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/browse/categories/{category_id}/playlists'.format(category_id=categoryId))
|
|
4387
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
4388
|
+
msg.UrlParameters = urlParms
|
|
4389
|
+
self.MakeRequest('GET', msg)
|
|
4390
|
+
|
|
4391
|
+
# process results.
|
|
4392
|
+
resultMessage = msg.ResponseData.get('message','unknown')
|
|
4393
|
+
item = msg.ResponseData.get('playlists',None)
|
|
4394
|
+
if item is not None:
|
|
4395
|
+
pageObj = PlaylistPageSimplified(root=item)
|
|
3802
4396
|
|
|
4397
|
+
# trace.
|
|
4398
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
4399
|
+
|
|
4400
|
+
# was limit total argument specified?
|
|
4401
|
+
if (limitTotal <= 0):
|
|
4402
|
+
|
|
4403
|
+
# no - just return the initial page of results.
|
|
4404
|
+
result = pageObj
|
|
4405
|
+
break
|
|
4406
|
+
|
|
4407
|
+
else:
|
|
4408
|
+
|
|
4409
|
+
# append page of items to final results.
|
|
4410
|
+
item:PlaylistSimplified
|
|
4411
|
+
for item in pageObj.Items:
|
|
4412
|
+
result.Items.append(item)
|
|
4413
|
+
result.Limit = result.ItemsCount
|
|
4414
|
+
if result.ItemsCount >= limitTotal:
|
|
4415
|
+
break
|
|
4416
|
+
|
|
4417
|
+
# anymore pages to process? if not, then exit the loop.
|
|
4418
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
4419
|
+
break
|
|
4420
|
+
|
|
4421
|
+
# update result object with final paging details.
|
|
4422
|
+
result.Total = pageObj.Total
|
|
4423
|
+
|
|
4424
|
+
# sort items on Name property, ascending order.
|
|
4425
|
+
if len(result.Items) > 0:
|
|
4426
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
4427
|
+
|
|
3803
4428
|
# trace.
|
|
3804
4429
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
3805
4430
|
return result, resultMessage
|
|
@@ -3873,6 +4498,9 @@ class SpotifyClient:
|
|
|
3873
4498
|
apiMethodParms.AppendKeyValue("market", market)
|
|
3874
4499
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for a single audiobook chapter", apiMethodParms)
|
|
3875
4500
|
|
|
4501
|
+
# ensure market was either supplied or implied; default if neither.
|
|
4502
|
+
market = self._ValidateMarket(market)
|
|
4503
|
+
|
|
3876
4504
|
# build spotify web api request parameters.
|
|
3877
4505
|
urlParms:dict = {}
|
|
3878
4506
|
if market is not None:
|
|
@@ -3959,6 +4587,9 @@ class SpotifyClient:
|
|
|
3959
4587
|
apiMethodParms.AppendKeyValue("market", market)
|
|
3960
4588
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for multiple chapters", apiMethodParms)
|
|
3961
4589
|
|
|
4590
|
+
# ensure market was either supplied or implied; default if neither.
|
|
4591
|
+
market = self._ValidateMarket(market)
|
|
4592
|
+
|
|
3962
4593
|
# build spotify web api request parameters.
|
|
3963
4594
|
urlParms:dict = \
|
|
3964
4595
|
{
|
|
@@ -4051,6 +4682,9 @@ class SpotifyClient:
|
|
|
4051
4682
|
apiMethodParms.AppendKeyValue("market", market)
|
|
4052
4683
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for a single episode", apiMethodParms)
|
|
4053
4684
|
|
|
4685
|
+
# ensure market was either supplied or implied; default if neither.
|
|
4686
|
+
market = self._ValidateMarket(market)
|
|
4687
|
+
|
|
4054
4688
|
# build spotify web api request parameters.
|
|
4055
4689
|
urlParms:dict = {}
|
|
4056
4690
|
if market is not None:
|
|
@@ -4085,6 +4719,7 @@ class SpotifyClient:
|
|
|
4085
4719
|
def GetEpisodeFavorites(self,
|
|
4086
4720
|
limit:int=20,
|
|
4087
4721
|
offset:int=0,
|
|
4722
|
+
limitTotal:int=None
|
|
4088
4723
|
) -> EpisodePageSaved:
|
|
4089
4724
|
"""
|
|
4090
4725
|
Get a list of the episodes saved in the current Spotify user's 'Your Library'.
|
|
@@ -4093,12 +4728,18 @@ class SpotifyClient:
|
|
|
4093
4728
|
|
|
4094
4729
|
Args:
|
|
4095
4730
|
limit (int):
|
|
4096
|
-
The maximum number of items to return.
|
|
4731
|
+
The maximum number of items to return in a page of items.
|
|
4097
4732
|
Default: 20, Range: 1 to 50.
|
|
4098
4733
|
offset (int):
|
|
4099
|
-
The index of the first item to return.
|
|
4734
|
+
The page index offset of the first item to return.
|
|
4100
4735
|
Use with limit to get the next set of items.
|
|
4101
4736
|
Default: 0 (the first item).
|
|
4737
|
+
limitTotal (int):
|
|
4738
|
+
The maximum number of items to return for the request.
|
|
4739
|
+
If specified, this argument overrides the limit and offset argument values
|
|
4740
|
+
and paging is automatically used to retrieve all available items up to the
|
|
4741
|
+
maximum number specified.
|
|
4742
|
+
Default: None (disabled)
|
|
4102
4743
|
|
|
4103
4744
|
Returns:
|
|
4104
4745
|
An `EpisodePageSaved` object that contains saved episode information.
|
|
@@ -4111,11 +4752,17 @@ class SpotifyClient:
|
|
|
4111
4752
|
If the method fails for any other reason.
|
|
4112
4753
|
|
|
4113
4754
|
<details>
|
|
4114
|
-
<summary>Sample Code</summary>
|
|
4755
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
4115
4756
|
```python
|
|
4116
4757
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetEpisodeFavorites.py
|
|
4117
4758
|
```
|
|
4118
4759
|
</details>
|
|
4760
|
+
<details>
|
|
4761
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
4762
|
+
```python
|
|
4763
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetEpisodeFavorites_AutoPaging.py
|
|
4764
|
+
```
|
|
4765
|
+
</details>
|
|
4119
4766
|
"""
|
|
4120
4767
|
apiMethodName:str = 'GetEpisodeFavorites'
|
|
4121
4768
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -4127,6 +4774,7 @@ class SpotifyClient:
|
|
|
4127
4774
|
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
4128
4775
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
4129
4776
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
4777
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
4130
4778
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the users episode favorites", apiMethodParms)
|
|
4131
4779
|
|
|
4132
4780
|
# validations.
|
|
@@ -4134,6 +4782,16 @@ class SpotifyClient:
|
|
|
4134
4782
|
limit = 20
|
|
4135
4783
|
if offset is None:
|
|
4136
4784
|
offset = 0
|
|
4785
|
+
if not isinstance(limitTotal, int):
|
|
4786
|
+
limitTotal = 0
|
|
4787
|
+
|
|
4788
|
+
# are we auto-paging? if so, then use max limit.
|
|
4789
|
+
if limitTotal > 0:
|
|
4790
|
+
limit = 50
|
|
4791
|
+
#limit = 1 # TEST TODO
|
|
4792
|
+
if limit > limitTotal:
|
|
4793
|
+
limit = limitTotal
|
|
4794
|
+
result = EpisodePageSaved()
|
|
4137
4795
|
|
|
4138
4796
|
# build spotify web api request parameters.
|
|
4139
4797
|
urlParms:dict = \
|
|
@@ -4142,14 +4800,48 @@ class SpotifyClient:
|
|
|
4142
4800
|
'offset': offset,
|
|
4143
4801
|
}
|
|
4144
4802
|
|
|
4145
|
-
#
|
|
4146
|
-
|
|
4147
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
4148
|
-
msg.UrlParameters = urlParms
|
|
4149
|
-
self.MakeRequest('GET', msg)
|
|
4803
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
4804
|
+
while True:
|
|
4150
4805
|
|
|
4151
|
-
|
|
4152
|
-
|
|
4806
|
+
# execute spotify web api request.
|
|
4807
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/episodes')
|
|
4808
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
4809
|
+
msg.UrlParameters = urlParms
|
|
4810
|
+
self.MakeRequest('GET', msg)
|
|
4811
|
+
|
|
4812
|
+
# process results.
|
|
4813
|
+
pageObj = EpisodePageSaved(root=msg.ResponseData)
|
|
4814
|
+
|
|
4815
|
+
# trace.
|
|
4816
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
4817
|
+
|
|
4818
|
+
# was limit total argument specified?
|
|
4819
|
+
if (limitTotal <= 0):
|
|
4820
|
+
|
|
4821
|
+
# no - just return the initial page of results.
|
|
4822
|
+
result = pageObj
|
|
4823
|
+
break
|
|
4824
|
+
|
|
4825
|
+
else:
|
|
4826
|
+
|
|
4827
|
+
# append page of items to final results.
|
|
4828
|
+
item:EpisodeSaved
|
|
4829
|
+
for item in pageObj.Items:
|
|
4830
|
+
result.Items.append(item)
|
|
4831
|
+
result.Limit = result.ItemsCount
|
|
4832
|
+
if result.ItemsCount >= limitTotal:
|
|
4833
|
+
break
|
|
4834
|
+
|
|
4835
|
+
# anymore pages to process? if not, then exit the loop.
|
|
4836
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
4837
|
+
break
|
|
4838
|
+
|
|
4839
|
+
# update result object with final paging details.
|
|
4840
|
+
result.Total = pageObj.Total
|
|
4841
|
+
|
|
4842
|
+
# sort items on Name property, ascending order.
|
|
4843
|
+
if len(result.Items) > 0:
|
|
4844
|
+
result.Items.sort(key=lambda x: (x.Episode.Name or "").lower(), reverse=False)
|
|
4153
4845
|
|
|
4154
4846
|
# trace.
|
|
4155
4847
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -4223,6 +4915,9 @@ class SpotifyClient:
|
|
|
4223
4915
|
apiMethodParms.AppendKeyValue("market", market)
|
|
4224
4916
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for multiple episodes", apiMethodParms)
|
|
4225
4917
|
|
|
4918
|
+
# ensure market was either supplied or implied; default if neither.
|
|
4919
|
+
market = self._ValidateMarket(market)
|
|
4920
|
+
|
|
4226
4921
|
# build spotify web api request parameters.
|
|
4227
4922
|
urlParms:dict = \
|
|
4228
4923
|
{
|
|
@@ -4264,17 +4959,18 @@ class SpotifyClient:
|
|
|
4264
4959
|
offset:int=0,
|
|
4265
4960
|
country:str=None,
|
|
4266
4961
|
locale:str=None,
|
|
4267
|
-
timestamp:str=None
|
|
4962
|
+
timestamp:str=None,
|
|
4963
|
+
limitTotal:int=None
|
|
4268
4964
|
) -> Tuple[PlaylistPageSimplified, str]:
|
|
4269
4965
|
"""
|
|
4270
4966
|
Get a list of Spotify featured playlists (shown, for example, on a Spotify player's 'Browse' tab).
|
|
4271
4967
|
|
|
4272
4968
|
Args:
|
|
4273
4969
|
limit (int):
|
|
4274
|
-
The maximum number of items to return.
|
|
4970
|
+
The maximum number of items to return in a page of items.
|
|
4275
4971
|
Default: 20, Range: 1 to 50.
|
|
4276
4972
|
offset (int):
|
|
4277
|
-
The index of the first item to return.
|
|
4973
|
+
The page index offset of the first item to return.
|
|
4278
4974
|
Use with limit to get the next set of items.
|
|
4279
4975
|
Default: 0 (the first item).
|
|
4280
4976
|
country (str):
|
|
@@ -4300,6 +4996,12 @@ class SpotifyClient:
|
|
|
4300
4996
|
If there were no featured playlists (or there is no data) at the specified time, the response will
|
|
4301
4997
|
revert to the current UTC time.
|
|
4302
4998
|
Example: `2023-10-23T09:00:00`
|
|
4999
|
+
limitTotal (int):
|
|
5000
|
+
The maximum number of items to return for the request.
|
|
5001
|
+
If specified, this argument overrides the limit and offset argument values
|
|
5002
|
+
and paging is automatically used to retrieve all available items up to the
|
|
5003
|
+
maximum number specified.
|
|
5004
|
+
Default: None (disabled)
|
|
4303
5005
|
|
|
4304
5006
|
Returns:
|
|
4305
5007
|
A tuple of 2 objects:
|
|
@@ -4314,11 +5016,17 @@ class SpotifyClient:
|
|
|
4314
5016
|
If the method fails for any other reason.
|
|
4315
5017
|
|
|
4316
5018
|
<details>
|
|
4317
|
-
<summary>Sample Code</summary>
|
|
5019
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
4318
5020
|
```python
|
|
4319
5021
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetFeaturedPlaylists.py
|
|
4320
5022
|
```
|
|
4321
5023
|
</details>
|
|
5024
|
+
<details>
|
|
5025
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
5026
|
+
```python
|
|
5027
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetFeaturedPlaylists_AutoPaging.py
|
|
5028
|
+
```
|
|
5029
|
+
</details>
|
|
4322
5030
|
"""
|
|
4323
5031
|
apiMethodName:str = 'GetFeaturedPlaylists'
|
|
4324
5032
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -4334,6 +5042,7 @@ class SpotifyClient:
|
|
|
4334
5042
|
apiMethodParms.AppendKeyValue("country", country)
|
|
4335
5043
|
apiMethodParms.AppendKeyValue("locale", locale)
|
|
4336
5044
|
apiMethodParms.AppendKeyValue("timestamp", timestamp)
|
|
5045
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
4337
5046
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of Spotify featured playlists", apiMethodParms)
|
|
4338
5047
|
|
|
4339
5048
|
# validations.
|
|
@@ -4341,6 +5050,16 @@ class SpotifyClient:
|
|
|
4341
5050
|
limit = 20
|
|
4342
5051
|
if offset is None:
|
|
4343
5052
|
offset = 0
|
|
5053
|
+
if not isinstance(limitTotal, int):
|
|
5054
|
+
limitTotal = 0
|
|
5055
|
+
|
|
5056
|
+
# are we auto-paging? if so, then use max limit.
|
|
5057
|
+
if limitTotal > 0:
|
|
5058
|
+
limit = 50
|
|
5059
|
+
#limit = 2 # TEST TODO
|
|
5060
|
+
if limit > limitTotal:
|
|
5061
|
+
limit = limitTotal
|
|
5062
|
+
result = PlaylistPageSimplified()
|
|
4344
5063
|
|
|
4345
5064
|
# build spotify web api request parameters.
|
|
4346
5065
|
urlParms:dict = \
|
|
@@ -4355,18 +5074,52 @@ class SpotifyClient:
|
|
|
4355
5074
|
if timestamp is not None:
|
|
4356
5075
|
urlParms['timestamp'] = timestamp
|
|
4357
5076
|
|
|
4358
|
-
#
|
|
4359
|
-
|
|
4360
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
4361
|
-
msg.UrlParameters = urlParms
|
|
4362
|
-
self.MakeRequest('GET', msg)
|
|
5077
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
5078
|
+
while True:
|
|
4363
5079
|
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
5080
|
+
# execute spotify web api request.
|
|
5081
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/browse/featured-playlists')
|
|
5082
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5083
|
+
msg.UrlParameters = urlParms
|
|
5084
|
+
self.MakeRequest('GET', msg)
|
|
5085
|
+
|
|
5086
|
+
# process results.
|
|
5087
|
+
resultMessage = msg.ResponseData.get('message','unknown')
|
|
5088
|
+
item = msg.ResponseData.get('playlists',None)
|
|
5089
|
+
if item is not None:
|
|
5090
|
+
pageObj = PlaylistPageSimplified(root=item)
|
|
4369
5091
|
|
|
5092
|
+
# trace.
|
|
5093
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
5094
|
+
|
|
5095
|
+
# was limit total argument specified?
|
|
5096
|
+
if (limitTotal <= 0):
|
|
5097
|
+
|
|
5098
|
+
# no - just return the initial page of results.
|
|
5099
|
+
result = pageObj
|
|
5100
|
+
break
|
|
5101
|
+
|
|
5102
|
+
else:
|
|
5103
|
+
|
|
5104
|
+
# append page of items to final results.
|
|
5105
|
+
item:PlaylistSimplified
|
|
5106
|
+
for item in pageObj.Items:
|
|
5107
|
+
result.Items.append(item)
|
|
5108
|
+
result.Limit = result.ItemsCount
|
|
5109
|
+
if result.ItemsCount >= limitTotal:
|
|
5110
|
+
break
|
|
5111
|
+
|
|
5112
|
+
# anymore pages to process? if not, then exit the loop.
|
|
5113
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
5114
|
+
break
|
|
5115
|
+
|
|
5116
|
+
# update result object with final paging details.
|
|
5117
|
+
result.Total = pageObj.Total
|
|
5118
|
+
|
|
5119
|
+
# sort items on Name property, ascending order.
|
|
5120
|
+
if len(result.Items) > 0:
|
|
5121
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
5122
|
+
|
|
4370
5123
|
# trace.
|
|
4371
5124
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
4372
5125
|
return result, resultMessage
|
|
@@ -4480,17 +5233,10 @@ class SpotifyClient:
|
|
|
4480
5233
|
|
|
4481
5234
|
No exceptions are raised with this method.
|
|
4482
5235
|
"""
|
|
4483
|
-
apiMethodName:str = 'GetIdFromUri'
|
|
4484
|
-
apiMethodParms:SIMethodParmListContext = None
|
|
4485
5236
|
result:str = None
|
|
4486
5237
|
|
|
4487
5238
|
try:
|
|
4488
5239
|
|
|
4489
|
-
# trace.
|
|
4490
|
-
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
4491
|
-
apiMethodParms.AppendKeyValue("uri", uri)
|
|
4492
|
-
_logsi.LogMethodParmList(SILevel.Verbose, "Get Id portion of a Spotify Uri value", apiMethodParms)
|
|
4493
|
-
|
|
4494
5240
|
# validations.
|
|
4495
5241
|
if uri is None or len(uri.strip()) == 0:
|
|
4496
5242
|
return result
|
|
@@ -4502,19 +5248,12 @@ class SpotifyClient:
|
|
|
4502
5248
|
if idx > -1:
|
|
4503
5249
|
result = uri[idx+1:]
|
|
4504
5250
|
|
|
4505
|
-
# trace.
|
|
4506
|
-
_logsi.LogValue(SILevel.Verbose, 'Spotify Id', result)
|
|
4507
5251
|
return result
|
|
4508
5252
|
|
|
4509
5253
|
except Exception:
|
|
4510
5254
|
|
|
4511
5255
|
return None
|
|
4512
5256
|
|
|
4513
|
-
finally:
|
|
4514
|
-
|
|
4515
|
-
# trace.
|
|
4516
|
-
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
4517
|
-
|
|
4518
5257
|
|
|
4519
5258
|
def GetMarkets(self,
|
|
4520
5259
|
refresh:bool=True
|
|
@@ -4827,6 +5566,9 @@ class SpotifyClient:
|
|
|
4827
5566
|
apiMethodParms.AppendKeyValue("market", market)
|
|
4828
5567
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get the object currently being played on the user's Spotify account", apiMethodParms)
|
|
4829
5568
|
|
|
5569
|
+
# ensure market was either supplied or implied; default if neither.
|
|
5570
|
+
market = self._ValidateMarket(market)
|
|
5571
|
+
|
|
4830
5572
|
# build spotify web api request parameters.
|
|
4831
5573
|
urlParms:dict = {}
|
|
4832
5574
|
if market is not None:
|
|
@@ -4915,6 +5657,9 @@ class SpotifyClient:
|
|
|
4915
5657
|
apiMethodParms.AppendKeyValue("market", market)
|
|
4916
5658
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get the user's current playback state", apiMethodParms)
|
|
4917
5659
|
|
|
5660
|
+
# ensure market was either supplied or implied; default if neither.
|
|
5661
|
+
market = self._ValidateMarket(market)
|
|
5662
|
+
|
|
4918
5663
|
# build spotify web api request parameters.
|
|
4919
5664
|
urlParms:dict = {}
|
|
4920
5665
|
if market is not None:
|
|
@@ -5018,7 +5763,7 @@ class SpotifyClient:
|
|
|
5018
5763
|
|
|
5019
5764
|
Args:
|
|
5020
5765
|
limit (int):
|
|
5021
|
-
The maximum number of items to return.
|
|
5766
|
+
The maximum number of items to return in a page of items.
|
|
5022
5767
|
Default: `20`, Range: `1` to `50`.
|
|
5023
5768
|
after (int):
|
|
5024
5769
|
Returns all items after (but not including) this cursor position, which is
|
|
@@ -5035,6 +5780,9 @@ class SpotifyClient:
|
|
|
5035
5780
|
|
|
5036
5781
|
The `after` and `before` arguments are based upon local time (not UTC time). Recently
|
|
5037
5782
|
played item history uses a local timestamp, and NOT a UTC timestamp.
|
|
5783
|
+
|
|
5784
|
+
If both `after` and `before` arguments are null (or zero), then an `after` value
|
|
5785
|
+
is generated that will retrieve recently played tracks for the past 24 hours.
|
|
5038
5786
|
|
|
5039
5787
|
Returns:
|
|
5040
5788
|
A `PlayHistoryPage` object that contains the recently played items.
|
|
@@ -5072,15 +5820,31 @@ class SpotifyClient:
|
|
|
5072
5820
|
apiMethodParms.AppendKeyValue("after", after)
|
|
5073
5821
|
apiMethodParms.AppendKeyValue("before", before)
|
|
5074
5822
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get tracks from the current user's recently played tracks", apiMethodParms)
|
|
5823
|
+
|
|
5824
|
+
# validations.
|
|
5825
|
+
if after is None:
|
|
5826
|
+
after = 0
|
|
5827
|
+
if (not isinstance(after,int)):
|
|
5828
|
+
after = int(after)
|
|
5829
|
+
|
|
5830
|
+
if before is None:
|
|
5831
|
+
before = 0
|
|
5832
|
+
if (not isinstance(before,int)):
|
|
5833
|
+
before = int(before)
|
|
5834
|
+
|
|
5835
|
+
# if no after or before, then get all tracks played within the past 24 hours.
|
|
5836
|
+
if (after == 0) and (before == 0):
|
|
5837
|
+
after = GetUnixTimestampMSFromUtcNow(hours=-24)
|
|
5838
|
+
_logsi.LogVerbose("Defaulting to retrieve play history for the past 24 hours (after = %d)" % after)
|
|
5075
5839
|
|
|
5076
5840
|
# build spotify web api request parameters.
|
|
5077
5841
|
urlParms:dict = \
|
|
5078
5842
|
{
|
|
5079
5843
|
'limit': limit,
|
|
5080
5844
|
}
|
|
5081
|
-
if after
|
|
5845
|
+
if after > 0:
|
|
5082
5846
|
urlParms['after'] = after
|
|
5083
|
-
if before
|
|
5847
|
+
if before > 0:
|
|
5084
5848
|
urlParms['before'] = before
|
|
5085
5849
|
|
|
5086
5850
|
# execute spotify web api request.
|
|
@@ -5182,6 +5946,9 @@ class SpotifyClient:
|
|
|
5182
5946
|
apiMethodParms.AppendKeyValue("additionalTypes", additionalTypes)
|
|
5183
5947
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a playlist owned by a Spotify user", apiMethodParms)
|
|
5184
5948
|
|
|
5949
|
+
# ensure market was either supplied or implied; default if neither.
|
|
5950
|
+
market = self._ValidateMarket(market)
|
|
5951
|
+
|
|
5185
5952
|
# build spotify web api request parameters.
|
|
5186
5953
|
urlParms:dict = {}
|
|
5187
5954
|
if market is not None:
|
|
@@ -5291,7 +6058,8 @@ class SpotifyClient:
|
|
|
5291
6058
|
offset:int=0,
|
|
5292
6059
|
market:str=None,
|
|
5293
6060
|
fields:str=None,
|
|
5294
|
-
additionalTypes:str=None
|
|
6061
|
+
additionalTypes:str=None,
|
|
6062
|
+
limitTotal:int=None
|
|
5295
6063
|
) -> PlaylistPage:
|
|
5296
6064
|
"""
|
|
5297
6065
|
Get full details of the items of a playlist owned by a Spotify user.
|
|
@@ -5303,10 +6071,10 @@ class SpotifyClient:
|
|
|
5303
6071
|
The Spotify ID of the playlist.
|
|
5304
6072
|
Example: `5v5ETK9WFXAnGQ3MRubKuE`
|
|
5305
6073
|
limit (int):
|
|
5306
|
-
The maximum number of items to return.
|
|
6074
|
+
The maximum number of items to return in a page of items.
|
|
5307
6075
|
Default: 50, Range: 1 to 50.
|
|
5308
6076
|
offset (int):
|
|
5309
|
-
The index of the first item to return.
|
|
6077
|
+
The page index offset of the first item to return.
|
|
5310
6078
|
Use with limit to get the next set of items.
|
|
5311
6079
|
Default: 0 (the first item).
|
|
5312
6080
|
market (str):
|
|
@@ -5337,6 +6105,12 @@ class SpotifyClient:
|
|
|
5337
6105
|
Note: This parameter was introduced to allow existing clients to maintain their current behaviour
|
|
5338
6106
|
and might be deprecated in the future. In addition to providing this parameter, make sure that your
|
|
5339
6107
|
client properly handles cases of new types in the future by checking against the type field of each object.
|
|
6108
|
+
limitTotal (int):
|
|
6109
|
+
The maximum number of items to return for the request.
|
|
6110
|
+
If specified, this argument overrides the limit and offset argument values
|
|
6111
|
+
and paging is automatically used to retrieve all available items up to the
|
|
6112
|
+
maximum number specified.
|
|
6113
|
+
Default: None (disabled)
|
|
5340
6114
|
|
|
5341
6115
|
Returns:
|
|
5342
6116
|
A `Playlist` object that contains the playlist details.
|
|
@@ -5349,11 +6123,17 @@ class SpotifyClient:
|
|
|
5349
6123
|
If the method fails for any other reason.
|
|
5350
6124
|
|
|
5351
6125
|
<details>
|
|
5352
|
-
<summary>Sample Code</summary>
|
|
6126
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
5353
6127
|
```python
|
|
5354
6128
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetPlaylistItems.py
|
|
5355
6129
|
```
|
|
5356
6130
|
</details>
|
|
6131
|
+
<details>
|
|
6132
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
6133
|
+
```python
|
|
6134
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetPlaylistItems_AutoPaging.py
|
|
6135
|
+
```
|
|
6136
|
+
</details>
|
|
5357
6137
|
"""
|
|
5358
6138
|
apiMethodName:str = 'GetPlaylistItems'
|
|
5359
6139
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -5369,6 +6149,7 @@ class SpotifyClient:
|
|
|
5369
6149
|
apiMethodParms.AppendKeyValue("market", market)
|
|
5370
6150
|
apiMethodParms.AppendKeyValue("fields", fields)
|
|
5371
6151
|
apiMethodParms.AppendKeyValue("additionalTypes", additionalTypes)
|
|
6152
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
5372
6153
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get full details of the items of a playlist owned by a Spotify user", apiMethodParms)
|
|
5373
6154
|
|
|
5374
6155
|
# validations.
|
|
@@ -5376,6 +6157,19 @@ class SpotifyClient:
|
|
|
5376
6157
|
limit = 20
|
|
5377
6158
|
if offset is None:
|
|
5378
6159
|
offset = 0
|
|
6160
|
+
if not isinstance(limitTotal, int):
|
|
6161
|
+
limitTotal = 0
|
|
6162
|
+
|
|
6163
|
+
# are we auto-paging? if so, then use max limit.
|
|
6164
|
+
if limitTotal > 0:
|
|
6165
|
+
limit = 50
|
|
6166
|
+
#limit = 2 # TEST TODO
|
|
6167
|
+
if limit > limitTotal:
|
|
6168
|
+
limit = limitTotal
|
|
6169
|
+
result = PlaylistPage()
|
|
6170
|
+
|
|
6171
|
+
# ensure market was either supplied or implied; default if neither.
|
|
6172
|
+
market = self._ValidateMarket(market)
|
|
5379
6173
|
|
|
5380
6174
|
# build spotify web api request parameters.
|
|
5381
6175
|
urlParms:dict = \
|
|
@@ -5390,17 +6184,49 @@ class SpotifyClient:
|
|
|
5390
6184
|
if additionalTypes is not None:
|
|
5391
6185
|
urlParms['additional_types'] = additionalTypes
|
|
5392
6186
|
|
|
5393
|
-
#
|
|
5394
|
-
|
|
5395
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5396
|
-
msg.UrlParameters = urlParms
|
|
5397
|
-
self.MakeRequest('GET', msg)
|
|
6187
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
6188
|
+
while True:
|
|
5398
6189
|
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
6190
|
+
# execute spotify web api request.
|
|
6191
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/playlists/{id}/tracks'.format(id=playlistId))
|
|
6192
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
6193
|
+
msg.UrlParameters = urlParms
|
|
6194
|
+
self.MakeRequest('GET', msg)
|
|
6195
|
+
|
|
6196
|
+
# process results.
|
|
6197
|
+
pageObj = PlaylistPage(root=msg.ResponseData)
|
|
6198
|
+
|
|
6199
|
+
# trace.
|
|
6200
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
6201
|
+
|
|
6202
|
+
# was limit total argument specified?
|
|
6203
|
+
if (limitTotal <= 0):
|
|
6204
|
+
|
|
6205
|
+
# no - just return the initial page of results.
|
|
6206
|
+
result = pageObj
|
|
6207
|
+
break
|
|
6208
|
+
|
|
6209
|
+
else:
|
|
6210
|
+
|
|
6211
|
+
# append page of items to final results.
|
|
6212
|
+
item:PlaylistTrack
|
|
6213
|
+
for item in pageObj.Items:
|
|
6214
|
+
result.Items.append(item)
|
|
6215
|
+
result.Limit = result.ItemsCount
|
|
6216
|
+
if result.ItemsCount >= limitTotal:
|
|
6217
|
+
break
|
|
6218
|
+
|
|
6219
|
+
# anymore pages to process? if not, then exit the loop.
|
|
6220
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
6221
|
+
break
|
|
6222
|
+
|
|
6223
|
+
# update result object with final paging details.
|
|
6224
|
+
result.Total = pageObj.Total
|
|
6225
|
+
|
|
6226
|
+
# do not sort this list, as it is in play order.
|
|
6227
|
+
|
|
5402
6228
|
# trace.
|
|
5403
|
-
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
6229
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
5404
6230
|
return result
|
|
5405
6231
|
|
|
5406
6232
|
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
@@ -5419,6 +6245,7 @@ class SpotifyClient:
|
|
|
5419
6245
|
def GetPlaylistFavorites(self,
|
|
5420
6246
|
limit:int=20,
|
|
5421
6247
|
offset:int=0,
|
|
6248
|
+
limitTotal:int=None
|
|
5422
6249
|
) -> PlaylistPageSimplified:
|
|
5423
6250
|
"""
|
|
5424
6251
|
Get a list of the playlists owned or followed by the current Spotify user.
|
|
@@ -5427,12 +6254,18 @@ class SpotifyClient:
|
|
|
5427
6254
|
|
|
5428
6255
|
Args:
|
|
5429
6256
|
limit (int):
|
|
5430
|
-
The maximum number of items to return.
|
|
6257
|
+
The maximum number of items to return in a page of items.
|
|
5431
6258
|
Default: 20, Range: 1 to 50.
|
|
5432
6259
|
offset (int):
|
|
5433
|
-
The index of the first item to return.
|
|
6260
|
+
The page index offset of the first item to return.
|
|
5434
6261
|
Use with limit to get the next set of items.
|
|
5435
6262
|
Default: 0 (the first item).
|
|
6263
|
+
limitTotal (int):
|
|
6264
|
+
The maximum number of items to return for the request.
|
|
6265
|
+
If specified, this argument overrides the limit and offset argument values
|
|
6266
|
+
and paging is automatically used to retrieve all available items up to the
|
|
6267
|
+
maximum number specified.
|
|
6268
|
+
Default: None (disabled)
|
|
5436
6269
|
|
|
5437
6270
|
Returns:
|
|
5438
6271
|
An `PlaylistPageSimplified` object that contains playlist information.
|
|
@@ -5445,11 +6278,17 @@ class SpotifyClient:
|
|
|
5445
6278
|
If the method fails for any other reason.
|
|
5446
6279
|
|
|
5447
6280
|
<details>
|
|
5448
|
-
<summary>Sample Code</summary>
|
|
6281
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
5449
6282
|
```python
|
|
5450
6283
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetPlaylistFavorites.py
|
|
5451
6284
|
```
|
|
5452
6285
|
</details>
|
|
6286
|
+
<details>
|
|
6287
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
6288
|
+
```python
|
|
6289
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetPlaylistFavorites_AutoPaging.py
|
|
6290
|
+
```
|
|
6291
|
+
</details>
|
|
5453
6292
|
"""
|
|
5454
6293
|
apiMethodName:str = 'GetPlaylistFavorites'
|
|
5455
6294
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -5461,6 +6300,7 @@ class SpotifyClient:
|
|
|
5461
6300
|
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
5462
6301
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
5463
6302
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
6303
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
5464
6304
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the users playlist favorites", apiMethodParms)
|
|
5465
6305
|
|
|
5466
6306
|
# validations.
|
|
@@ -5468,6 +6308,16 @@ class SpotifyClient:
|
|
|
5468
6308
|
limit = 20
|
|
5469
6309
|
if offset is None:
|
|
5470
6310
|
offset = 0
|
|
6311
|
+
if not isinstance(limitTotal, int):
|
|
6312
|
+
limitTotal = 0
|
|
6313
|
+
|
|
6314
|
+
# are we auto-paging? if so, then use max limit.
|
|
6315
|
+
if limitTotal > 0:
|
|
6316
|
+
limit = 50
|
|
6317
|
+
#limit = 2 # TEST TODO
|
|
6318
|
+
if limit > limitTotal:
|
|
6319
|
+
limit = limitTotal
|
|
6320
|
+
result = PlaylistPageSimplified()
|
|
5471
6321
|
|
|
5472
6322
|
# build spotify web api request parameters.
|
|
5473
6323
|
urlParms:dict = \
|
|
@@ -5476,14 +6326,48 @@ class SpotifyClient:
|
|
|
5476
6326
|
'offset': offset,
|
|
5477
6327
|
}
|
|
5478
6328
|
|
|
5479
|
-
#
|
|
5480
|
-
|
|
5481
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5482
|
-
msg.UrlParameters = urlParms
|
|
5483
|
-
self.MakeRequest('GET', msg)
|
|
6329
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
6330
|
+
while True:
|
|
5484
6331
|
|
|
5485
|
-
|
|
5486
|
-
|
|
6332
|
+
# execute spotify web api request.
|
|
6333
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/playlists')
|
|
6334
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
6335
|
+
msg.UrlParameters = urlParms
|
|
6336
|
+
self.MakeRequest('GET', msg)
|
|
6337
|
+
|
|
6338
|
+
# process results.
|
|
6339
|
+
pageObj = PlaylistPageSimplified(root=msg.ResponseData)
|
|
6340
|
+
|
|
6341
|
+
# trace.
|
|
6342
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
6343
|
+
|
|
6344
|
+
# was limit total argument specified?
|
|
6345
|
+
if (limitTotal <= 0):
|
|
6346
|
+
|
|
6347
|
+
# no - just return the initial page of results.
|
|
6348
|
+
result = pageObj
|
|
6349
|
+
break
|
|
6350
|
+
|
|
6351
|
+
else:
|
|
6352
|
+
|
|
6353
|
+
# append page of items to final results.
|
|
6354
|
+
item:PlaylistSimplified
|
|
6355
|
+
for item in pageObj.Items:
|
|
6356
|
+
result.Items.append(item)
|
|
6357
|
+
result.Limit = result.ItemsCount
|
|
6358
|
+
if result.ItemsCount >= limitTotal:
|
|
6359
|
+
break
|
|
6360
|
+
|
|
6361
|
+
# anymore pages to process? if not, then exit the loop.
|
|
6362
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
6363
|
+
break
|
|
6364
|
+
|
|
6365
|
+
# update result object with final paging details.
|
|
6366
|
+
result.Total = pageObj.Total
|
|
6367
|
+
|
|
6368
|
+
# sort items on Name property, ascending order.
|
|
6369
|
+
if len(result.Items) > 0:
|
|
6370
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
5487
6371
|
|
|
5488
6372
|
# trace.
|
|
5489
6373
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -5506,6 +6390,7 @@ class SpotifyClient:
|
|
|
5506
6390
|
userId:str,
|
|
5507
6391
|
limit:int=20,
|
|
5508
6392
|
offset:int=0,
|
|
6393
|
+
limitTotal:int=None
|
|
5509
6394
|
) -> PlaylistPageSimplified:
|
|
5510
6395
|
"""
|
|
5511
6396
|
Get a list of the playlists owned or followed by a Spotify user.
|
|
@@ -5517,12 +6402,18 @@ class SpotifyClient:
|
|
|
5517
6402
|
The user's Spotify user ID.
|
|
5518
6403
|
Example: `smedjan`
|
|
5519
6404
|
limit (int):
|
|
5520
|
-
The maximum number of items to return.
|
|
6405
|
+
The maximum number of items to return in a page of items.
|
|
5521
6406
|
Default: 20, Range: 1 to 50.
|
|
5522
6407
|
offset (int):
|
|
5523
|
-
The index of the first item to return.
|
|
6408
|
+
The page index offset of the first item to return.
|
|
5524
6409
|
Use with limit to get the next set of items.
|
|
5525
6410
|
Default: 0 (the first item).
|
|
6411
|
+
limitTotal (int):
|
|
6412
|
+
The maximum number of items to return for the request.
|
|
6413
|
+
If specified, this argument overrides the limit and offset argument values
|
|
6414
|
+
and paging is automatically used to retrieve all available items up to the
|
|
6415
|
+
maximum number specified.
|
|
6416
|
+
Default: None (disabled)
|
|
5526
6417
|
|
|
5527
6418
|
Returns:
|
|
5528
6419
|
An `PlaylistPageSimplified` object that contains playlist information.
|
|
@@ -5535,11 +6426,17 @@ class SpotifyClient:
|
|
|
5535
6426
|
If the method fails for any other reason.
|
|
5536
6427
|
|
|
5537
6428
|
<details>
|
|
5538
|
-
<summary>Sample Code</summary>
|
|
6429
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
5539
6430
|
```python
|
|
5540
6431
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetPlaylistsForUser.py
|
|
5541
6432
|
```
|
|
5542
6433
|
</details>
|
|
6434
|
+
<details>
|
|
6435
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
6436
|
+
```python
|
|
6437
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetPlaylistsForUser_AutoPaging.py
|
|
6438
|
+
```
|
|
6439
|
+
</details>
|
|
5543
6440
|
"""
|
|
5544
6441
|
apiMethodName:str = 'GetPlaylistsForUser'
|
|
5545
6442
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -5552,6 +6449,7 @@ class SpotifyClient:
|
|
|
5552
6449
|
apiMethodParms.AppendKeyValue("userId", userId)
|
|
5553
6450
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
5554
6451
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
6452
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
5555
6453
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the playlists owned or followed by a Spotify user", apiMethodParms)
|
|
5556
6454
|
|
|
5557
6455
|
# validations.
|
|
@@ -5559,6 +6457,16 @@ class SpotifyClient:
|
|
|
5559
6457
|
limit = 20
|
|
5560
6458
|
if offset is None:
|
|
5561
6459
|
offset = 0
|
|
6460
|
+
if not isinstance(limitTotal, int):
|
|
6461
|
+
limitTotal = 0
|
|
6462
|
+
|
|
6463
|
+
# are we auto-paging? if so, then use max limit.
|
|
6464
|
+
if limitTotal > 0:
|
|
6465
|
+
limit = 50
|
|
6466
|
+
#limit = 2 # TEST TODO
|
|
6467
|
+
if limit > limitTotal:
|
|
6468
|
+
limit = limitTotal
|
|
6469
|
+
result = PlaylistPageSimplified()
|
|
5562
6470
|
|
|
5563
6471
|
# build spotify web api request parameters.
|
|
5564
6472
|
urlParms:dict = \
|
|
@@ -5568,14 +6476,48 @@ class SpotifyClient:
|
|
|
5568
6476
|
'offset': offset,
|
|
5569
6477
|
}
|
|
5570
6478
|
|
|
5571
|
-
#
|
|
5572
|
-
|
|
5573
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5574
|
-
msg.UrlParameters = urlParms
|
|
5575
|
-
self.MakeRequest('GET', msg)
|
|
6479
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
6480
|
+
while True:
|
|
5576
6481
|
|
|
5577
|
-
|
|
5578
|
-
|
|
6482
|
+
# execute spotify web api request.
|
|
6483
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/users/{user_id}/playlists'.format(user_id=userId))
|
|
6484
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
6485
|
+
msg.UrlParameters = urlParms
|
|
6486
|
+
self.MakeRequest('GET', msg)
|
|
6487
|
+
|
|
6488
|
+
# process results.
|
|
6489
|
+
pageObj = PlaylistPageSimplified(root=msg.ResponseData)
|
|
6490
|
+
|
|
6491
|
+
# trace.
|
|
6492
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
6493
|
+
|
|
6494
|
+
# was limit total argument specified?
|
|
6495
|
+
if (limitTotal <= 0):
|
|
6496
|
+
|
|
6497
|
+
# no - just return the initial page of results.
|
|
6498
|
+
result = pageObj
|
|
6499
|
+
break
|
|
6500
|
+
|
|
6501
|
+
else:
|
|
6502
|
+
|
|
6503
|
+
# append page of items to final results.
|
|
6504
|
+
item:PlaylistSimplified
|
|
6505
|
+
for item in pageObj.Items:
|
|
6506
|
+
result.Items.append(item)
|
|
6507
|
+
result.Limit = result.ItemsCount
|
|
6508
|
+
if result.ItemsCount >= limitTotal:
|
|
6509
|
+
break
|
|
6510
|
+
|
|
6511
|
+
# anymore pages to process? if not, then exit the loop.
|
|
6512
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
6513
|
+
break
|
|
6514
|
+
|
|
6515
|
+
# update result object with final paging details.
|
|
6516
|
+
result.Total = pageObj.Total
|
|
6517
|
+
|
|
6518
|
+
# sort items on Name property, ascending order.
|
|
6519
|
+
if len(result.Items) > 0:
|
|
6520
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
5579
6521
|
|
|
5580
6522
|
# trace.
|
|
5581
6523
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -5648,6 +6590,9 @@ class SpotifyClient:
|
|
|
5648
6590
|
apiMethodParms.AppendKeyValue("market", market)
|
|
5649
6591
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for a single show", apiMethodParms)
|
|
5650
6592
|
|
|
6593
|
+
# ensure market was either supplied or implied; default if neither.
|
|
6594
|
+
market = self._ValidateMarket(market)
|
|
6595
|
+
|
|
5651
6596
|
# build spotify web api request parameters.
|
|
5652
6597
|
urlParms:dict = {}
|
|
5653
6598
|
if market is not None:
|
|
@@ -5683,7 +6628,8 @@ class SpotifyClient:
|
|
|
5683
6628
|
showId:str,
|
|
5684
6629
|
limit:int=20,
|
|
5685
6630
|
offset:int=0,
|
|
5686
|
-
market:str=None
|
|
6631
|
+
market:str=None,
|
|
6632
|
+
limitTotal:int=None
|
|
5687
6633
|
) -> EpisodePageSimplified:
|
|
5688
6634
|
"""
|
|
5689
6635
|
Get Spotify catalog information about a show's episodes.
|
|
@@ -5695,7 +6641,7 @@ class SpotifyClient:
|
|
|
5695
6641
|
The Spotify ID for the show.
|
|
5696
6642
|
Example: `38bS44xjbVVZ3No3ByF1dJ`
|
|
5697
6643
|
limit (int):
|
|
5698
|
-
The maximum number of items to return.
|
|
6644
|
+
The maximum number of items to return in a page of items.
|
|
5699
6645
|
Default: 20, Range: 1 to 50.
|
|
5700
6646
|
offset (int):
|
|
5701
6647
|
The index of the first item to return; use with limit to get the next set of items.
|
|
@@ -5708,6 +6654,12 @@ class SpotifyClient:
|
|
|
5708
6654
|
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
5709
6655
|
Users can view the country that is associated with their account in the account settings.
|
|
5710
6656
|
Example: `ES`
|
|
6657
|
+
limitTotal (int):
|
|
6658
|
+
The maximum number of items to return for the request.
|
|
6659
|
+
If specified, this argument overrides the limit and offset argument values
|
|
6660
|
+
and paging is automatically used to retrieve all available items up to the
|
|
6661
|
+
maximum number specified.
|
|
6662
|
+
Default: None (disabled)
|
|
5711
6663
|
|
|
5712
6664
|
Returns:
|
|
5713
6665
|
A `EpisodePageSimplified` object that contains simplified track information for the showId.
|
|
@@ -5720,11 +6672,17 @@ class SpotifyClient:
|
|
|
5720
6672
|
If the method fails for any other reason.
|
|
5721
6673
|
|
|
5722
6674
|
<details>
|
|
5723
|
-
<summary>Sample Code</summary>
|
|
6675
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
5724
6676
|
```python
|
|
5725
6677
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetShowEpisodes.py
|
|
5726
6678
|
```
|
|
5727
6679
|
</details>
|
|
6680
|
+
<details>
|
|
6681
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
6682
|
+
```python
|
|
6683
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetShowEpisodes_AutoPaging.py
|
|
6684
|
+
```
|
|
6685
|
+
</details>
|
|
5728
6686
|
"""
|
|
5729
6687
|
apiMethodName:str = 'GetShowEpisodes'
|
|
5730
6688
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -5738,6 +6696,7 @@ class SpotifyClient:
|
|
|
5738
6696
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
5739
6697
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
5740
6698
|
apiMethodParms.AppendKeyValue("market", market)
|
|
6699
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
5741
6700
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information about a show's episodes", apiMethodParms)
|
|
5742
6701
|
|
|
5743
6702
|
# validations.
|
|
@@ -5745,6 +6704,19 @@ class SpotifyClient:
|
|
|
5745
6704
|
limit = 20
|
|
5746
6705
|
if offset is None:
|
|
5747
6706
|
offset = 0
|
|
6707
|
+
if not isinstance(limitTotal, int):
|
|
6708
|
+
limitTotal = 0
|
|
6709
|
+
|
|
6710
|
+
# are we auto-paging? if so, then use max limit.
|
|
6711
|
+
if limitTotal > 0:
|
|
6712
|
+
limit = 50
|
|
6713
|
+
#limit = 2 # TEST TODO
|
|
6714
|
+
if limit > limitTotal:
|
|
6715
|
+
limit = limitTotal
|
|
6716
|
+
result = EpisodePageSimplified()
|
|
6717
|
+
|
|
6718
|
+
# ensure market was either supplied or implied; default if neither.
|
|
6719
|
+
market = self._ValidateMarket(market)
|
|
5748
6720
|
|
|
5749
6721
|
# build spotify web api request parameters.
|
|
5750
6722
|
urlParms:dict = \
|
|
@@ -5755,14 +6727,46 @@ class SpotifyClient:
|
|
|
5755
6727
|
if market is not None:
|
|
5756
6728
|
urlParms['market'] = market
|
|
5757
6729
|
|
|
5758
|
-
#
|
|
5759
|
-
|
|
5760
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5761
|
-
msg.UrlParameters = urlParms
|
|
5762
|
-
self.MakeRequest('GET', msg)
|
|
6730
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
6731
|
+
while True:
|
|
5763
6732
|
|
|
5764
|
-
|
|
5765
|
-
|
|
6733
|
+
# execute spotify web api request.
|
|
6734
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/shows/{id}/episodes'.format(id=showId))
|
|
6735
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
6736
|
+
msg.UrlParameters = urlParms
|
|
6737
|
+
self.MakeRequest('GET', msg)
|
|
6738
|
+
|
|
6739
|
+
# process results.
|
|
6740
|
+
pageObj = EpisodePageSimplified(root=msg.ResponseData)
|
|
6741
|
+
|
|
6742
|
+
# trace.
|
|
6743
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
6744
|
+
|
|
6745
|
+
# was limit total argument specified?
|
|
6746
|
+
if (limitTotal <= 0):
|
|
6747
|
+
|
|
6748
|
+
# no - just return the initial page of results.
|
|
6749
|
+
result = pageObj
|
|
6750
|
+
break
|
|
6751
|
+
|
|
6752
|
+
else:
|
|
6753
|
+
|
|
6754
|
+
# append page of items to final results.
|
|
6755
|
+
item:EpisodeSimplified
|
|
6756
|
+
for item in pageObj.Items:
|
|
6757
|
+
result.Items.append(item)
|
|
6758
|
+
result.Limit = result.ItemsCount
|
|
6759
|
+
if result.ItemsCount >= limitTotal:
|
|
6760
|
+
break
|
|
6761
|
+
|
|
6762
|
+
# anymore pages to process? if not, then exit the loop.
|
|
6763
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
6764
|
+
break
|
|
6765
|
+
|
|
6766
|
+
# update result object with final paging details.
|
|
6767
|
+
result.Total = pageObj.Total
|
|
6768
|
+
|
|
6769
|
+
# no sort, as items are in playable order.
|
|
5766
6770
|
|
|
5767
6771
|
# trace.
|
|
5768
6772
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -5784,6 +6788,7 @@ class SpotifyClient:
|
|
|
5784
6788
|
def GetShowFavorites(self,
|
|
5785
6789
|
limit:int=20,
|
|
5786
6790
|
offset:int=0,
|
|
6791
|
+
limitTotal:int=None
|
|
5787
6792
|
) -> ShowPageSaved:
|
|
5788
6793
|
"""
|
|
5789
6794
|
Get a list of the shows saved in the current Spotify user's 'Your Library'.
|
|
@@ -5792,12 +6797,18 @@ class SpotifyClient:
|
|
|
5792
6797
|
|
|
5793
6798
|
Args:
|
|
5794
6799
|
limit (int):
|
|
5795
|
-
The maximum number of items to return.
|
|
6800
|
+
The maximum number of items to return in a page of items.
|
|
5796
6801
|
Default: 20, Range: 1 to 50.
|
|
5797
6802
|
offset (int):
|
|
5798
|
-
The index of the first item to return.
|
|
6803
|
+
The page index offset of the first item to return.
|
|
5799
6804
|
Use with limit to get the next set of items.
|
|
5800
6805
|
Default: 0 (the first item).
|
|
6806
|
+
limitTotal (int):
|
|
6807
|
+
The maximum number of items to return for the request.
|
|
6808
|
+
If specified, this argument overrides the limit and offset argument values
|
|
6809
|
+
and paging is automatically used to retrieve all available items up to the
|
|
6810
|
+
maximum number specified.
|
|
6811
|
+
Default: None (disabled)
|
|
5801
6812
|
|
|
5802
6813
|
Returns:
|
|
5803
6814
|
An `ShowPageSaved` object that contains saved show information.
|
|
@@ -5810,11 +6821,17 @@ class SpotifyClient:
|
|
|
5810
6821
|
If the method fails for any other reason.
|
|
5811
6822
|
|
|
5812
6823
|
<details>
|
|
5813
|
-
<summary>Sample Code</summary>
|
|
6824
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
5814
6825
|
```python
|
|
5815
6826
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetShowFavorites.py
|
|
5816
6827
|
```
|
|
5817
6828
|
</details>
|
|
6829
|
+
<details>
|
|
6830
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
6831
|
+
```python
|
|
6832
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetShowFavorites_AutoPaging.py
|
|
6833
|
+
```
|
|
6834
|
+
</details>
|
|
5818
6835
|
"""
|
|
5819
6836
|
apiMethodName:str = 'GetShowFavorites'
|
|
5820
6837
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -5826,6 +6843,7 @@ class SpotifyClient:
|
|
|
5826
6843
|
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
5827
6844
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
5828
6845
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
6846
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
5829
6847
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the users show favorites", apiMethodParms)
|
|
5830
6848
|
|
|
5831
6849
|
# validations.
|
|
@@ -5833,6 +6851,16 @@ class SpotifyClient:
|
|
|
5833
6851
|
limit = 20
|
|
5834
6852
|
if offset is None:
|
|
5835
6853
|
offset = 0
|
|
6854
|
+
if not isinstance(limitTotal, int):
|
|
6855
|
+
limitTotal = 0
|
|
6856
|
+
|
|
6857
|
+
# are we auto-paging? if so, then use max limit.
|
|
6858
|
+
if limitTotal > 0:
|
|
6859
|
+
limit = 50
|
|
6860
|
+
#limit = 2 # TEST TODO
|
|
6861
|
+
if limit > limitTotal:
|
|
6862
|
+
limit = limitTotal
|
|
6863
|
+
result = ShowPageSaved()
|
|
5836
6864
|
|
|
5837
6865
|
# build spotify web api request parameters.
|
|
5838
6866
|
urlParms:dict = \
|
|
@@ -5841,14 +6869,48 @@ class SpotifyClient:
|
|
|
5841
6869
|
'offset': offset,
|
|
5842
6870
|
}
|
|
5843
6871
|
|
|
5844
|
-
#
|
|
5845
|
-
|
|
5846
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5847
|
-
msg.UrlParameters = urlParms
|
|
5848
|
-
self.MakeRequest('GET', msg)
|
|
6872
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
6873
|
+
while True:
|
|
5849
6874
|
|
|
5850
|
-
|
|
5851
|
-
|
|
6875
|
+
# execute spotify web api request.
|
|
6876
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/shows')
|
|
6877
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
6878
|
+
msg.UrlParameters = urlParms
|
|
6879
|
+
self.MakeRequest('GET', msg)
|
|
6880
|
+
|
|
6881
|
+
# process results.
|
|
6882
|
+
pageObj = ShowPageSaved(root=msg.ResponseData)
|
|
6883
|
+
|
|
6884
|
+
# trace.
|
|
6885
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
6886
|
+
|
|
6887
|
+
# was limit total argument specified?
|
|
6888
|
+
if (limitTotal <= 0):
|
|
6889
|
+
|
|
6890
|
+
# no - just return the initial page of results.
|
|
6891
|
+
result = pageObj
|
|
6892
|
+
break
|
|
6893
|
+
|
|
6894
|
+
else:
|
|
6895
|
+
|
|
6896
|
+
# append page of items to final results.
|
|
6897
|
+
item:AlbumSaved
|
|
6898
|
+
for item in pageObj.Items:
|
|
6899
|
+
result.Items.append(item)
|
|
6900
|
+
result.Limit = result.ItemsCount
|
|
6901
|
+
if result.ItemsCount >= limitTotal:
|
|
6902
|
+
break
|
|
6903
|
+
|
|
6904
|
+
# anymore pages to process? if not, then exit the loop.
|
|
6905
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
6906
|
+
break
|
|
6907
|
+
|
|
6908
|
+
# update result object with final paging details.
|
|
6909
|
+
result.Total = pageObj.Total
|
|
6910
|
+
|
|
6911
|
+
# sort items on Name property, ascending order.
|
|
6912
|
+
if len(result.Items) > 0:
|
|
6913
|
+
result.Items.sort(key=lambda x: (x.Show.Name or "").lower(), reverse=False)
|
|
5852
6914
|
|
|
5853
6915
|
# trace.
|
|
5854
6916
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -5922,6 +6984,9 @@ class SpotifyClient:
|
|
|
5922
6984
|
apiMethodParms.AppendKeyValue("market", market)
|
|
5923
6985
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for multiple shows", apiMethodParms)
|
|
5924
6986
|
|
|
6987
|
+
# ensure market was either supplied or implied; default if neither.
|
|
6988
|
+
market = self._ValidateMarket(market)
|
|
6989
|
+
|
|
5925
6990
|
# build spotify web api request parameters.
|
|
5926
6991
|
urlParms:dict = \
|
|
5927
6992
|
{
|
|
@@ -6090,6 +7155,7 @@ class SpotifyClient:
|
|
|
6090
7155
|
limit:int=20,
|
|
6091
7156
|
offset:int=0,
|
|
6092
7157
|
market:str=None,
|
|
7158
|
+
limitTotal:int=None
|
|
6093
7159
|
) -> TrackPageSaved:
|
|
6094
7160
|
"""
|
|
6095
7161
|
Get a list of the tracks saved in the current Spotify user's 'Your Library'.
|
|
@@ -6098,10 +7164,10 @@ class SpotifyClient:
|
|
|
6098
7164
|
|
|
6099
7165
|
Args:
|
|
6100
7166
|
limit (int):
|
|
6101
|
-
The maximum number of items to return.
|
|
7167
|
+
The maximum number of items to return in a page of items.
|
|
6102
7168
|
Default: 20, Range: 1 to 50.
|
|
6103
7169
|
offset (int):
|
|
6104
|
-
The index of the first item to return.
|
|
7170
|
+
The page index offset of the first item to return.
|
|
6105
7171
|
Use with limit to get the next set of items.
|
|
6106
7172
|
Default: 0 (the first item).
|
|
6107
7173
|
market (str):
|
|
@@ -6112,6 +7178,12 @@ class SpotifyClient:
|
|
|
6112
7178
|
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
6113
7179
|
Users can view the country that is associated with their account in the account settings.
|
|
6114
7180
|
Example: `ES`
|
|
7181
|
+
limitTotal (int):
|
|
7182
|
+
The maximum number of items to return for the request.
|
|
7183
|
+
If specified, this argument overrides the limit and offset argument values
|
|
7184
|
+
and paging is automatically used to retrieve all available items up to the
|
|
7185
|
+
maximum number specified.
|
|
7186
|
+
Default: None (disabled)
|
|
6115
7187
|
|
|
6116
7188
|
Returns:
|
|
6117
7189
|
An `TrackPageSaved` object that contains saved track information.
|
|
@@ -6124,11 +7196,17 @@ class SpotifyClient:
|
|
|
6124
7196
|
If the method fails for any other reason.
|
|
6125
7197
|
|
|
6126
7198
|
<details>
|
|
6127
|
-
<summary>Sample Code</summary>
|
|
7199
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
6128
7200
|
```python
|
|
6129
7201
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetTrackFavorites.py
|
|
6130
7202
|
```
|
|
6131
7203
|
</details>
|
|
7204
|
+
<details>
|
|
7205
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
7206
|
+
```python
|
|
7207
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetTrackFavorites_AutoPaging.py
|
|
7208
|
+
```
|
|
7209
|
+
</details>
|
|
6132
7210
|
"""
|
|
6133
7211
|
apiMethodName:str = 'GetTrackFavorites'
|
|
6134
7212
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -6141,6 +7219,7 @@ class SpotifyClient:
|
|
|
6141
7219
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
6142
7220
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
6143
7221
|
apiMethodParms.AppendKeyValue("market", market)
|
|
7222
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
6144
7223
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the users track favorites", apiMethodParms)
|
|
6145
7224
|
|
|
6146
7225
|
# validations.
|
|
@@ -6148,6 +7227,19 @@ class SpotifyClient:
|
|
|
6148
7227
|
limit = 20
|
|
6149
7228
|
if offset is None:
|
|
6150
7229
|
offset = 0
|
|
7230
|
+
if not isinstance(limitTotal, int):
|
|
7231
|
+
limitTotal = 0
|
|
7232
|
+
|
|
7233
|
+
# are we auto-paging? if so, then use max limit.
|
|
7234
|
+
if limitTotal > 0:
|
|
7235
|
+
limit = 50
|
|
7236
|
+
#limit = 2 # TEST TODO
|
|
7237
|
+
if limit > limitTotal:
|
|
7238
|
+
limit = limitTotal
|
|
7239
|
+
result = TrackPageSaved()
|
|
7240
|
+
|
|
7241
|
+
# ensure market was either supplied or implied; default if neither.
|
|
7242
|
+
market = self._ValidateMarket(market)
|
|
6151
7243
|
|
|
6152
7244
|
# build spotify web api request parameters.
|
|
6153
7245
|
urlParms:dict = \
|
|
@@ -6158,15 +7250,49 @@ class SpotifyClient:
|
|
|
6158
7250
|
if market is not None:
|
|
6159
7251
|
urlParms['market'] = market
|
|
6160
7252
|
|
|
6161
|
-
#
|
|
6162
|
-
|
|
6163
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
6164
|
-
msg.UrlParameters = urlParms
|
|
6165
|
-
self.MakeRequest('GET', msg)
|
|
7253
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
7254
|
+
while True:
|
|
6166
7255
|
|
|
6167
|
-
|
|
6168
|
-
|
|
7256
|
+
# execute spotify web api request.
|
|
7257
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/tracks')
|
|
7258
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
7259
|
+
msg.UrlParameters = urlParms
|
|
7260
|
+
self.MakeRequest('GET', msg)
|
|
7261
|
+
|
|
7262
|
+
# process results.
|
|
7263
|
+
pageObj = TrackPageSaved(root=msg.ResponseData)
|
|
6169
7264
|
|
|
7265
|
+
# trace.
|
|
7266
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
7267
|
+
|
|
7268
|
+
# was limit total argument specified?
|
|
7269
|
+
if (limitTotal <= 0):
|
|
7270
|
+
|
|
7271
|
+
# no - just return the initial page of results.
|
|
7272
|
+
result = pageObj
|
|
7273
|
+
break
|
|
7274
|
+
|
|
7275
|
+
else:
|
|
7276
|
+
|
|
7277
|
+
# append page of items to final results.
|
|
7278
|
+
item:TrackSaved
|
|
7279
|
+
for item in pageObj.Items:
|
|
7280
|
+
result.Items.append(item)
|
|
7281
|
+
result.Limit = result.ItemsCount
|
|
7282
|
+
if result.ItemsCount >= limitTotal:
|
|
7283
|
+
break
|
|
7284
|
+
|
|
7285
|
+
# anymore pages to process? if not, then exit the loop.
|
|
7286
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
7287
|
+
break
|
|
7288
|
+
|
|
7289
|
+
# update result object with final paging details.
|
|
7290
|
+
result.Total = pageObj.Total
|
|
7291
|
+
|
|
7292
|
+
# sort items on Name property, ascending order.
|
|
7293
|
+
if len(result.Items) > 0:
|
|
7294
|
+
result.Items.sort(key=lambda x: (x.Track.Name or "").lower(), reverse=False)
|
|
7295
|
+
|
|
6170
7296
|
# trace.
|
|
6171
7297
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
6172
7298
|
return result
|
|
@@ -6234,6 +7360,9 @@ class SpotifyClient:
|
|
|
6234
7360
|
apiMethodParms.AppendKeyValue("market", market)
|
|
6235
7361
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for multiple tracks", apiMethodParms)
|
|
6236
7362
|
|
|
7363
|
+
# ensure market was either supplied or implied; default if neither.
|
|
7364
|
+
market = self._ValidateMarket(market)
|
|
7365
|
+
|
|
6237
7366
|
# build spotify web api request parameters.
|
|
6238
7367
|
urlParms:dict = \
|
|
6239
7368
|
{
|
|
@@ -6373,7 +7502,7 @@ class SpotifyClient:
|
|
|
6373
7502
|
|
|
6374
7503
|
Args:
|
|
6375
7504
|
limit (int):
|
|
6376
|
-
The maximum number of items to return.
|
|
7505
|
+
The maximum number of items to return in a page of items.
|
|
6377
7506
|
Default: 20, Range: 1 to 50.
|
|
6378
7507
|
market (str):
|
|
6379
7508
|
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
@@ -6604,6 +7733,9 @@ class SpotifyClient:
|
|
|
6604
7733
|
apiMethodParms.AppendKeyValue("targetValence", targetValence)
|
|
6605
7734
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get track recommendations for specified criteria", apiMethodParms)
|
|
6606
7735
|
|
|
7736
|
+
# ensure market was either supplied or implied; default if neither.
|
|
7737
|
+
market = self._ValidateMarket(market)
|
|
7738
|
+
|
|
6607
7739
|
# build spotify web api request parameters.
|
|
6608
7740
|
urlParms:dict = \
|
|
6609
7741
|
{
|
|
@@ -6759,17 +7891,10 @@ class SpotifyClient:
|
|
|
6759
7891
|
|
|
6760
7892
|
No exceptions are raised with this method.
|
|
6761
7893
|
"""
|
|
6762
|
-
apiMethodName:str = 'GetTypeFromUri'
|
|
6763
|
-
apiMethodParms:SIMethodParmListContext = None
|
|
6764
7894
|
result:str = None
|
|
6765
7895
|
|
|
6766
7896
|
try:
|
|
6767
7897
|
|
|
6768
|
-
# trace.
|
|
6769
|
-
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
6770
|
-
apiMethodParms.AppendKeyValue("uri", uri)
|
|
6771
|
-
_logsi.LogMethodParmList(SILevel.Verbose, "Get Type portion of a Spotify Uri value", apiMethodParms)
|
|
6772
|
-
|
|
6773
7898
|
# validations.
|
|
6774
7899
|
if uri is None or len(uri.strip()) == 0:
|
|
6775
7900
|
return result
|
|
@@ -6785,8 +7910,6 @@ class SpotifyClient:
|
|
|
6785
7910
|
if idxEnd > -1:
|
|
6786
7911
|
result = uri[idxStart+1:idxEnd]
|
|
6787
7912
|
|
|
6788
|
-
# trace.
|
|
6789
|
-
_logsi.LogValue(SILevel.Verbose, 'Spotify Type', result)
|
|
6790
7913
|
return result
|
|
6791
7914
|
|
|
6792
7915
|
except Exception as ex:
|
|
@@ -6794,11 +7917,6 @@ class SpotifyClient:
|
|
|
6794
7917
|
_logsi.LogWarning("GetTypeFromUri failed: %s" % str(ex))
|
|
6795
7918
|
return None
|
|
6796
7919
|
|
|
6797
|
-
finally:
|
|
6798
|
-
|
|
6799
|
-
# trace.
|
|
6800
|
-
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
6801
|
-
|
|
6802
7920
|
|
|
6803
7921
|
def GetUsersCurrentProfile(self,
|
|
6804
7922
|
refresh:bool=True
|
|
@@ -6948,7 +8066,8 @@ class SpotifyClient:
|
|
|
6948
8066
|
def GetUsersTopArtists(self,
|
|
6949
8067
|
timeRange:str='medium_term',
|
|
6950
8068
|
limit:int=20,
|
|
6951
|
-
offset:int=0
|
|
8069
|
+
offset:int=0,
|
|
8070
|
+
limitTotal:int=None
|
|
6952
8071
|
) -> ArtistPage:
|
|
6953
8072
|
"""
|
|
6954
8073
|
Get the current user's top artists based on calculated affinity.
|
|
@@ -6963,12 +8082,18 @@ class SpotifyClient:
|
|
|
6963
8082
|
Default: `medium_term`
|
|
6964
8083
|
Example: `long_term`
|
|
6965
8084
|
limit (int):
|
|
6966
|
-
The maximum number of items to return.
|
|
8085
|
+
The maximum number of items to return in a page of items.
|
|
6967
8086
|
Default: 20, Range: 1 to 50.
|
|
6968
8087
|
offset (int):
|
|
6969
|
-
The index of the first item to return.
|
|
8088
|
+
The page index offset of the first item to return.
|
|
6970
8089
|
Use with limit to get the next set of items.
|
|
6971
8090
|
Default: 0 (the first item), Range: 0 to 1000
|
|
8091
|
+
limitTotal (int):
|
|
8092
|
+
The maximum number of items to return for the request.
|
|
8093
|
+
If specified, this argument overrides the limit and offset argument values
|
|
8094
|
+
and paging is automatically used to retrieve all available items up to the
|
|
8095
|
+
maximum number specified.
|
|
8096
|
+
Default: None (disabled)
|
|
6972
8097
|
|
|
6973
8098
|
Returns:
|
|
6974
8099
|
An `ArtistPage` object of matching results.
|
|
@@ -6981,11 +8106,17 @@ class SpotifyClient:
|
|
|
6981
8106
|
If the method fails for any other reason.
|
|
6982
8107
|
|
|
6983
8108
|
<details>
|
|
6984
|
-
<summary>Sample Code</summary>
|
|
8109
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
6985
8110
|
```python
|
|
6986
8111
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetUsersTopArtists.py
|
|
6987
8112
|
```
|
|
6988
8113
|
</details>
|
|
8114
|
+
<details>
|
|
8115
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
8116
|
+
```python
|
|
8117
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetUsersTopArtists_AutoPaging.py
|
|
8118
|
+
```
|
|
8119
|
+
</details>
|
|
6989
8120
|
"""
|
|
6990
8121
|
apiMethodName:str = 'GetUsersTopArtists'
|
|
6991
8122
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -6998,6 +8129,7 @@ class SpotifyClient:
|
|
|
6998
8129
|
apiMethodParms.AppendKeyValue("timeRange", timeRange)
|
|
6999
8130
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
7000
8131
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
8132
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
7001
8133
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get the current user's top artists", apiMethodParms)
|
|
7002
8134
|
|
|
7003
8135
|
# validations.
|
|
@@ -7007,6 +8139,16 @@ class SpotifyClient:
|
|
|
7007
8139
|
limit = 20
|
|
7008
8140
|
if offset is None:
|
|
7009
8141
|
offset = 0
|
|
8142
|
+
if not isinstance(limitTotal, int):
|
|
8143
|
+
limitTotal = 0
|
|
8144
|
+
|
|
8145
|
+
# are we auto-paging? if so, then use max limit.
|
|
8146
|
+
if limitTotal > 0:
|
|
8147
|
+
limit = 50
|
|
8148
|
+
#limit = 20 # TEST TODO
|
|
8149
|
+
if limit > limitTotal:
|
|
8150
|
+
limit = limitTotal
|
|
8151
|
+
result = ArtistPage()
|
|
7010
8152
|
|
|
7011
8153
|
# build spotify web api request parameters.
|
|
7012
8154
|
urlParms:dict = \
|
|
@@ -7016,17 +8158,51 @@ class SpotifyClient:
|
|
|
7016
8158
|
'offset': offset,
|
|
7017
8159
|
}
|
|
7018
8160
|
|
|
7019
|
-
#
|
|
7020
|
-
|
|
7021
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
7022
|
-
msg.UrlParameters = urlParms
|
|
7023
|
-
self.MakeRequest('GET', msg)
|
|
8161
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
8162
|
+
while True:
|
|
7024
8163
|
|
|
7025
|
-
|
|
7026
|
-
|
|
8164
|
+
# execute spotify web api request.
|
|
8165
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/top/artists')
|
|
8166
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
8167
|
+
msg.UrlParameters = urlParms
|
|
8168
|
+
self.MakeRequest('GET', msg)
|
|
8169
|
+
|
|
8170
|
+
# process results.
|
|
8171
|
+
pageObj = ArtistPage(root=msg.ResponseData)
|
|
8172
|
+
|
|
8173
|
+
# trace.
|
|
8174
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
8175
|
+
|
|
8176
|
+
# was limit total argument specified?
|
|
8177
|
+
if (limitTotal <= 0):
|
|
8178
|
+
|
|
8179
|
+
# no - just return the initial page of results.
|
|
8180
|
+
result = pageObj
|
|
8181
|
+
break
|
|
8182
|
+
|
|
8183
|
+
else:
|
|
8184
|
+
|
|
8185
|
+
# append page of items to final results.
|
|
8186
|
+
item:Artist
|
|
8187
|
+
for item in pageObj.Items:
|
|
8188
|
+
result.Items.append(item)
|
|
8189
|
+
result.Limit = result.ItemsCount
|
|
8190
|
+
if result.ItemsCount >= limitTotal:
|
|
8191
|
+
break
|
|
8192
|
+
|
|
8193
|
+
# anymore pages to process? if not, then exit the loop.
|
|
8194
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
8195
|
+
break
|
|
8196
|
+
|
|
8197
|
+
# update result object with final paging details.
|
|
8198
|
+
result.Total = pageObj.Total
|
|
8199
|
+
|
|
8200
|
+
# sort items on Name property, ascending order.
|
|
8201
|
+
if len(result.Items) > 0:
|
|
8202
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
7027
8203
|
|
|
7028
8204
|
# trace.
|
|
7029
|
-
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
8205
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
7030
8206
|
return result
|
|
7031
8207
|
|
|
7032
8208
|
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
@@ -7045,7 +8221,8 @@ class SpotifyClient:
|
|
|
7045
8221
|
def GetUsersTopTracks(self,
|
|
7046
8222
|
timeRange:str='medium_term',
|
|
7047
8223
|
limit:int=20,
|
|
7048
|
-
offset:int=0
|
|
8224
|
+
offset:int=0,
|
|
8225
|
+
limitTotal:int=None
|
|
7049
8226
|
) -> TrackPage:
|
|
7050
8227
|
"""
|
|
7051
8228
|
Get the current user's top tracks based on calculated affinity.
|
|
@@ -7060,12 +8237,18 @@ class SpotifyClient:
|
|
|
7060
8237
|
Default: `medium_term`
|
|
7061
8238
|
Example: `long_term`
|
|
7062
8239
|
limit (int):
|
|
7063
|
-
The maximum number of items to return.
|
|
8240
|
+
The maximum number of items to return in a page of items.
|
|
7064
8241
|
Default: 20, Range: 1 to 50.
|
|
7065
8242
|
offset (int):
|
|
7066
|
-
The index of the first item to return.
|
|
8243
|
+
The page index offset of the first item to return.
|
|
7067
8244
|
Use with limit to get the next set of items.
|
|
7068
|
-
Default: 0 (the first item)
|
|
8245
|
+
Default: 0 (the first item).
|
|
8246
|
+
limitTotal (int):
|
|
8247
|
+
The maximum number of items to return for the request.
|
|
8248
|
+
If specified, this argument overrides the limit and offset argument values
|
|
8249
|
+
and paging is automatically used to retrieve all available items up to the
|
|
8250
|
+
maximum number specified.
|
|
8251
|
+
Default: None (disabled)
|
|
7069
8252
|
|
|
7070
8253
|
Returns:
|
|
7071
8254
|
An `TrackPage` object of matching results.
|
|
@@ -7078,11 +8261,17 @@ class SpotifyClient:
|
|
|
7078
8261
|
If the method fails for any other reason.
|
|
7079
8262
|
|
|
7080
8263
|
<details>
|
|
7081
|
-
<summary>Sample Code</summary>
|
|
8264
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
7082
8265
|
```python
|
|
7083
8266
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetUsersTopTracks.py
|
|
7084
8267
|
```
|
|
7085
8268
|
</details>
|
|
8269
|
+
<details>
|
|
8270
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
8271
|
+
```python
|
|
8272
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/GetUsersTopTracks_AutoPaging.py
|
|
8273
|
+
```
|
|
8274
|
+
</details>
|
|
7086
8275
|
"""
|
|
7087
8276
|
apiMethodName:str = 'GetUsersTopTracks'
|
|
7088
8277
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -7095,6 +8284,7 @@ class SpotifyClient:
|
|
|
7095
8284
|
apiMethodParms.AppendKeyValue("timeRange", timeRange)
|
|
7096
8285
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
7097
8286
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
8287
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
7098
8288
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get the current user's top tracks", apiMethodParms)
|
|
7099
8289
|
|
|
7100
8290
|
# validations.
|
|
@@ -7104,6 +8294,16 @@ class SpotifyClient:
|
|
|
7104
8294
|
limit = 20
|
|
7105
8295
|
if offset is None:
|
|
7106
8296
|
offset = 0
|
|
8297
|
+
if not isinstance(limitTotal, int):
|
|
8298
|
+
limitTotal = 0
|
|
8299
|
+
|
|
8300
|
+
# are we auto-paging? if so, then use max limit.
|
|
8301
|
+
if limitTotal > 0:
|
|
8302
|
+
limit = 50
|
|
8303
|
+
#limit = 10 # TEST TODO
|
|
8304
|
+
if limit > limitTotal:
|
|
8305
|
+
limit = limitTotal
|
|
8306
|
+
result = TrackPage()
|
|
7107
8307
|
|
|
7108
8308
|
# build spotify web api request parameters.
|
|
7109
8309
|
urlParms:dict = \
|
|
@@ -7113,17 +8313,51 @@ class SpotifyClient:
|
|
|
7113
8313
|
'offset': offset,
|
|
7114
8314
|
}
|
|
7115
8315
|
|
|
7116
|
-
#
|
|
7117
|
-
|
|
7118
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
7119
|
-
msg.UrlParameters = urlParms
|
|
7120
|
-
self.MakeRequest('GET', msg)
|
|
8316
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
8317
|
+
while True:
|
|
7121
8318
|
|
|
7122
|
-
|
|
7123
|
-
|
|
8319
|
+
# execute spotify web api request.
|
|
8320
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/top/tracks')
|
|
8321
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
8322
|
+
msg.UrlParameters = urlParms
|
|
8323
|
+
self.MakeRequest('GET', msg)
|
|
8324
|
+
|
|
8325
|
+
# process results.
|
|
8326
|
+
pageObj = TrackPage(root=msg.ResponseData)
|
|
8327
|
+
|
|
8328
|
+
# trace.
|
|
8329
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
8330
|
+
|
|
8331
|
+
# was limit total argument specified?
|
|
8332
|
+
if (limitTotal <= 0):
|
|
8333
|
+
|
|
8334
|
+
# no - just return the initial page of results.
|
|
8335
|
+
result = pageObj
|
|
8336
|
+
break
|
|
8337
|
+
|
|
8338
|
+
else:
|
|
8339
|
+
|
|
8340
|
+
# append page of items to final results.
|
|
8341
|
+
item:Track
|
|
8342
|
+
for item in pageObj.Items:
|
|
8343
|
+
result.Items.append(item)
|
|
8344
|
+
result.Limit = result.ItemsCount
|
|
8345
|
+
if result.ItemsCount >= limitTotal:
|
|
8346
|
+
break
|
|
8347
|
+
|
|
8348
|
+
# anymore pages to process? if not, then exit the loop.
|
|
8349
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
8350
|
+
break
|
|
8351
|
+
|
|
8352
|
+
# update result object with final paging details.
|
|
8353
|
+
result.Total = pageObj.Total
|
|
8354
|
+
|
|
8355
|
+
# sort items on Name property, ascending order.
|
|
8356
|
+
if len(result.Items) > 0:
|
|
8357
|
+
result.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
|
|
7124
8358
|
|
|
7125
8359
|
# trace.
|
|
7126
|
-
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
8360
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
7127
8361
|
return result
|
|
7128
8362
|
|
|
7129
8363
|
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
@@ -9223,18 +10457,192 @@ class SpotifyClient:
|
|
|
9223
10457
|
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
9224
10458
|
|
|
9225
10459
|
|
|
9226
|
-
def Search(self,
|
|
9227
|
-
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9232
|
-
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
|
|
9236
|
-
|
|
9237
|
-
|
|
10460
|
+
# def Search(self,
|
|
10461
|
+
# criteria:str,
|
|
10462
|
+
# criteriaType:str,
|
|
10463
|
+
# limit:int=20,
|
|
10464
|
+
# offset:int=0,
|
|
10465
|
+
# market:str=None,
|
|
10466
|
+
# includeExternal:str=None,
|
|
10467
|
+
# ) -> SearchResponse:
|
|
10468
|
+
# """
|
|
10469
|
+
# Get Spotify catalog information about albums, artists, playlists, tracks, shows, episodes
|
|
10470
|
+
# or audiobooks that match a keyword string. Audiobooks are only available within the US, UK,
|
|
10471
|
+
# Canada, Ireland, New Zealand and Australia markets.
|
|
10472
|
+
|
|
10473
|
+
# Args:
|
|
10474
|
+
# criteria (str):
|
|
10475
|
+
# Your search query.
|
|
10476
|
+
# You can narrow down your search using field filters.
|
|
10477
|
+
# The available filters are album, artist, track, year, upc, tag:hipster, tag:new,
|
|
10478
|
+
# isrc, and genre. Each field filter only applies to certain result types.
|
|
10479
|
+
# The artist and year filters can be used while searching albums, artists and tracks.
|
|
10480
|
+
# You can filter on a single year or a range (e.g. 1955-1960).
|
|
10481
|
+
# The album filter can be used while searching albums and tracks.
|
|
10482
|
+
# The genre filter can be used while searching artists and tracks.
|
|
10483
|
+
# The isrc and track filters can be used while searching tracks.
|
|
10484
|
+
# The upc, tag:new and tag:hipster filters can only be used while searching albums.
|
|
10485
|
+
# The tag:new filter will return albums released in the past two weeks and tag:hipster
|
|
10486
|
+
# can be used to return only albums with the lowest 10% popularity.
|
|
10487
|
+
# criteriaType (str):
|
|
10488
|
+
# A comma-separated list of item types to search across.
|
|
10489
|
+
# Search results include hits from all the specified item types.
|
|
10490
|
+
# For example: "album,track" returns both albums and tracks matching criteria argument.
|
|
10491
|
+
# Allowed values: "album", "artist", "playlist", "track", "show", "episode", "audiobook".
|
|
10492
|
+
# limit (int):
|
|
10493
|
+
# The maximum number of items to return in a page of items.
|
|
10494
|
+
# Default: 20, Range: 1 to 50.
|
|
10495
|
+
# offset (int):
|
|
10496
|
+
# The page index offset of the first item to return.
|
|
10497
|
+
# Use with limit to get the next set of items.
|
|
10498
|
+
# Default: 0 (the first item). Range: 0 to 1000.
|
|
10499
|
+
# market (str):
|
|
10500
|
+
# An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
10501
|
+
# is available in that market will be returned. If a valid user access token is specified
|
|
10502
|
+
# in the request header, the country associated with the user account will take priority over
|
|
10503
|
+
# this parameter.
|
|
10504
|
+
# Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
10505
|
+
# Users can view the country that is associated with their account in the account settings.
|
|
10506
|
+
# Example: `ES`
|
|
10507
|
+
# includeExternal (str):
|
|
10508
|
+
# If "audio" is specified it signals that the client can play externally hosted audio content, and
|
|
10509
|
+
# marks the content as playable in the response. By default externally hosted audio content is marked
|
|
10510
|
+
# as unplayable in the response.
|
|
10511
|
+
# Allowed values: "audio"
|
|
10512
|
+
|
|
10513
|
+
# Returns:
|
|
10514
|
+
# A `SearchResponse` object that contains the search results.
|
|
10515
|
+
|
|
10516
|
+
# Raises:
|
|
10517
|
+
# SpotifyWebApiError:
|
|
10518
|
+
# If the Spotify Web API request was for a non-authorization service
|
|
10519
|
+
# and the response contains error information.
|
|
10520
|
+
# SpotifApiError:
|
|
10521
|
+
# If the method fails for any other reason.
|
|
10522
|
+
|
|
10523
|
+
# Note the offset limitation of 1000 entries; this effectively limits you to 1,050 maximum
|
|
10524
|
+
# entries that you can return with a search.
|
|
10525
|
+
|
|
10526
|
+
# <details>
|
|
10527
|
+
# <summary>Sample Code - Search Albums</summary>
|
|
10528
|
+
# ```python
|
|
10529
|
+
# .. include:: ../docs/include/samplecode/SpotifyClient/SearchAlbums.py
|
|
10530
|
+
# ```
|
|
10531
|
+
# </details>
|
|
10532
|
+
|
|
10533
|
+
# <details>
|
|
10534
|
+
# <summary>Sample Code - Search Artists</summary>
|
|
10535
|
+
# ```python
|
|
10536
|
+
# .. include:: ../docs/include/samplecode/SpotifyClient/SearchArtists.py
|
|
10537
|
+
# ```
|
|
10538
|
+
# </details>
|
|
10539
|
+
|
|
10540
|
+
# <details>
|
|
10541
|
+
# <summary>Sample Code - Search Audiobooks</summary>
|
|
10542
|
+
# ```python
|
|
10543
|
+
# .. include:: ../docs/include/samplecode/SpotifyClient/SearchAudiobooks.py
|
|
10544
|
+
# ```
|
|
10545
|
+
# </details>
|
|
10546
|
+
|
|
10547
|
+
# <details>
|
|
10548
|
+
# <summary>Sample Code - Search Episodes</summary>
|
|
10549
|
+
# ```python
|
|
10550
|
+
# .. include:: ../docs/include/samplecode/SpotifyClient/SearchEpisodes.py
|
|
10551
|
+
# ```
|
|
10552
|
+
# </details>
|
|
10553
|
+
|
|
10554
|
+
# <details>
|
|
10555
|
+
# <summary>Sample Code - Search Playlists</summary>
|
|
10556
|
+
# ```python
|
|
10557
|
+
# .. include:: ../docs/include/samplecode/SpotifyClient/SearchPlaylists.py
|
|
10558
|
+
# ```
|
|
10559
|
+
# </details>
|
|
10560
|
+
|
|
10561
|
+
# <details>
|
|
10562
|
+
# <summary>Sample Code - Search Shows</summary>
|
|
10563
|
+
# ```python
|
|
10564
|
+
# .. include:: ../docs/include/samplecode/SpotifyClient/SearchShows.py
|
|
10565
|
+
# ```
|
|
10566
|
+
# </details>
|
|
10567
|
+
|
|
10568
|
+
# <details>
|
|
10569
|
+
# <summary>Sample Code - Search Tracks</summary>
|
|
10570
|
+
# ```python
|
|
10571
|
+
# .. include:: ../docs/include/samplecode/SpotifyClient/SearchTracks.py
|
|
10572
|
+
# ```
|
|
10573
|
+
# </details>
|
|
10574
|
+
# """
|
|
10575
|
+
# apiMethodName:str = 'Search'
|
|
10576
|
+
# apiMethodParms:SIMethodParmListContext = None
|
|
10577
|
+
# result:SearchResponse = None
|
|
10578
|
+
|
|
10579
|
+
# try:
|
|
10580
|
+
|
|
10581
|
+
# # trace.
|
|
10582
|
+
# apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
10583
|
+
# apiMethodParms.AppendKeyValue("criteria", criteria)
|
|
10584
|
+
# apiMethodParms.AppendKeyValue("criteriaType", criteriaType)
|
|
10585
|
+
# apiMethodParms.AppendKeyValue("limit", limit)
|
|
10586
|
+
# apiMethodParms.AppendKeyValue("offset", offset)
|
|
10587
|
+
# apiMethodParms.AppendKeyValue("market", market)
|
|
10588
|
+
# apiMethodParms.AppendKeyValue("includeExternal", includeExternal)
|
|
10589
|
+
# _logsi.LogMethodParmList(SILevel.Verbose, "Searching Spotify catalog for information.", apiMethodParms)
|
|
10590
|
+
|
|
10591
|
+
# # validations.
|
|
10592
|
+
# if limit is None:
|
|
10593
|
+
# limit = 20
|
|
10594
|
+
# if offset is None:
|
|
10595
|
+
# offset = 0
|
|
10596
|
+
|
|
10597
|
+
# # build spotify web api request parameters.
|
|
10598
|
+
# urlParms:dict = \
|
|
10599
|
+
# {
|
|
10600
|
+
# 'q': criteria,
|
|
10601
|
+
# 'type': criteriaType,
|
|
10602
|
+
# 'limit': limit,
|
|
10603
|
+
# 'offset': offset,
|
|
10604
|
+
# }
|
|
10605
|
+
# if market is not None:
|
|
10606
|
+
# urlParms['market'] = market
|
|
10607
|
+
# if includeExternal is not None:
|
|
10608
|
+
# urlParms['include_external'] = includeExternal
|
|
10609
|
+
|
|
10610
|
+
# # execute spotify web api request.
|
|
10611
|
+
# msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/search')
|
|
10612
|
+
# msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
10613
|
+
# msg.UrlParameters = urlParms
|
|
10614
|
+
# self.MakeRequest('GET', msg)
|
|
10615
|
+
|
|
10616
|
+
# # process results.
|
|
10617
|
+
# result = SearchResponse(criteria, criteriaType, root=msg.ResponseData)
|
|
10618
|
+
|
|
10619
|
+
# # trace.
|
|
10620
|
+
# _logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
10621
|
+
# return result
|
|
10622
|
+
|
|
10623
|
+
# except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
10624
|
+
# except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
10625
|
+
# except Exception as ex:
|
|
10626
|
+
|
|
10627
|
+
# # format unhandled exception.
|
|
10628
|
+
# raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
10629
|
+
|
|
10630
|
+
# finally:
|
|
10631
|
+
|
|
10632
|
+
# # trace.
|
|
10633
|
+
# _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
10634
|
+
|
|
10635
|
+
|
|
10636
|
+
def SearchAlbums(self,
|
|
10637
|
+
criteria:str,
|
|
10638
|
+
limit:int=20,
|
|
10639
|
+
offset:int=0,
|
|
10640
|
+
market:str=None,
|
|
10641
|
+
includeExternal:str=None,
|
|
10642
|
+
limitTotal:int=None
|
|
10643
|
+
) -> SearchResponse:
|
|
10644
|
+
"""
|
|
10645
|
+
Get Spotify catalog information about Albums that match a keyword string.
|
|
9238
10646
|
|
|
9239
10647
|
Args:
|
|
9240
10648
|
criteria (str):
|
|
@@ -9250,18 +10658,13 @@ class SpotifyClient:
|
|
|
9250
10658
|
The upc, tag:new and tag:hipster filters can only be used while searching albums.
|
|
9251
10659
|
The tag:new filter will return albums released in the past two weeks and tag:hipster
|
|
9252
10660
|
can be used to return only albums with the lowest 10% popularity.
|
|
9253
|
-
criteriaType (str):
|
|
9254
|
-
A comma-separated list of item types to search across.
|
|
9255
|
-
Search results include hits from all the specified item types.
|
|
9256
|
-
For example: "album,track" returns both albums and tracks matching criteria argument.
|
|
9257
|
-
Allowed values: "album", "artist", "playlist", "track", "show", "episode", "audiobook".
|
|
9258
10661
|
limit (int):
|
|
9259
|
-
The maximum number of items to return.
|
|
10662
|
+
The maximum number of items to return in a page of items.
|
|
9260
10663
|
Default: 20, Range: 1 to 50.
|
|
9261
10664
|
offset (int):
|
|
9262
|
-
The index of the first item to return.
|
|
10665
|
+
The page index offset of the first item to return.
|
|
9263
10666
|
Use with limit to get the next set of items.
|
|
9264
|
-
Default: 0 (the first item)
|
|
10667
|
+
Default: 0 (the first item). Range: 0 to 1000.
|
|
9265
10668
|
market (str):
|
|
9266
10669
|
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
9267
10670
|
is available in that market will be returned. If a valid user access token is specified
|
|
@@ -9275,6 +10678,12 @@ class SpotifyClient:
|
|
|
9275
10678
|
marks the content as playable in the response. By default externally hosted audio content is marked
|
|
9276
10679
|
as unplayable in the response.
|
|
9277
10680
|
Allowed values: "audio"
|
|
10681
|
+
limitTotal (int):
|
|
10682
|
+
The maximum number of items to return for the request.
|
|
10683
|
+
If specified, this argument overrides the limit and offset argument values
|
|
10684
|
+
and paging is automatically used to retrieve all available items up to the
|
|
10685
|
+
maximum number specified.
|
|
10686
|
+
Default: None (disabled)
|
|
9278
10687
|
|
|
9279
10688
|
Returns:
|
|
9280
10689
|
A `SearchResponse` object that contains the search results.
|
|
@@ -9286,61 +10695,26 @@ class SpotifyClient:
|
|
|
9286
10695
|
SpotifApiError:
|
|
9287
10696
|
If the method fails for any other reason.
|
|
9288
10697
|
|
|
9289
|
-
Note
|
|
9290
|
-
|
|
10698
|
+
Note that Spotify Web API automatically limits you to 1,000 max entries per type that can
|
|
10699
|
+
be returned with a search.
|
|
9291
10700
|
|
|
9292
10701
|
<details>
|
|
9293
|
-
<summary>Sample Code -
|
|
10702
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
9294
10703
|
```python
|
|
9295
10704
|
.. include:: ../docs/include/samplecode/SpotifyClient/SearchAlbums.py
|
|
9296
10705
|
```
|
|
9297
10706
|
</details>
|
|
9298
|
-
|
|
9299
|
-
<details>
|
|
9300
|
-
<summary>Sample Code - Search Artists</summary>
|
|
9301
|
-
```python
|
|
9302
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/SearchArtists.py
|
|
9303
|
-
```
|
|
9304
|
-
</details>
|
|
9305
|
-
|
|
9306
|
-
<details>
|
|
9307
|
-
<summary>Sample Code - Search Audiobooks</summary>
|
|
9308
|
-
```python
|
|
9309
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/SearchAudiobooks.py
|
|
9310
|
-
```
|
|
9311
|
-
</details>
|
|
9312
|
-
|
|
9313
|
-
<details>
|
|
9314
|
-
<summary>Sample Code - Search Episodes</summary>
|
|
9315
|
-
```python
|
|
9316
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/SearchEpisodes.py
|
|
9317
|
-
```
|
|
9318
|
-
</details>
|
|
9319
|
-
|
|
9320
|
-
<details>
|
|
9321
|
-
<summary>Sample Code - Search Playlists</summary>
|
|
9322
|
-
```python
|
|
9323
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/SearchPlaylists.py
|
|
9324
|
-
```
|
|
9325
|
-
</details>
|
|
9326
|
-
|
|
9327
|
-
<details>
|
|
9328
|
-
<summary>Sample Code - Search Shows</summary>
|
|
9329
|
-
```python
|
|
9330
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/SearchShows.py
|
|
9331
|
-
```
|
|
9332
|
-
</details>
|
|
9333
|
-
|
|
9334
10707
|
<details>
|
|
9335
|
-
<summary>Sample Code -
|
|
10708
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
9336
10709
|
```python
|
|
9337
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/
|
|
10710
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchAlbums_AutoPaging.py
|
|
9338
10711
|
```
|
|
9339
10712
|
</details>
|
|
9340
10713
|
"""
|
|
9341
|
-
apiMethodName:str = '
|
|
10714
|
+
apiMethodName:str = 'SearchAlbums'
|
|
9342
10715
|
apiMethodParms:SIMethodParmListContext = None
|
|
9343
|
-
|
|
10716
|
+
criteriaType:str = 'album'
|
|
10717
|
+
result:AlbumPageSimplified = None
|
|
9344
10718
|
|
|
9345
10719
|
try:
|
|
9346
10720
|
|
|
@@ -9352,13 +10726,26 @@ class SpotifyClient:
|
|
|
9352
10726
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
9353
10727
|
apiMethodParms.AppendKeyValue("market", market)
|
|
9354
10728
|
apiMethodParms.AppendKeyValue("includeExternal", includeExternal)
|
|
9355
|
-
|
|
10729
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
10730
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Searching Spotify catalog for %s information" % criteriaType, apiMethodParms)
|
|
9356
10731
|
|
|
9357
10732
|
# validations.
|
|
9358
10733
|
if limit is None:
|
|
9359
10734
|
limit = 20
|
|
9360
10735
|
if offset is None:
|
|
9361
10736
|
offset = 0
|
|
10737
|
+
if not isinstance(limitTotal, int):
|
|
10738
|
+
limitTotal = 0
|
|
10739
|
+
|
|
10740
|
+
# are we auto-paging? if so, then use max limit.
|
|
10741
|
+
if limitTotal > 0:
|
|
10742
|
+
limit = 50
|
|
10743
|
+
if limit > limitTotal:
|
|
10744
|
+
limit = limitTotal
|
|
10745
|
+
result = AlbumPageSimplified()
|
|
10746
|
+
|
|
10747
|
+
# ensure market was either supplied or implied; default if neither.
|
|
10748
|
+
market = self._ValidateMarket(market)
|
|
9362
10749
|
|
|
9363
10750
|
# build spotify web api request parameters.
|
|
9364
10751
|
urlParms:dict = \
|
|
@@ -9373,18 +10760,1203 @@ class SpotifyClient:
|
|
|
9373
10760
|
if includeExternal is not None:
|
|
9374
10761
|
urlParms['include_external'] = includeExternal
|
|
9375
10762
|
|
|
9376
|
-
#
|
|
9377
|
-
|
|
9378
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
9379
|
-
msg.UrlParameters = urlParms
|
|
9380
|
-
self.MakeRequest('GET', msg)
|
|
10763
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
10764
|
+
while True:
|
|
9381
10765
|
|
|
9382
|
-
|
|
9383
|
-
|
|
10766
|
+
# execute spotify web api request.
|
|
10767
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/search')
|
|
10768
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
10769
|
+
msg.UrlParameters = urlParms
|
|
10770
|
+
self.MakeRequest('GET', msg)
|
|
10771
|
+
|
|
10772
|
+
# process results.
|
|
10773
|
+
searchResponse:SearchResponse = SearchResponse(criteria, criteriaType, root=msg.ResponseData)
|
|
10774
|
+
pageObj = searchResponse.Albums
|
|
10775
|
+
|
|
10776
|
+
# trace.
|
|
10777
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
10778
|
+
|
|
10779
|
+
# was limit total argument specified?
|
|
10780
|
+
if (limitTotal <= 0):
|
|
10781
|
+
|
|
10782
|
+
# no - just return the initial page of results.
|
|
10783
|
+
result = pageObj
|
|
10784
|
+
break
|
|
10785
|
+
|
|
10786
|
+
else:
|
|
10787
|
+
|
|
10788
|
+
# append page of items to final results.
|
|
10789
|
+
item:AlbumSimplified
|
|
10790
|
+
for item in pageObj.Items:
|
|
10791
|
+
result.Items.append(item)
|
|
10792
|
+
result.Limit = result.ItemsCount
|
|
10793
|
+
if result.ItemsCount >= limitTotal:
|
|
10794
|
+
break
|
|
10795
|
+
|
|
10796
|
+
# anymore pages to process? if not, then exit the loop.
|
|
10797
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
10798
|
+
break
|
|
10799
|
+
|
|
10800
|
+
# update result object with final paging details.
|
|
10801
|
+
result.Total = pageObj.Total
|
|
10802
|
+
|
|
10803
|
+
# do not sort, as spotify uses intelligent AI to return results in its order.
|
|
9384
10804
|
|
|
9385
10805
|
# trace.
|
|
9386
|
-
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
9387
|
-
|
|
10806
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
10807
|
+
|
|
10808
|
+
# return a search response object.
|
|
10809
|
+
response:SearchResponse = SearchResponse(criteria, criteriaType)
|
|
10810
|
+
response.Albums = result
|
|
10811
|
+
return response
|
|
10812
|
+
|
|
10813
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
10814
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
10815
|
+
except Exception as ex:
|
|
10816
|
+
|
|
10817
|
+
# format unhandled exception.
|
|
10818
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
10819
|
+
|
|
10820
|
+
finally:
|
|
10821
|
+
|
|
10822
|
+
# trace.
|
|
10823
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
10824
|
+
|
|
10825
|
+
|
|
10826
|
+
def SearchArtists(self,
|
|
10827
|
+
criteria:str,
|
|
10828
|
+
limit:int=20,
|
|
10829
|
+
offset:int=0,
|
|
10830
|
+
market:str=None,
|
|
10831
|
+
includeExternal:str=None,
|
|
10832
|
+
limitTotal:int=None
|
|
10833
|
+
) -> SearchResponse:
|
|
10834
|
+
"""
|
|
10835
|
+
Get Spotify catalog information about Artists that match a keyword string.
|
|
10836
|
+
|
|
10837
|
+
Args:
|
|
10838
|
+
criteria (str):
|
|
10839
|
+
Your search query.
|
|
10840
|
+
You can narrow down your search using field filters.
|
|
10841
|
+
The available filters are album, artist, track, year, upc, tag:hipster, tag:new,
|
|
10842
|
+
isrc, and genre. Each field filter only applies to certain result types.
|
|
10843
|
+
The artist and year filters can be used while searching albums, artists and tracks.
|
|
10844
|
+
You can filter on a single year or a range (e.g. 1955-1960).
|
|
10845
|
+
The album filter can be used while searching albums and tracks.
|
|
10846
|
+
The genre filter can be used while searching artists and tracks.
|
|
10847
|
+
The isrc and track filters can be used while searching tracks.
|
|
10848
|
+
The upc, tag:new and tag:hipster filters can only be used while searching albums.
|
|
10849
|
+
The tag:new filter will return albums released in the past two weeks and tag:hipster
|
|
10850
|
+
can be used to return only albums with the lowest 10% popularity.
|
|
10851
|
+
limit (int):
|
|
10852
|
+
The maximum number of items to return in a page of items.
|
|
10853
|
+
Default: 20, Range: 1 to 50.
|
|
10854
|
+
offset (int):
|
|
10855
|
+
The page index offset of the first item to return.
|
|
10856
|
+
Use with limit to get the next set of items.
|
|
10857
|
+
Default: 0 (the first item). Range: 0 to 1000.
|
|
10858
|
+
market (str):
|
|
10859
|
+
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
10860
|
+
is available in that market will be returned. If a valid user access token is specified
|
|
10861
|
+
in the request header, the country associated with the user account will take priority over
|
|
10862
|
+
this parameter.
|
|
10863
|
+
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
10864
|
+
Users can view the country that is associated with their account in the account settings.
|
|
10865
|
+
Example: `ES`
|
|
10866
|
+
includeExternal (str):
|
|
10867
|
+
If "audio" is specified it signals that the client can play externally hosted audio content, and
|
|
10868
|
+
marks the content as playable in the response. By default externally hosted audio content is marked
|
|
10869
|
+
as unplayable in the response.
|
|
10870
|
+
Allowed values: "audio"
|
|
10871
|
+
limitTotal (int):
|
|
10872
|
+
The maximum number of items to return for the request.
|
|
10873
|
+
If specified, this argument overrides the limit and offset argument values
|
|
10874
|
+
and paging is automatically used to retrieve all available items up to the
|
|
10875
|
+
maximum number specified.
|
|
10876
|
+
Default: None (disabled)
|
|
10877
|
+
|
|
10878
|
+
Returns:
|
|
10879
|
+
A `SearchResponse` object that contains the search results.
|
|
10880
|
+
|
|
10881
|
+
Raises:
|
|
10882
|
+
SpotifyWebApiError:
|
|
10883
|
+
If the Spotify Web API request was for a non-authorization service
|
|
10884
|
+
and the response contains error information.
|
|
10885
|
+
SpotifApiError:
|
|
10886
|
+
If the method fails for any other reason.
|
|
10887
|
+
|
|
10888
|
+
Note that Spotify Web API automatically limits you to 1,000 max entries per type that can
|
|
10889
|
+
be returned with a search.
|
|
10890
|
+
|
|
10891
|
+
<details>
|
|
10892
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
10893
|
+
```python
|
|
10894
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchArtists.py
|
|
10895
|
+
```
|
|
10896
|
+
</details>
|
|
10897
|
+
<details>
|
|
10898
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
10899
|
+
```python
|
|
10900
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchArtists_AutoPaging.py
|
|
10901
|
+
```
|
|
10902
|
+
</details>
|
|
10903
|
+
"""
|
|
10904
|
+
apiMethodName:str = 'SearchArtists'
|
|
10905
|
+
apiMethodParms:SIMethodParmListContext = None
|
|
10906
|
+
criteriaType:str = 'artist'
|
|
10907
|
+
result:ArtistPage = None
|
|
10908
|
+
|
|
10909
|
+
try:
|
|
10910
|
+
|
|
10911
|
+
# trace.
|
|
10912
|
+
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
10913
|
+
apiMethodParms.AppendKeyValue("criteria", criteria)
|
|
10914
|
+
apiMethodParms.AppendKeyValue("criteriaType", criteriaType)
|
|
10915
|
+
apiMethodParms.AppendKeyValue("limit", limit)
|
|
10916
|
+
apiMethodParms.AppendKeyValue("offset", offset)
|
|
10917
|
+
apiMethodParms.AppendKeyValue("market", market)
|
|
10918
|
+
apiMethodParms.AppendKeyValue("includeExternal", includeExternal)
|
|
10919
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
10920
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Searching Spotify catalog for %s information" % criteriaType, apiMethodParms)
|
|
10921
|
+
|
|
10922
|
+
# validations.
|
|
10923
|
+
if limit is None:
|
|
10924
|
+
limit = 20
|
|
10925
|
+
if offset is None:
|
|
10926
|
+
offset = 0
|
|
10927
|
+
if not isinstance(limitTotal, int):
|
|
10928
|
+
limitTotal = 0
|
|
10929
|
+
|
|
10930
|
+
# are we auto-paging? if so, then use max limit.
|
|
10931
|
+
if limitTotal > 0:
|
|
10932
|
+
limit = 50
|
|
10933
|
+
if limit > limitTotal:
|
|
10934
|
+
limit = limitTotal
|
|
10935
|
+
result = ArtistPage()
|
|
10936
|
+
|
|
10937
|
+
# ensure market was either supplied or implied; default if neither.
|
|
10938
|
+
market = self._ValidateMarket(market)
|
|
10939
|
+
|
|
10940
|
+
# build spotify web api request parameters.
|
|
10941
|
+
urlParms:dict = \
|
|
10942
|
+
{
|
|
10943
|
+
'q': criteria,
|
|
10944
|
+
'type': criteriaType,
|
|
10945
|
+
'limit': limit,
|
|
10946
|
+
'offset': offset,
|
|
10947
|
+
}
|
|
10948
|
+
if market is not None:
|
|
10949
|
+
urlParms['market'] = market
|
|
10950
|
+
if includeExternal is not None:
|
|
10951
|
+
urlParms['include_external'] = includeExternal
|
|
10952
|
+
|
|
10953
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
10954
|
+
while True:
|
|
10955
|
+
|
|
10956
|
+
# execute spotify web api request.
|
|
10957
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/search')
|
|
10958
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
10959
|
+
msg.UrlParameters = urlParms
|
|
10960
|
+
self.MakeRequest('GET', msg)
|
|
10961
|
+
|
|
10962
|
+
# process results.
|
|
10963
|
+
searchResponse:SearchResponse = SearchResponse(criteria, criteriaType, root=msg.ResponseData)
|
|
10964
|
+
pageObj = searchResponse.Artists
|
|
10965
|
+
|
|
10966
|
+
# trace.
|
|
10967
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
10968
|
+
|
|
10969
|
+
# was limit total argument specified?
|
|
10970
|
+
if (limitTotal <= 0):
|
|
10971
|
+
|
|
10972
|
+
# no - just return the initial page of results.
|
|
10973
|
+
result = pageObj
|
|
10974
|
+
break
|
|
10975
|
+
|
|
10976
|
+
else:
|
|
10977
|
+
|
|
10978
|
+
# append page of items to final results.
|
|
10979
|
+
item:Artist
|
|
10980
|
+
for item in pageObj.Items:
|
|
10981
|
+
result.Items.append(item)
|
|
10982
|
+
result.Limit = result.ItemsCount
|
|
10983
|
+
if result.ItemsCount >= limitTotal:
|
|
10984
|
+
break
|
|
10985
|
+
|
|
10986
|
+
# anymore pages to process? if not, then exit the loop.
|
|
10987
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
10988
|
+
break
|
|
10989
|
+
|
|
10990
|
+
# update result object with final paging details.
|
|
10991
|
+
result.Total = pageObj.Total
|
|
10992
|
+
|
|
10993
|
+
# do not sort, as spotify uses intelligent AI to return results in its order.
|
|
10994
|
+
|
|
10995
|
+
# trace.
|
|
10996
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
10997
|
+
|
|
10998
|
+
# return a search response object.
|
|
10999
|
+
response:SearchResponse = SearchResponse(criteria, criteriaType)
|
|
11000
|
+
response.Artists = result
|
|
11001
|
+
return response
|
|
11002
|
+
|
|
11003
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
11004
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
11005
|
+
except Exception as ex:
|
|
11006
|
+
|
|
11007
|
+
# format unhandled exception.
|
|
11008
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
11009
|
+
|
|
11010
|
+
finally:
|
|
11011
|
+
|
|
11012
|
+
# trace.
|
|
11013
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
11014
|
+
|
|
11015
|
+
|
|
11016
|
+
def SearchAudiobooks(self,
|
|
11017
|
+
criteria:str,
|
|
11018
|
+
limit:int=20,
|
|
11019
|
+
offset:int=0,
|
|
11020
|
+
market:str=None,
|
|
11021
|
+
includeExternal:str=None,
|
|
11022
|
+
limitTotal:int=None
|
|
11023
|
+
) -> SearchResponse:
|
|
11024
|
+
"""
|
|
11025
|
+
Get Spotify catalog information about Audiobooks that match a keyword string.
|
|
11026
|
+
|
|
11027
|
+
Args:
|
|
11028
|
+
criteria (str):
|
|
11029
|
+
Your search query.
|
|
11030
|
+
You can narrow down your search using field filters.
|
|
11031
|
+
The available filters are album, artist, track, year, upc, tag:hipster, tag:new,
|
|
11032
|
+
isrc, and genre. Each field filter only applies to certain result types.
|
|
11033
|
+
The artist and year filters can be used while searching albums, artists and tracks.
|
|
11034
|
+
You can filter on a single year or a range (e.g. 1955-1960).
|
|
11035
|
+
The album filter can be used while searching albums and tracks.
|
|
11036
|
+
The genre filter can be used while searching artists and tracks.
|
|
11037
|
+
The isrc and track filters can be used while searching tracks.
|
|
11038
|
+
The upc, tag:new and tag:hipster filters can only be used while searching albums.
|
|
11039
|
+
The tag:new filter will return albums released in the past two weeks and tag:hipster
|
|
11040
|
+
can be used to return only albums with the lowest 10% popularity.
|
|
11041
|
+
limit (int):
|
|
11042
|
+
The maximum number of items to return in a page of items.
|
|
11043
|
+
Default: 20, Range: 1 to 50.
|
|
11044
|
+
offset (int):
|
|
11045
|
+
The page index offset of the first item to return.
|
|
11046
|
+
Use with limit to get the next set of items.
|
|
11047
|
+
Default: 0 (the first item). Range: 0 to 1000.
|
|
11048
|
+
market (str):
|
|
11049
|
+
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
11050
|
+
is available in that market will be returned. If a valid user access token is specified
|
|
11051
|
+
in the request header, the country associated with the user account will take priority over
|
|
11052
|
+
this parameter.
|
|
11053
|
+
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
11054
|
+
Users can view the country that is associated with their account in the account settings.
|
|
11055
|
+
Example: `ES`
|
|
11056
|
+
includeExternal (str):
|
|
11057
|
+
If "audio" is specified it signals that the client can play externally hosted audio content, and
|
|
11058
|
+
marks the content as playable in the response. By default externally hosted audio content is marked
|
|
11059
|
+
as unplayable in the response.
|
|
11060
|
+
Allowed values: "audio"
|
|
11061
|
+
limitTotal (int):
|
|
11062
|
+
The maximum number of items to return for the request.
|
|
11063
|
+
If specified, this argument overrides the limit and offset argument values
|
|
11064
|
+
and paging is automatically used to retrieve all available items up to the
|
|
11065
|
+
maximum number specified.
|
|
11066
|
+
Default: None (disabled)
|
|
11067
|
+
|
|
11068
|
+
Returns:
|
|
11069
|
+
A `SearchResponse` object that contains the search results.
|
|
11070
|
+
|
|
11071
|
+
Raises:
|
|
11072
|
+
SpotifyWebApiError:
|
|
11073
|
+
If the Spotify Web API request was for a non-authorization service
|
|
11074
|
+
and the response contains error information.
|
|
11075
|
+
SpotifApiError:
|
|
11076
|
+
If the method fails for any other reason.
|
|
11077
|
+
|
|
11078
|
+
Audiobooks are only available within the US, UK, Canada, Ireland, New Zealand and Australia markets.
|
|
11079
|
+
|
|
11080
|
+
Note that Spotify Web API automatically limits you to 1,000 max entries per type that can
|
|
11081
|
+
be returned with a search.
|
|
11082
|
+
|
|
11083
|
+
<details>
|
|
11084
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
11085
|
+
```python
|
|
11086
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchAudiobooks.py
|
|
11087
|
+
```
|
|
11088
|
+
</details>
|
|
11089
|
+
<details>
|
|
11090
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
11091
|
+
```python
|
|
11092
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchAudiobooks_AutoPaging.py
|
|
11093
|
+
```
|
|
11094
|
+
</details>
|
|
11095
|
+
"""
|
|
11096
|
+
apiMethodName:str = 'SearchAudiobooks'
|
|
11097
|
+
apiMethodParms:SIMethodParmListContext = None
|
|
11098
|
+
criteriaType:str = 'audiobook'
|
|
11099
|
+
result:AudiobookPageSimplified = None
|
|
11100
|
+
|
|
11101
|
+
try:
|
|
11102
|
+
|
|
11103
|
+
# trace.
|
|
11104
|
+
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
11105
|
+
apiMethodParms.AppendKeyValue("criteria", criteria)
|
|
11106
|
+
apiMethodParms.AppendKeyValue("criteriaType", criteriaType)
|
|
11107
|
+
apiMethodParms.AppendKeyValue("limit", limit)
|
|
11108
|
+
apiMethodParms.AppendKeyValue("offset", offset)
|
|
11109
|
+
apiMethodParms.AppendKeyValue("market", market)
|
|
11110
|
+
apiMethodParms.AppendKeyValue("includeExternal", includeExternal)
|
|
11111
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
11112
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Searching Spotify catalog for %s information" % criteriaType, apiMethodParms)
|
|
11113
|
+
|
|
11114
|
+
# validations.
|
|
11115
|
+
if limit is None:
|
|
11116
|
+
limit = 20
|
|
11117
|
+
if offset is None:
|
|
11118
|
+
offset = 0
|
|
11119
|
+
if not isinstance(limitTotal, int):
|
|
11120
|
+
limitTotal = 0
|
|
11121
|
+
|
|
11122
|
+
# are we auto-paging? if so, then use max limit.
|
|
11123
|
+
if limitTotal > 0:
|
|
11124
|
+
limit = 50
|
|
11125
|
+
if limit > limitTotal:
|
|
11126
|
+
limit = limitTotal
|
|
11127
|
+
result = AudiobookPageSimplified()
|
|
11128
|
+
|
|
11129
|
+
# ensure market was either supplied or implied; default if neither.
|
|
11130
|
+
market = self._ValidateMarket(market)
|
|
11131
|
+
|
|
11132
|
+
# build spotify web api request parameters.
|
|
11133
|
+
urlParms:dict = \
|
|
11134
|
+
{
|
|
11135
|
+
'q': criteria,
|
|
11136
|
+
'type': criteriaType,
|
|
11137
|
+
'limit': limit,
|
|
11138
|
+
'offset': offset,
|
|
11139
|
+
}
|
|
11140
|
+
if market is not None:
|
|
11141
|
+
urlParms['market'] = market
|
|
11142
|
+
if includeExternal is not None:
|
|
11143
|
+
urlParms['include_external'] = includeExternal
|
|
11144
|
+
|
|
11145
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
11146
|
+
while True:
|
|
11147
|
+
|
|
11148
|
+
# execute spotify web api request.
|
|
11149
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/search')
|
|
11150
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
11151
|
+
msg.UrlParameters = urlParms
|
|
11152
|
+
self.MakeRequest('GET', msg)
|
|
11153
|
+
|
|
11154
|
+
# process results.
|
|
11155
|
+
searchResponse:SearchResponse = SearchResponse(criteria, criteriaType, root=msg.ResponseData)
|
|
11156
|
+
pageObj = searchResponse.Audiobooks
|
|
11157
|
+
|
|
11158
|
+
# trace.
|
|
11159
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
11160
|
+
|
|
11161
|
+
# was limit total argument specified?
|
|
11162
|
+
if (limitTotal <= 0):
|
|
11163
|
+
|
|
11164
|
+
# no - just return the initial page of results.
|
|
11165
|
+
result = pageObj
|
|
11166
|
+
break
|
|
11167
|
+
|
|
11168
|
+
else:
|
|
11169
|
+
|
|
11170
|
+
# append page of items to final results.
|
|
11171
|
+
item:AudiobookSimplified
|
|
11172
|
+
for item in pageObj.Items:
|
|
11173
|
+
result.Items.append(item)
|
|
11174
|
+
result.Limit = result.ItemsCount
|
|
11175
|
+
if result.ItemsCount >= limitTotal:
|
|
11176
|
+
break
|
|
11177
|
+
|
|
11178
|
+
# anymore pages to process? if not, then exit the loop.
|
|
11179
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
11180
|
+
break
|
|
11181
|
+
|
|
11182
|
+
# update result object with final paging details.
|
|
11183
|
+
result.Total = pageObj.Total
|
|
11184
|
+
|
|
11185
|
+
# do not sort, as spotify uses intelligent AI to return results in its order.
|
|
11186
|
+
|
|
11187
|
+
# trace.
|
|
11188
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
11189
|
+
|
|
11190
|
+
# return a search response object.
|
|
11191
|
+
response:SearchResponse = SearchResponse(criteria, criteriaType)
|
|
11192
|
+
response.Audiobooks = result
|
|
11193
|
+
return response
|
|
11194
|
+
|
|
11195
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
11196
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
11197
|
+
except Exception as ex:
|
|
11198
|
+
|
|
11199
|
+
# format unhandled exception.
|
|
11200
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
11201
|
+
|
|
11202
|
+
finally:
|
|
11203
|
+
|
|
11204
|
+
# trace.
|
|
11205
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
11206
|
+
|
|
11207
|
+
|
|
11208
|
+
def SearchEpisodes(self,
|
|
11209
|
+
criteria:str,
|
|
11210
|
+
limit:int=20,
|
|
11211
|
+
offset:int=0,
|
|
11212
|
+
market:str=None,
|
|
11213
|
+
includeExternal:str=None,
|
|
11214
|
+
limitTotal:int=None
|
|
11215
|
+
) -> SearchResponse:
|
|
11216
|
+
"""
|
|
11217
|
+
Get Spotify catalog information about Episodes that match a keyword string.
|
|
11218
|
+
|
|
11219
|
+
Args:
|
|
11220
|
+
criteria (str):
|
|
11221
|
+
Your search query.
|
|
11222
|
+
You can narrow down your search using field filters.
|
|
11223
|
+
The available filters are album, artist, track, year, upc, tag:hipster, tag:new,
|
|
11224
|
+
isrc, and genre. Each field filter only applies to certain result types.
|
|
11225
|
+
The artist and year filters can be used while searching albums, artists and tracks.
|
|
11226
|
+
You can filter on a single year or a range (e.g. 1955-1960).
|
|
11227
|
+
The album filter can be used while searching albums and tracks.
|
|
11228
|
+
The genre filter can be used while searching artists and tracks.
|
|
11229
|
+
The isrc and track filters can be used while searching tracks.
|
|
11230
|
+
The upc, tag:new and tag:hipster filters can only be used while searching albums.
|
|
11231
|
+
The tag:new filter will return albums released in the past two weeks and tag:hipster
|
|
11232
|
+
can be used to return only albums with the lowest 10% popularity.
|
|
11233
|
+
limit (int):
|
|
11234
|
+
The maximum number of items to return in a page of items.
|
|
11235
|
+
Default: 20, Range: 1 to 50.
|
|
11236
|
+
offset (int):
|
|
11237
|
+
The page index offset of the first item to return.
|
|
11238
|
+
Use with limit to get the next set of items.
|
|
11239
|
+
Default: 0 (the first item). Range: 0 to 1000.
|
|
11240
|
+
market (str):
|
|
11241
|
+
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
11242
|
+
is available in that market will be returned. If a valid user access token is specified
|
|
11243
|
+
in the request header, the country associated with the user account will take priority over
|
|
11244
|
+
this parameter.
|
|
11245
|
+
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
11246
|
+
Users can view the country that is associated with their account in the account settings.
|
|
11247
|
+
Example: `ES`
|
|
11248
|
+
includeExternal (str):
|
|
11249
|
+
If "audio" is specified it signals that the client can play externally hosted audio content, and
|
|
11250
|
+
marks the content as playable in the response. By default externally hosted audio content is marked
|
|
11251
|
+
as unplayable in the response.
|
|
11252
|
+
Allowed values: "audio"
|
|
11253
|
+
limitTotal (int):
|
|
11254
|
+
The maximum number of items to return for the request.
|
|
11255
|
+
If specified, this argument overrides the limit and offset argument values
|
|
11256
|
+
and paging is automatically used to retrieve all available items up to the
|
|
11257
|
+
maximum number specified.
|
|
11258
|
+
Default: None (disabled)
|
|
11259
|
+
|
|
11260
|
+
Returns:
|
|
11261
|
+
A `SearchResponse` object that contains the search results.
|
|
11262
|
+
|
|
11263
|
+
Raises:
|
|
11264
|
+
SpotifyWebApiError:
|
|
11265
|
+
If the Spotify Web API request was for a non-authorization service
|
|
11266
|
+
and the response contains error information.
|
|
11267
|
+
SpotifApiError:
|
|
11268
|
+
If the method fails for any other reason.
|
|
11269
|
+
|
|
11270
|
+
Note that Spotify Web API automatically limits you to 1,000 max entries per type that can
|
|
11271
|
+
be returned with a search.
|
|
11272
|
+
|
|
11273
|
+
<details>
|
|
11274
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
11275
|
+
```python
|
|
11276
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchEpisodes.py
|
|
11277
|
+
```
|
|
11278
|
+
</details>
|
|
11279
|
+
<details>
|
|
11280
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
11281
|
+
```python
|
|
11282
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchEpisodes_AutoPaging.py
|
|
11283
|
+
```
|
|
11284
|
+
</details>
|
|
11285
|
+
"""
|
|
11286
|
+
apiMethodName:str = 'SearchEpisodes'
|
|
11287
|
+
apiMethodParms:SIMethodParmListContext = None
|
|
11288
|
+
criteriaType:str = 'episode'
|
|
11289
|
+
result:EpisodePageSimplified = None
|
|
11290
|
+
|
|
11291
|
+
try:
|
|
11292
|
+
|
|
11293
|
+
# trace.
|
|
11294
|
+
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
11295
|
+
apiMethodParms.AppendKeyValue("criteria", criteria)
|
|
11296
|
+
apiMethodParms.AppendKeyValue("criteriaType", criteriaType)
|
|
11297
|
+
apiMethodParms.AppendKeyValue("limit", limit)
|
|
11298
|
+
apiMethodParms.AppendKeyValue("offset", offset)
|
|
11299
|
+
apiMethodParms.AppendKeyValue("market", market)
|
|
11300
|
+
apiMethodParms.AppendKeyValue("includeExternal", includeExternal)
|
|
11301
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
11302
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Searching Spotify catalog for %s information" % criteriaType, apiMethodParms)
|
|
11303
|
+
|
|
11304
|
+
# validations.
|
|
11305
|
+
if limit is None:
|
|
11306
|
+
limit = 20
|
|
11307
|
+
if offset is None:
|
|
11308
|
+
offset = 0
|
|
11309
|
+
if not isinstance(limitTotal, int):
|
|
11310
|
+
limitTotal = 0
|
|
11311
|
+
|
|
11312
|
+
# are we auto-paging? if so, then use max limit.
|
|
11313
|
+
if limitTotal > 0:
|
|
11314
|
+
limit = 50
|
|
11315
|
+
if limit > limitTotal:
|
|
11316
|
+
limit = limitTotal
|
|
11317
|
+
result = EpisodePageSimplified()
|
|
11318
|
+
|
|
11319
|
+
# ensure market was either supplied or implied; default if neither.
|
|
11320
|
+
market = self._ValidateMarket(market)
|
|
11321
|
+
|
|
11322
|
+
# build spotify web api request parameters.
|
|
11323
|
+
urlParms:dict = \
|
|
11324
|
+
{
|
|
11325
|
+
'q': criteria,
|
|
11326
|
+
'type': criteriaType,
|
|
11327
|
+
'limit': limit,
|
|
11328
|
+
'offset': offset,
|
|
11329
|
+
}
|
|
11330
|
+
if market is not None:
|
|
11331
|
+
urlParms['market'] = market
|
|
11332
|
+
if includeExternal is not None:
|
|
11333
|
+
urlParms['include_external'] = includeExternal
|
|
11334
|
+
|
|
11335
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
11336
|
+
while True:
|
|
11337
|
+
|
|
11338
|
+
# execute spotify web api request.
|
|
11339
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/search')
|
|
11340
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
11341
|
+
msg.UrlParameters = urlParms
|
|
11342
|
+
self.MakeRequest('GET', msg)
|
|
11343
|
+
|
|
11344
|
+
# process results.
|
|
11345
|
+
searchResponse:SearchResponse = SearchResponse(criteria, criteriaType, root=msg.ResponseData)
|
|
11346
|
+
pageObj = searchResponse.Episodes
|
|
11347
|
+
|
|
11348
|
+
# trace.
|
|
11349
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
11350
|
+
|
|
11351
|
+
# was limit total argument specified?
|
|
11352
|
+
if (limitTotal <= 0):
|
|
11353
|
+
|
|
11354
|
+
# no - just return the initial page of results.
|
|
11355
|
+
result = pageObj
|
|
11356
|
+
break
|
|
11357
|
+
|
|
11358
|
+
else:
|
|
11359
|
+
|
|
11360
|
+
# append page of items to final results.
|
|
11361
|
+
item:EpisodeSimplified
|
|
11362
|
+
for item in pageObj.Items:
|
|
11363
|
+
result.Items.append(item)
|
|
11364
|
+
result.Limit = result.ItemsCount
|
|
11365
|
+
if result.ItemsCount >= limitTotal:
|
|
11366
|
+
break
|
|
11367
|
+
|
|
11368
|
+
# anymore pages to process? if not, then exit the loop.
|
|
11369
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
11370
|
+
break
|
|
11371
|
+
|
|
11372
|
+
# update result object with final paging details.
|
|
11373
|
+
result.Total = pageObj.Total
|
|
11374
|
+
|
|
11375
|
+
# do not sort, as spotify uses intelligent AI to return results in its order.
|
|
11376
|
+
|
|
11377
|
+
# trace.
|
|
11378
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
11379
|
+
|
|
11380
|
+
# return a search response object.
|
|
11381
|
+
response:SearchResponse = SearchResponse(criteria, criteriaType)
|
|
11382
|
+
response.Episodes = result
|
|
11383
|
+
return response
|
|
11384
|
+
|
|
11385
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
11386
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
11387
|
+
except Exception as ex:
|
|
11388
|
+
|
|
11389
|
+
# format unhandled exception.
|
|
11390
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
11391
|
+
|
|
11392
|
+
finally:
|
|
11393
|
+
|
|
11394
|
+
# trace.
|
|
11395
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
11396
|
+
|
|
11397
|
+
|
|
11398
|
+
def SearchPlaylists(self,
|
|
11399
|
+
criteria:str,
|
|
11400
|
+
limit:int=20,
|
|
11401
|
+
offset:int=0,
|
|
11402
|
+
market:str=None,
|
|
11403
|
+
includeExternal:str=None,
|
|
11404
|
+
limitTotal:int=None
|
|
11405
|
+
) -> SearchResponse:
|
|
11406
|
+
"""
|
|
11407
|
+
Get Spotify catalog information about Playlists that match a keyword string.
|
|
11408
|
+
|
|
11409
|
+
Args:
|
|
11410
|
+
criteria (str):
|
|
11411
|
+
Your search query.
|
|
11412
|
+
You can narrow down your search using field filters.
|
|
11413
|
+
The available filters are album, artist, track, year, upc, tag:hipster, tag:new,
|
|
11414
|
+
isrc, and genre. Each field filter only applies to certain result types.
|
|
11415
|
+
The artist and year filters can be used while searching albums, artists and tracks.
|
|
11416
|
+
You can filter on a single year or a range (e.g. 1955-1960).
|
|
11417
|
+
The album filter can be used while searching albums and tracks.
|
|
11418
|
+
The genre filter can be used while searching artists and tracks.
|
|
11419
|
+
The isrc and track filters can be used while searching tracks.
|
|
11420
|
+
The upc, tag:new and tag:hipster filters can only be used while searching albums.
|
|
11421
|
+
The tag:new filter will return albums released in the past two weeks and tag:hipster
|
|
11422
|
+
can be used to return only albums with the lowest 10% popularity.
|
|
11423
|
+
limit (int):
|
|
11424
|
+
The maximum number of items to return in a page of items.
|
|
11425
|
+
Default: 20, Range: 1 to 50.
|
|
11426
|
+
offset (int):
|
|
11427
|
+
The page index offset of the first item to return.
|
|
11428
|
+
Use with limit to get the next set of items.
|
|
11429
|
+
Default: 0 (the first item). Range: 0 to 1000.
|
|
11430
|
+
market (str):
|
|
11431
|
+
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
11432
|
+
is available in that market will be returned. If a valid user access token is specified
|
|
11433
|
+
in the request header, the country associated with the user account will take priority over
|
|
11434
|
+
this parameter.
|
|
11435
|
+
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
11436
|
+
Users can view the country that is associated with their account in the account settings.
|
|
11437
|
+
Example: `ES`
|
|
11438
|
+
includeExternal (str):
|
|
11439
|
+
If "audio" is specified it signals that the client can play externally hosted audio content, and
|
|
11440
|
+
marks the content as playable in the response. By default externally hosted audio content is marked
|
|
11441
|
+
as unplayable in the response.
|
|
11442
|
+
Allowed values: "audio"
|
|
11443
|
+
limitTotal (int):
|
|
11444
|
+
The maximum number of items to return for the request.
|
|
11445
|
+
If specified, this argument overrides the limit and offset argument values
|
|
11446
|
+
and paging is automatically used to retrieve all available items up to the
|
|
11447
|
+
maximum number specified.
|
|
11448
|
+
Default: None (disabled)
|
|
11449
|
+
|
|
11450
|
+
Returns:
|
|
11451
|
+
A `SearchResponse` object that contains the search results.
|
|
11452
|
+
|
|
11453
|
+
Raises:
|
|
11454
|
+
SpotifyWebApiError:
|
|
11455
|
+
If the Spotify Web API request was for a non-authorization service
|
|
11456
|
+
and the response contains error information.
|
|
11457
|
+
SpotifApiError:
|
|
11458
|
+
If the method fails for any other reason.
|
|
11459
|
+
|
|
11460
|
+
Note that Spotify Web API automatically limits you to 1,000 max entries per type that can
|
|
11461
|
+
be returned with a search.
|
|
11462
|
+
|
|
11463
|
+
<details>
|
|
11464
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
11465
|
+
```python
|
|
11466
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchPlaylists.py
|
|
11467
|
+
```
|
|
11468
|
+
</details>
|
|
11469
|
+
<details>
|
|
11470
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
11471
|
+
```python
|
|
11472
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchPlaylists_AutoPaging.py
|
|
11473
|
+
```
|
|
11474
|
+
</details>
|
|
11475
|
+
<details>
|
|
11476
|
+
<summary>Sample Code - Spotify Generated, Daily Mix</summary>
|
|
11477
|
+
```python
|
|
11478
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchPlaylists_Spotify_DailyMix.py
|
|
11479
|
+
```
|
|
11480
|
+
</details>
|
|
11481
|
+
"""
|
|
11482
|
+
apiMethodName:str = 'SearchPlaylists'
|
|
11483
|
+
apiMethodParms:SIMethodParmListContext = None
|
|
11484
|
+
criteriaType:str = 'playlist'
|
|
11485
|
+
result:PlaylistPageSimplified = None
|
|
11486
|
+
|
|
11487
|
+
try:
|
|
11488
|
+
|
|
11489
|
+
# trace.
|
|
11490
|
+
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
11491
|
+
apiMethodParms.AppendKeyValue("criteria", criteria)
|
|
11492
|
+
apiMethodParms.AppendKeyValue("criteriaType", criteriaType)
|
|
11493
|
+
apiMethodParms.AppendKeyValue("limit", limit)
|
|
11494
|
+
apiMethodParms.AppendKeyValue("offset", offset)
|
|
11495
|
+
apiMethodParms.AppendKeyValue("market", market)
|
|
11496
|
+
apiMethodParms.AppendKeyValue("includeExternal", includeExternal)
|
|
11497
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
11498
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Searching Spotify catalog for %s information" % criteriaType, apiMethodParms)
|
|
11499
|
+
|
|
11500
|
+
# validations.
|
|
11501
|
+
if limit is None:
|
|
11502
|
+
limit = 20
|
|
11503
|
+
if offset is None:
|
|
11504
|
+
offset = 0
|
|
11505
|
+
if not isinstance(limitTotal, int):
|
|
11506
|
+
limitTotal = 0
|
|
11507
|
+
|
|
11508
|
+
# are we auto-paging? if so, then use max limit.
|
|
11509
|
+
if limitTotal > 0:
|
|
11510
|
+
limit = 50
|
|
11511
|
+
if limit > limitTotal:
|
|
11512
|
+
limit = limitTotal
|
|
11513
|
+
result = PlaylistPageSimplified()
|
|
11514
|
+
|
|
11515
|
+
# ensure market was either supplied or implied; default if neither.
|
|
11516
|
+
market = self._ValidateMarket(market)
|
|
11517
|
+
|
|
11518
|
+
# build spotify web api request parameters.
|
|
11519
|
+
urlParms:dict = \
|
|
11520
|
+
{
|
|
11521
|
+
'q': criteria,
|
|
11522
|
+
'type': criteriaType,
|
|
11523
|
+
'limit': limit,
|
|
11524
|
+
'offset': offset,
|
|
11525
|
+
}
|
|
11526
|
+
if market is not None:
|
|
11527
|
+
urlParms['market'] = market
|
|
11528
|
+
if includeExternal is not None:
|
|
11529
|
+
urlParms['include_external'] = includeExternal
|
|
11530
|
+
|
|
11531
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
11532
|
+
while True:
|
|
11533
|
+
|
|
11534
|
+
# execute spotify web api request.
|
|
11535
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/search')
|
|
11536
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
11537
|
+
msg.UrlParameters = urlParms
|
|
11538
|
+
self.MakeRequest('GET', msg)
|
|
11539
|
+
|
|
11540
|
+
# process results.
|
|
11541
|
+
searchResponse:SearchResponse = SearchResponse(criteria, criteriaType, root=msg.ResponseData)
|
|
11542
|
+
pageObj = searchResponse.Playlists
|
|
11543
|
+
|
|
11544
|
+
# trace.
|
|
11545
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
11546
|
+
|
|
11547
|
+
# was limit total argument specified?
|
|
11548
|
+
if (limitTotal <= 0):
|
|
11549
|
+
|
|
11550
|
+
# no - just return the initial page of results.
|
|
11551
|
+
result = pageObj
|
|
11552
|
+
break
|
|
11553
|
+
|
|
11554
|
+
else:
|
|
11555
|
+
|
|
11556
|
+
# append page of items to final results.
|
|
11557
|
+
item:PlaylistSimplified
|
|
11558
|
+
for item in pageObj.Items:
|
|
11559
|
+
result.Items.append(item)
|
|
11560
|
+
result.Limit = result.ItemsCount
|
|
11561
|
+
if result.ItemsCount >= limitTotal:
|
|
11562
|
+
break
|
|
11563
|
+
|
|
11564
|
+
# anymore pages to process? if not, then exit the loop.
|
|
11565
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
11566
|
+
break
|
|
11567
|
+
|
|
11568
|
+
# update result object with final paging details.
|
|
11569
|
+
result.Total = pageObj.Total
|
|
11570
|
+
|
|
11571
|
+
# do not sort, as spotify uses intelligent AI to return results in its order.
|
|
11572
|
+
|
|
11573
|
+
# trace.
|
|
11574
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
11575
|
+
|
|
11576
|
+
# return a search response object.
|
|
11577
|
+
response:SearchResponse = SearchResponse(criteria, criteriaType)
|
|
11578
|
+
response.Playlists = result
|
|
11579
|
+
return response
|
|
11580
|
+
|
|
11581
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
11582
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
11583
|
+
except Exception as ex:
|
|
11584
|
+
|
|
11585
|
+
# format unhandled exception.
|
|
11586
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
11587
|
+
|
|
11588
|
+
finally:
|
|
11589
|
+
|
|
11590
|
+
# trace.
|
|
11591
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
11592
|
+
|
|
11593
|
+
|
|
11594
|
+
def SearchShows(self,
|
|
11595
|
+
criteria:str,
|
|
11596
|
+
limit:int=20,
|
|
11597
|
+
offset:int=0,
|
|
11598
|
+
market:str=None,
|
|
11599
|
+
includeExternal:str=None,
|
|
11600
|
+
limitTotal:int=None
|
|
11601
|
+
) -> SearchResponse:
|
|
11602
|
+
"""
|
|
11603
|
+
Get Spotify catalog information about Shows that match a keyword string.
|
|
11604
|
+
|
|
11605
|
+
Args:
|
|
11606
|
+
criteria (str):
|
|
11607
|
+
Your search query.
|
|
11608
|
+
You can narrow down your search using field filters.
|
|
11609
|
+
The available filters are album, artist, track, year, upc, tag:hipster, tag:new,
|
|
11610
|
+
isrc, and genre. Each field filter only applies to certain result types.
|
|
11611
|
+
The artist and year filters can be used while searching albums, artists and tracks.
|
|
11612
|
+
You can filter on a single year or a range (e.g. 1955-1960).
|
|
11613
|
+
The album filter can be used while searching albums and tracks.
|
|
11614
|
+
The genre filter can be used while searching artists and tracks.
|
|
11615
|
+
The isrc and track filters can be used while searching tracks.
|
|
11616
|
+
The upc, tag:new and tag:hipster filters can only be used while searching albums.
|
|
11617
|
+
The tag:new filter will return albums released in the past two weeks and tag:hipster
|
|
11618
|
+
can be used to return only albums with the lowest 10% popularity.
|
|
11619
|
+
limit (int):
|
|
11620
|
+
The maximum number of items to return in a page of items.
|
|
11621
|
+
Default: 20, Range: 1 to 50.
|
|
11622
|
+
offset (int):
|
|
11623
|
+
The page index offset of the first item to return.
|
|
11624
|
+
Use with limit to get the next set of items.
|
|
11625
|
+
Default: 0 (the first item). Range: 0 to 1000.
|
|
11626
|
+
market (str):
|
|
11627
|
+
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
11628
|
+
is available in that market will be returned. If a valid user access token is specified
|
|
11629
|
+
in the request header, the country associated with the user account will take priority over
|
|
11630
|
+
this parameter.
|
|
11631
|
+
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
11632
|
+
Users can view the country that is associated with their account in the account settings.
|
|
11633
|
+
Example: `ES`
|
|
11634
|
+
includeExternal (str):
|
|
11635
|
+
If "audio" is specified it signals that the client can play externally hosted audio content, and
|
|
11636
|
+
marks the content as playable in the response. By default externally hosted audio content is marked
|
|
11637
|
+
as unplayable in the response.
|
|
11638
|
+
Allowed values: "audio"
|
|
11639
|
+
limitTotal (int):
|
|
11640
|
+
The maximum number of items to return for the request.
|
|
11641
|
+
If specified, this argument overrides the limit and offset argument values
|
|
11642
|
+
and paging is automatically used to retrieve all available items up to the
|
|
11643
|
+
maximum number specified.
|
|
11644
|
+
Default: None (disabled)
|
|
11645
|
+
|
|
11646
|
+
Returns:
|
|
11647
|
+
A `SearchResponse` object that contains the search results.
|
|
11648
|
+
|
|
11649
|
+
Raises:
|
|
11650
|
+
SpotifyWebApiError:
|
|
11651
|
+
If the Spotify Web API request was for a non-authorization service
|
|
11652
|
+
and the response contains error information.
|
|
11653
|
+
SpotifApiError:
|
|
11654
|
+
If the method fails for any other reason.
|
|
11655
|
+
|
|
11656
|
+
Note that Spotify Web API automatically limits you to 1,000 max entries per type that can
|
|
11657
|
+
be returned with a search.
|
|
11658
|
+
|
|
11659
|
+
<details>
|
|
11660
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
11661
|
+
```python
|
|
11662
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchShows.py
|
|
11663
|
+
```
|
|
11664
|
+
</details>
|
|
11665
|
+
<details>
|
|
11666
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
11667
|
+
```python
|
|
11668
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchShows_AutoPaging.py
|
|
11669
|
+
```
|
|
11670
|
+
</details>
|
|
11671
|
+
"""
|
|
11672
|
+
apiMethodName:str = 'SearchShows'
|
|
11673
|
+
apiMethodParms:SIMethodParmListContext = None
|
|
11674
|
+
criteriaType:str = 'show'
|
|
11675
|
+
result:ShowPageSimplified = None
|
|
11676
|
+
|
|
11677
|
+
try:
|
|
11678
|
+
|
|
11679
|
+
# trace.
|
|
11680
|
+
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
11681
|
+
apiMethodParms.AppendKeyValue("criteria", criteria)
|
|
11682
|
+
apiMethodParms.AppendKeyValue("criteriaType", criteriaType)
|
|
11683
|
+
apiMethodParms.AppendKeyValue("limit", limit)
|
|
11684
|
+
apiMethodParms.AppendKeyValue("offset", offset)
|
|
11685
|
+
apiMethodParms.AppendKeyValue("market", market)
|
|
11686
|
+
apiMethodParms.AppendKeyValue("includeExternal", includeExternal)
|
|
11687
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
11688
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Searching Spotify catalog for %s information" % criteriaType, apiMethodParms)
|
|
11689
|
+
|
|
11690
|
+
# validations.
|
|
11691
|
+
if limit is None:
|
|
11692
|
+
limit = 20
|
|
11693
|
+
if offset is None:
|
|
11694
|
+
offset = 0
|
|
11695
|
+
if not isinstance(limitTotal, int):
|
|
11696
|
+
limitTotal = 0
|
|
11697
|
+
|
|
11698
|
+
# are we auto-paging? if so, then use max limit.
|
|
11699
|
+
if limitTotal > 0:
|
|
11700
|
+
limit = 50
|
|
11701
|
+
if limit > limitTotal:
|
|
11702
|
+
limit = limitTotal
|
|
11703
|
+
result = ShowPageSimplified()
|
|
11704
|
+
|
|
11705
|
+
# ensure market was either supplied or implied; default if neither.
|
|
11706
|
+
market = self._ValidateMarket(market)
|
|
11707
|
+
|
|
11708
|
+
# build spotify web api request parameters.
|
|
11709
|
+
urlParms:dict = \
|
|
11710
|
+
{
|
|
11711
|
+
'q': criteria,
|
|
11712
|
+
'type': criteriaType,
|
|
11713
|
+
'limit': limit,
|
|
11714
|
+
'offset': offset,
|
|
11715
|
+
}
|
|
11716
|
+
if market is not None:
|
|
11717
|
+
urlParms['market'] = market
|
|
11718
|
+
if includeExternal is not None:
|
|
11719
|
+
urlParms['include_external'] = includeExternal
|
|
11720
|
+
|
|
11721
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
11722
|
+
while True:
|
|
11723
|
+
|
|
11724
|
+
# execute spotify web api request.
|
|
11725
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/search')
|
|
11726
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
11727
|
+
msg.UrlParameters = urlParms
|
|
11728
|
+
self.MakeRequest('GET', msg)
|
|
11729
|
+
|
|
11730
|
+
# process results.
|
|
11731
|
+
searchResponse:SearchResponse = SearchResponse(criteria, criteriaType, root=msg.ResponseData)
|
|
11732
|
+
pageObj = searchResponse.Shows
|
|
11733
|
+
|
|
11734
|
+
# trace.
|
|
11735
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
11736
|
+
|
|
11737
|
+
# was limit total argument specified?
|
|
11738
|
+
if (limitTotal <= 0):
|
|
11739
|
+
|
|
11740
|
+
# no - just return the initial page of results.
|
|
11741
|
+
result = pageObj
|
|
11742
|
+
break
|
|
11743
|
+
|
|
11744
|
+
else:
|
|
11745
|
+
|
|
11746
|
+
# append page of items to final results.
|
|
11747
|
+
item:ShowSimplified
|
|
11748
|
+
for item in pageObj.Items:
|
|
11749
|
+
result.Items.append(item)
|
|
11750
|
+
result.Limit = result.ItemsCount
|
|
11751
|
+
if result.ItemsCount >= limitTotal:
|
|
11752
|
+
break
|
|
11753
|
+
|
|
11754
|
+
# anymore pages to process? if not, then exit the loop.
|
|
11755
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
11756
|
+
break
|
|
11757
|
+
|
|
11758
|
+
# update result object with final paging details.
|
|
11759
|
+
result.Total = pageObj.Total
|
|
11760
|
+
|
|
11761
|
+
# do not sort, as spotify uses intelligent AI to return results in its order.
|
|
11762
|
+
|
|
11763
|
+
# trace.
|
|
11764
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
11765
|
+
|
|
11766
|
+
# return a search response object.
|
|
11767
|
+
response:SearchResponse = SearchResponse(criteria, criteriaType)
|
|
11768
|
+
response.Shows = result
|
|
11769
|
+
return response
|
|
11770
|
+
|
|
11771
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
11772
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
11773
|
+
except Exception as ex:
|
|
11774
|
+
|
|
11775
|
+
# format unhandled exception.
|
|
11776
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
11777
|
+
|
|
11778
|
+
finally:
|
|
11779
|
+
|
|
11780
|
+
# trace.
|
|
11781
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
11782
|
+
|
|
11783
|
+
|
|
11784
|
+
def SearchTracks(self,
|
|
11785
|
+
criteria:str,
|
|
11786
|
+
limit:int=20,
|
|
11787
|
+
offset:int=0,
|
|
11788
|
+
market:str=None,
|
|
11789
|
+
includeExternal:str=None,
|
|
11790
|
+
limitTotal:int=None
|
|
11791
|
+
) -> SearchResponse:
|
|
11792
|
+
"""
|
|
11793
|
+
Get Spotify catalog information about Tracks that match a keyword string.
|
|
11794
|
+
|
|
11795
|
+
Args:
|
|
11796
|
+
criteria (str):
|
|
11797
|
+
Your search query.
|
|
11798
|
+
You can narrow down your search using field filters.
|
|
11799
|
+
The available filters are album, artist, track, year, upc, tag:hipster, tag:new,
|
|
11800
|
+
isrc, and genre. Each field filter only applies to certain result types.
|
|
11801
|
+
The artist and year filters can be used while searching albums, artists and tracks.
|
|
11802
|
+
You can filter on a single year or a range (e.g. 1955-1960).
|
|
11803
|
+
The album filter can be used while searching albums and tracks.
|
|
11804
|
+
The genre filter can be used while searching artists and tracks.
|
|
11805
|
+
The isrc and track filters can be used while searching tracks.
|
|
11806
|
+
The upc, tag:new and tag:hipster filters can only be used while searching albums.
|
|
11807
|
+
The tag:new filter will return albums released in the past two weeks and tag:hipster
|
|
11808
|
+
can be used to return only albums with the lowest 10% popularity.
|
|
11809
|
+
limit (int):
|
|
11810
|
+
The maximum number of items to return in a page of items.
|
|
11811
|
+
Default: 20, Range: 1 to 50.
|
|
11812
|
+
offset (int):
|
|
11813
|
+
The page index offset of the first item to return.
|
|
11814
|
+
Use with limit to get the next set of items.
|
|
11815
|
+
Default: 0 (the first item). Range: 0 to 1000.
|
|
11816
|
+
market (str):
|
|
11817
|
+
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
11818
|
+
is available in that market will be returned. If a valid user access token is specified
|
|
11819
|
+
in the request header, the country associated with the user account will take priority over
|
|
11820
|
+
this parameter.
|
|
11821
|
+
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
11822
|
+
Users can view the country that is associated with their account in the account settings.
|
|
11823
|
+
Example: `ES`
|
|
11824
|
+
includeExternal (str):
|
|
11825
|
+
If "audio" is specified it signals that the client can play externally hosted audio content, and
|
|
11826
|
+
marks the content as playable in the response. By default externally hosted audio content is marked
|
|
11827
|
+
as unplayable in the response.
|
|
11828
|
+
Allowed values: "audio"
|
|
11829
|
+
limitTotal (int):
|
|
11830
|
+
The maximum number of items to return for the request.
|
|
11831
|
+
If specified, this argument overrides the limit and offset argument values
|
|
11832
|
+
and paging is automatically used to retrieve all available items up to the
|
|
11833
|
+
maximum number specified.
|
|
11834
|
+
Default: None (disabled)
|
|
11835
|
+
|
|
11836
|
+
Returns:
|
|
11837
|
+
A `SearchResponse` object that contains the search results.
|
|
11838
|
+
|
|
11839
|
+
Raises:
|
|
11840
|
+
SpotifyWebApiError:
|
|
11841
|
+
If the Spotify Web API request was for a non-authorization service
|
|
11842
|
+
and the response contains error information.
|
|
11843
|
+
SpotifApiError:
|
|
11844
|
+
If the method fails for any other reason.
|
|
11845
|
+
|
|
11846
|
+
Note that Spotify Web API automatically limits you to 1,000 max entries per type that can
|
|
11847
|
+
be returned with a search.
|
|
11848
|
+
|
|
11849
|
+
<details>
|
|
11850
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
11851
|
+
```python
|
|
11852
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchTracks.py
|
|
11853
|
+
```
|
|
11854
|
+
</details>
|
|
11855
|
+
<details>
|
|
11856
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
11857
|
+
```python
|
|
11858
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchTracks_AutoPaging.py
|
|
11859
|
+
```
|
|
11860
|
+
</details>
|
|
11861
|
+
"""
|
|
11862
|
+
apiMethodName:str = 'SearchTracks'
|
|
11863
|
+
apiMethodParms:SIMethodParmListContext = None
|
|
11864
|
+
criteriaType:str = 'track'
|
|
11865
|
+
result:TrackPage = None
|
|
11866
|
+
|
|
11867
|
+
try:
|
|
11868
|
+
|
|
11869
|
+
# trace.
|
|
11870
|
+
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
11871
|
+
apiMethodParms.AppendKeyValue("criteria", criteria)
|
|
11872
|
+
apiMethodParms.AppendKeyValue("criteriaType", criteriaType)
|
|
11873
|
+
apiMethodParms.AppendKeyValue("limit", limit)
|
|
11874
|
+
apiMethodParms.AppendKeyValue("offset", offset)
|
|
11875
|
+
apiMethodParms.AppendKeyValue("market", market)
|
|
11876
|
+
apiMethodParms.AppendKeyValue("includeExternal", includeExternal)
|
|
11877
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
11878
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Searching Spotify catalog for %s information" % criteriaType, apiMethodParms)
|
|
11879
|
+
|
|
11880
|
+
# validations.
|
|
11881
|
+
if limit is None:
|
|
11882
|
+
limit = 20
|
|
11883
|
+
if offset is None:
|
|
11884
|
+
offset = 0
|
|
11885
|
+
if not isinstance(limitTotal, int):
|
|
11886
|
+
limitTotal = 0
|
|
11887
|
+
|
|
11888
|
+
# are we auto-paging? if so, then use max limit.
|
|
11889
|
+
if limitTotal > 0:
|
|
11890
|
+
limit = 50
|
|
11891
|
+
if limit > limitTotal:
|
|
11892
|
+
limit = limitTotal
|
|
11893
|
+
result = TrackPage()
|
|
11894
|
+
|
|
11895
|
+
# ensure market was either supplied or implied; default if neither.
|
|
11896
|
+
market = self._ValidateMarket(market)
|
|
11897
|
+
|
|
11898
|
+
# build spotify web api request parameters.
|
|
11899
|
+
urlParms:dict = \
|
|
11900
|
+
{
|
|
11901
|
+
'q': criteria,
|
|
11902
|
+
'type': criteriaType,
|
|
11903
|
+
'limit': limit,
|
|
11904
|
+
'offset': offset,
|
|
11905
|
+
}
|
|
11906
|
+
if market is not None:
|
|
11907
|
+
urlParms['market'] = market
|
|
11908
|
+
if includeExternal is not None:
|
|
11909
|
+
urlParms['include_external'] = includeExternal
|
|
11910
|
+
|
|
11911
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
11912
|
+
while True:
|
|
11913
|
+
|
|
11914
|
+
# execute spotify web api request.
|
|
11915
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/search')
|
|
11916
|
+
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
11917
|
+
msg.UrlParameters = urlParms
|
|
11918
|
+
self.MakeRequest('GET', msg)
|
|
11919
|
+
|
|
11920
|
+
# process results.
|
|
11921
|
+
searchResponse:SearchResponse = SearchResponse(criteria, criteriaType, root=msg.ResponseData)
|
|
11922
|
+
pageObj = searchResponse.Tracks
|
|
11923
|
+
|
|
11924
|
+
# trace.
|
|
11925
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE_PAGE + pageObj.PagingInfo) % (apiMethodName, type(pageObj).__name__), pageObj, excludeNonPublic=True)
|
|
11926
|
+
|
|
11927
|
+
# was limit total argument specified?
|
|
11928
|
+
if (limitTotal <= 0):
|
|
11929
|
+
|
|
11930
|
+
# no - just return the initial page of results.
|
|
11931
|
+
result = pageObj
|
|
11932
|
+
break
|
|
11933
|
+
|
|
11934
|
+
else:
|
|
11935
|
+
|
|
11936
|
+
# append page of items to final results.
|
|
11937
|
+
item:Track
|
|
11938
|
+
for item in pageObj.Items:
|
|
11939
|
+
result.Items.append(item)
|
|
11940
|
+
result.Limit = result.ItemsCount
|
|
11941
|
+
if result.ItemsCount >= limitTotal:
|
|
11942
|
+
break
|
|
11943
|
+
|
|
11944
|
+
# anymore pages to process? if not, then exit the loop.
|
|
11945
|
+
if not self._CheckForNextPage(pageObj, result.ItemsCount, limit, limitTotal, urlParms):
|
|
11946
|
+
break
|
|
11947
|
+
|
|
11948
|
+
# update result object with final paging details.
|
|
11949
|
+
result.Total = pageObj.Total
|
|
11950
|
+
|
|
11951
|
+
# do not sort, as spotify uses intelligent AI to return results in its order.
|
|
11952
|
+
|
|
11953
|
+
# trace.
|
|
11954
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
11955
|
+
|
|
11956
|
+
# return a search response object.
|
|
11957
|
+
response:SearchResponse = SearchResponse(criteria, criteriaType)
|
|
11958
|
+
response.Tracks = result
|
|
11959
|
+
return response
|
|
9388
11960
|
|
|
9389
11961
|
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
9390
11962
|
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
@@ -9817,14 +12389,16 @@ class SpotifyClient:
|
|
|
9817
12389
|
|
|
9818
12390
|
# note that we cannot retrieve spotify user basic details, as the client credentials
|
|
9819
12391
|
# authentication type does not utilize an authorization token. in this case, we will
|
|
9820
|
-
# build a "public access" user profile, just so we have something there.
|
|
12392
|
+
# build a "public access" user profile, just so we have something there.
|
|
12393
|
+
#
|
|
12394
|
+
# also note that we do not set a value for Country, as some endpoints require a country
|
|
12395
|
+
# (or market) code in order to work properly (e.g. any of the Search... methods).
|
|
9821
12396
|
userProfile:UserProfile = UserProfile()
|
|
9822
12397
|
userProfile._DisplayName = 'Public Access'
|
|
9823
12398
|
userProfile._Followers = Followers()
|
|
9824
12399
|
userProfile._Followers._Total = 0
|
|
9825
12400
|
userProfile._Id = 'unknown'
|
|
9826
12401
|
userProfile._Uri = 'spotify.user.' + userProfile._Id
|
|
9827
|
-
userProfile._Country = 'unknown'
|
|
9828
12402
|
self._UserProfile = userProfile
|
|
9829
12403
|
|
|
9830
12404
|
# trace.
|