spotifywebapiPython 1.0.27__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.27.dist-info → spotifywebapiPython-1.0.28.dist-info}/METADATA +1 -1
- {spotifywebapiPython-1.0.27.dist-info → spotifywebapiPython-1.0.28.dist-info}/RECORD +24 -24
- spotifywebapipython/const.py +26 -2
- spotifywebapipython/docs/__init__.html +20 -2
- 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 +2105 -326
- 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 +2918 -335
- {spotifywebapiPython-1.0.27.dist-info → spotifywebapiPython-1.0.28.dist-info}/LICENSE +0 -0
- {spotifywebapiPython-1.0.27.dist-info → spotifywebapiPython-1.0.28.dist-info}/WHEEL +0 -0
- {spotifywebapiPython-1.0.27.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
|
|
@@ -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)
|
|
@@ -2598,7 +2860,8 @@ class SpotifyClient:
|
|
|
2598
2860
|
include_groups:str='album',
|
|
2599
2861
|
limit:int=20,
|
|
2600
2862
|
offset:int=0,
|
|
2601
|
-
market:str=None
|
|
2863
|
+
market:str=None,
|
|
2864
|
+
limitTotal:int=None
|
|
2602
2865
|
) -> AlbumPageSimplified:
|
|
2603
2866
|
"""
|
|
2604
2867
|
Get Spotify catalog information about an artist's albums.
|
|
@@ -2613,7 +2876,7 @@ class SpotifyClient:
|
|
|
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,6 +2889,12 @@ 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.
|
|
@@ -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)
|
|
@@ -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.
|
|
@@ -2855,8 +3179,14 @@ class SpotifyClient:
|
|
|
2855
3179
|
the first request.
|
|
2856
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)
|
|
@@ -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
|
|
@@ -4813,6 +5566,9 @@ class SpotifyClient:
|
|
|
4813
5566
|
apiMethodParms.AppendKeyValue("market", market)
|
|
4814
5567
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get the object currently being played on the user's Spotify account", apiMethodParms)
|
|
4815
5568
|
|
|
5569
|
+
# ensure market was either supplied or implied; default if neither.
|
|
5570
|
+
market = self._ValidateMarket(market)
|
|
5571
|
+
|
|
4816
5572
|
# build spotify web api request parameters.
|
|
4817
5573
|
urlParms:dict = {}
|
|
4818
5574
|
if market is not None:
|
|
@@ -4901,6 +5657,9 @@ class SpotifyClient:
|
|
|
4901
5657
|
apiMethodParms.AppendKeyValue("market", market)
|
|
4902
5658
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get the user's current playback state", apiMethodParms)
|
|
4903
5659
|
|
|
5660
|
+
# ensure market was either supplied or implied; default if neither.
|
|
5661
|
+
market = self._ValidateMarket(market)
|
|
5662
|
+
|
|
4904
5663
|
# build spotify web api request parameters.
|
|
4905
5664
|
urlParms:dict = {}
|
|
4906
5665
|
if market is not None:
|
|
@@ -5004,7 +5763,7 @@ class SpotifyClient:
|
|
|
5004
5763
|
|
|
5005
5764
|
Args:
|
|
5006
5765
|
limit (int):
|
|
5007
|
-
The maximum number of items to return.
|
|
5766
|
+
The maximum number of items to return in a page of items.
|
|
5008
5767
|
Default: `20`, Range: `1` to `50`.
|
|
5009
5768
|
after (int):
|
|
5010
5769
|
Returns all items after (but not including) this cursor position, which is
|
|
@@ -5187,6 +5946,9 @@ class SpotifyClient:
|
|
|
5187
5946
|
apiMethodParms.AppendKeyValue("additionalTypes", additionalTypes)
|
|
5188
5947
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a playlist owned by a Spotify user", apiMethodParms)
|
|
5189
5948
|
|
|
5949
|
+
# ensure market was either supplied or implied; default if neither.
|
|
5950
|
+
market = self._ValidateMarket(market)
|
|
5951
|
+
|
|
5190
5952
|
# build spotify web api request parameters.
|
|
5191
5953
|
urlParms:dict = {}
|
|
5192
5954
|
if market is not None:
|
|
@@ -5296,7 +6058,8 @@ class SpotifyClient:
|
|
|
5296
6058
|
offset:int=0,
|
|
5297
6059
|
market:str=None,
|
|
5298
6060
|
fields:str=None,
|
|
5299
|
-
additionalTypes:str=None
|
|
6061
|
+
additionalTypes:str=None,
|
|
6062
|
+
limitTotal:int=None
|
|
5300
6063
|
) -> PlaylistPage:
|
|
5301
6064
|
"""
|
|
5302
6065
|
Get full details of the items of a playlist owned by a Spotify user.
|
|
@@ -5308,10 +6071,10 @@ class SpotifyClient:
|
|
|
5308
6071
|
The Spotify ID of the playlist.
|
|
5309
6072
|
Example: `5v5ETK9WFXAnGQ3MRubKuE`
|
|
5310
6073
|
limit (int):
|
|
5311
|
-
The maximum number of items to return.
|
|
6074
|
+
The maximum number of items to return in a page of items.
|
|
5312
6075
|
Default: 50, Range: 1 to 50.
|
|
5313
6076
|
offset (int):
|
|
5314
|
-
The index of the first item to return.
|
|
6077
|
+
The page index offset of the first item to return.
|
|
5315
6078
|
Use with limit to get the next set of items.
|
|
5316
6079
|
Default: 0 (the first item).
|
|
5317
6080
|
market (str):
|
|
@@ -5342,6 +6105,12 @@ class SpotifyClient:
|
|
|
5342
6105
|
Note: This parameter was introduced to allow existing clients to maintain their current behaviour
|
|
5343
6106
|
and might be deprecated in the future. In addition to providing this parameter, make sure that your
|
|
5344
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)
|
|
5345
6114
|
|
|
5346
6115
|
Returns:
|
|
5347
6116
|
A `Playlist` object that contains the playlist details.
|
|
@@ -5354,11 +6123,17 @@ class SpotifyClient:
|
|
|
5354
6123
|
If the method fails for any other reason.
|
|
5355
6124
|
|
|
5356
6125
|
<details>
|
|
5357
|
-
<summary>Sample Code</summary>
|
|
6126
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
5358
6127
|
```python
|
|
5359
6128
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetPlaylistItems.py
|
|
5360
6129
|
```
|
|
5361
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>
|
|
5362
6137
|
"""
|
|
5363
6138
|
apiMethodName:str = 'GetPlaylistItems'
|
|
5364
6139
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -5374,6 +6149,7 @@ class SpotifyClient:
|
|
|
5374
6149
|
apiMethodParms.AppendKeyValue("market", market)
|
|
5375
6150
|
apiMethodParms.AppendKeyValue("fields", fields)
|
|
5376
6151
|
apiMethodParms.AppendKeyValue("additionalTypes", additionalTypes)
|
|
6152
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
5377
6153
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get full details of the items of a playlist owned by a Spotify user", apiMethodParms)
|
|
5378
6154
|
|
|
5379
6155
|
# validations.
|
|
@@ -5381,6 +6157,19 @@ class SpotifyClient:
|
|
|
5381
6157
|
limit = 20
|
|
5382
6158
|
if offset is None:
|
|
5383
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)
|
|
5384
6173
|
|
|
5385
6174
|
# build spotify web api request parameters.
|
|
5386
6175
|
urlParms:dict = \
|
|
@@ -5395,17 +6184,49 @@ class SpotifyClient:
|
|
|
5395
6184
|
if additionalTypes is not None:
|
|
5396
6185
|
urlParms['additional_types'] = additionalTypes
|
|
5397
6186
|
|
|
5398
|
-
#
|
|
5399
|
-
|
|
5400
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5401
|
-
msg.UrlParameters = urlParms
|
|
5402
|
-
self.MakeRequest('GET', msg)
|
|
6187
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
6188
|
+
while True:
|
|
5403
6189
|
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
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
|
+
|
|
5407
6228
|
# trace.
|
|
5408
|
-
_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)
|
|
5409
6230
|
return result
|
|
5410
6231
|
|
|
5411
6232
|
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
@@ -5424,6 +6245,7 @@ class SpotifyClient:
|
|
|
5424
6245
|
def GetPlaylistFavorites(self,
|
|
5425
6246
|
limit:int=20,
|
|
5426
6247
|
offset:int=0,
|
|
6248
|
+
limitTotal:int=None
|
|
5427
6249
|
) -> PlaylistPageSimplified:
|
|
5428
6250
|
"""
|
|
5429
6251
|
Get a list of the playlists owned or followed by the current Spotify user.
|
|
@@ -5432,12 +6254,18 @@ class SpotifyClient:
|
|
|
5432
6254
|
|
|
5433
6255
|
Args:
|
|
5434
6256
|
limit (int):
|
|
5435
|
-
The maximum number of items to return.
|
|
6257
|
+
The maximum number of items to return in a page of items.
|
|
5436
6258
|
Default: 20, Range: 1 to 50.
|
|
5437
6259
|
offset (int):
|
|
5438
|
-
The index of the first item to return.
|
|
6260
|
+
The page index offset of the first item to return.
|
|
5439
6261
|
Use with limit to get the next set of items.
|
|
5440
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)
|
|
5441
6269
|
|
|
5442
6270
|
Returns:
|
|
5443
6271
|
An `PlaylistPageSimplified` object that contains playlist information.
|
|
@@ -5450,11 +6278,17 @@ class SpotifyClient:
|
|
|
5450
6278
|
If the method fails for any other reason.
|
|
5451
6279
|
|
|
5452
6280
|
<details>
|
|
5453
|
-
<summary>Sample Code</summary>
|
|
6281
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
5454
6282
|
```python
|
|
5455
6283
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetPlaylistFavorites.py
|
|
5456
6284
|
```
|
|
5457
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>
|
|
5458
6292
|
"""
|
|
5459
6293
|
apiMethodName:str = 'GetPlaylistFavorites'
|
|
5460
6294
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -5466,6 +6300,7 @@ class SpotifyClient:
|
|
|
5466
6300
|
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
5467
6301
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
5468
6302
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
6303
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
5469
6304
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the users playlist favorites", apiMethodParms)
|
|
5470
6305
|
|
|
5471
6306
|
# validations.
|
|
@@ -5473,6 +6308,16 @@ class SpotifyClient:
|
|
|
5473
6308
|
limit = 20
|
|
5474
6309
|
if offset is None:
|
|
5475
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()
|
|
5476
6321
|
|
|
5477
6322
|
# build spotify web api request parameters.
|
|
5478
6323
|
urlParms:dict = \
|
|
@@ -5481,14 +6326,48 @@ class SpotifyClient:
|
|
|
5481
6326
|
'offset': offset,
|
|
5482
6327
|
}
|
|
5483
6328
|
|
|
5484
|
-
#
|
|
5485
|
-
|
|
5486
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5487
|
-
msg.UrlParameters = urlParms
|
|
5488
|
-
self.MakeRequest('GET', msg)
|
|
6329
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
6330
|
+
while True:
|
|
5489
6331
|
|
|
5490
|
-
|
|
5491
|
-
|
|
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)
|
|
5492
6371
|
|
|
5493
6372
|
# trace.
|
|
5494
6373
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -5511,6 +6390,7 @@ class SpotifyClient:
|
|
|
5511
6390
|
userId:str,
|
|
5512
6391
|
limit:int=20,
|
|
5513
6392
|
offset:int=0,
|
|
6393
|
+
limitTotal:int=None
|
|
5514
6394
|
) -> PlaylistPageSimplified:
|
|
5515
6395
|
"""
|
|
5516
6396
|
Get a list of the playlists owned or followed by a Spotify user.
|
|
@@ -5522,12 +6402,18 @@ class SpotifyClient:
|
|
|
5522
6402
|
The user's Spotify user ID.
|
|
5523
6403
|
Example: `smedjan`
|
|
5524
6404
|
limit (int):
|
|
5525
|
-
The maximum number of items to return.
|
|
6405
|
+
The maximum number of items to return in a page of items.
|
|
5526
6406
|
Default: 20, Range: 1 to 50.
|
|
5527
6407
|
offset (int):
|
|
5528
|
-
The index of the first item to return.
|
|
6408
|
+
The page index offset of the first item to return.
|
|
5529
6409
|
Use with limit to get the next set of items.
|
|
5530
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)
|
|
5531
6417
|
|
|
5532
6418
|
Returns:
|
|
5533
6419
|
An `PlaylistPageSimplified` object that contains playlist information.
|
|
@@ -5540,11 +6426,17 @@ class SpotifyClient:
|
|
|
5540
6426
|
If the method fails for any other reason.
|
|
5541
6427
|
|
|
5542
6428
|
<details>
|
|
5543
|
-
<summary>Sample Code</summary>
|
|
6429
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
5544
6430
|
```python
|
|
5545
6431
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetPlaylistsForUser.py
|
|
5546
6432
|
```
|
|
5547
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>
|
|
5548
6440
|
"""
|
|
5549
6441
|
apiMethodName:str = 'GetPlaylistsForUser'
|
|
5550
6442
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -5557,6 +6449,7 @@ class SpotifyClient:
|
|
|
5557
6449
|
apiMethodParms.AppendKeyValue("userId", userId)
|
|
5558
6450
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
5559
6451
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
6452
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
5560
6453
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the playlists owned or followed by a Spotify user", apiMethodParms)
|
|
5561
6454
|
|
|
5562
6455
|
# validations.
|
|
@@ -5564,6 +6457,16 @@ class SpotifyClient:
|
|
|
5564
6457
|
limit = 20
|
|
5565
6458
|
if offset is None:
|
|
5566
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()
|
|
5567
6470
|
|
|
5568
6471
|
# build spotify web api request parameters.
|
|
5569
6472
|
urlParms:dict = \
|
|
@@ -5573,14 +6476,48 @@ class SpotifyClient:
|
|
|
5573
6476
|
'offset': offset,
|
|
5574
6477
|
}
|
|
5575
6478
|
|
|
5576
|
-
#
|
|
5577
|
-
|
|
5578
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5579
|
-
msg.UrlParameters = urlParms
|
|
5580
|
-
self.MakeRequest('GET', msg)
|
|
6479
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
6480
|
+
while True:
|
|
5581
6481
|
|
|
5582
|
-
|
|
5583
|
-
|
|
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)
|
|
5584
6521
|
|
|
5585
6522
|
# trace.
|
|
5586
6523
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -5653,6 +6590,9 @@ class SpotifyClient:
|
|
|
5653
6590
|
apiMethodParms.AppendKeyValue("market", market)
|
|
5654
6591
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for a single show", apiMethodParms)
|
|
5655
6592
|
|
|
6593
|
+
# ensure market was either supplied or implied; default if neither.
|
|
6594
|
+
market = self._ValidateMarket(market)
|
|
6595
|
+
|
|
5656
6596
|
# build spotify web api request parameters.
|
|
5657
6597
|
urlParms:dict = {}
|
|
5658
6598
|
if market is not None:
|
|
@@ -5688,7 +6628,8 @@ class SpotifyClient:
|
|
|
5688
6628
|
showId:str,
|
|
5689
6629
|
limit:int=20,
|
|
5690
6630
|
offset:int=0,
|
|
5691
|
-
market:str=None
|
|
6631
|
+
market:str=None,
|
|
6632
|
+
limitTotal:int=None
|
|
5692
6633
|
) -> EpisodePageSimplified:
|
|
5693
6634
|
"""
|
|
5694
6635
|
Get Spotify catalog information about a show's episodes.
|
|
@@ -5700,7 +6641,7 @@ class SpotifyClient:
|
|
|
5700
6641
|
The Spotify ID for the show.
|
|
5701
6642
|
Example: `38bS44xjbVVZ3No3ByF1dJ`
|
|
5702
6643
|
limit (int):
|
|
5703
|
-
The maximum number of items to return.
|
|
6644
|
+
The maximum number of items to return in a page of items.
|
|
5704
6645
|
Default: 20, Range: 1 to 50.
|
|
5705
6646
|
offset (int):
|
|
5706
6647
|
The index of the first item to return; use with limit to get the next set of items.
|
|
@@ -5713,6 +6654,12 @@ class SpotifyClient:
|
|
|
5713
6654
|
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
5714
6655
|
Users can view the country that is associated with their account in the account settings.
|
|
5715
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)
|
|
5716
6663
|
|
|
5717
6664
|
Returns:
|
|
5718
6665
|
A `EpisodePageSimplified` object that contains simplified track information for the showId.
|
|
@@ -5725,11 +6672,17 @@ class SpotifyClient:
|
|
|
5725
6672
|
If the method fails for any other reason.
|
|
5726
6673
|
|
|
5727
6674
|
<details>
|
|
5728
|
-
<summary>Sample Code</summary>
|
|
6675
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
5729
6676
|
```python
|
|
5730
6677
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetShowEpisodes.py
|
|
5731
6678
|
```
|
|
5732
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>
|
|
5733
6686
|
"""
|
|
5734
6687
|
apiMethodName:str = 'GetShowEpisodes'
|
|
5735
6688
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -5743,6 +6696,7 @@ class SpotifyClient:
|
|
|
5743
6696
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
5744
6697
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
5745
6698
|
apiMethodParms.AppendKeyValue("market", market)
|
|
6699
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
5746
6700
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information about a show's episodes", apiMethodParms)
|
|
5747
6701
|
|
|
5748
6702
|
# validations.
|
|
@@ -5750,6 +6704,19 @@ class SpotifyClient:
|
|
|
5750
6704
|
limit = 20
|
|
5751
6705
|
if offset is None:
|
|
5752
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)
|
|
5753
6720
|
|
|
5754
6721
|
# build spotify web api request parameters.
|
|
5755
6722
|
urlParms:dict = \
|
|
@@ -5760,25 +6727,57 @@ class SpotifyClient:
|
|
|
5760
6727
|
if market is not None:
|
|
5761
6728
|
urlParms['market'] = market
|
|
5762
6729
|
|
|
5763
|
-
#
|
|
5764
|
-
|
|
5765
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5766
|
-
msg.UrlParameters = urlParms
|
|
5767
|
-
self.MakeRequest('GET', msg)
|
|
6730
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
6731
|
+
while True:
|
|
5768
6732
|
|
|
5769
|
-
|
|
5770
|
-
|
|
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)
|
|
5771
6738
|
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
return result
|
|
6739
|
+
# process results.
|
|
6740
|
+
pageObj = EpisodePageSimplified(root=msg.ResponseData)
|
|
5775
6741
|
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
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.
|
|
6770
|
+
|
|
6771
|
+
# trace.
|
|
6772
|
+
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
6773
|
+
return result
|
|
6774
|
+
|
|
6775
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
6776
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
6777
|
+
except Exception as ex:
|
|
6778
|
+
|
|
6779
|
+
# format unhandled exception.
|
|
6780
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
5782
6781
|
|
|
5783
6782
|
finally:
|
|
5784
6783
|
|
|
@@ -5789,6 +6788,7 @@ class SpotifyClient:
|
|
|
5789
6788
|
def GetShowFavorites(self,
|
|
5790
6789
|
limit:int=20,
|
|
5791
6790
|
offset:int=0,
|
|
6791
|
+
limitTotal:int=None
|
|
5792
6792
|
) -> ShowPageSaved:
|
|
5793
6793
|
"""
|
|
5794
6794
|
Get a list of the shows saved in the current Spotify user's 'Your Library'.
|
|
@@ -5797,12 +6797,18 @@ class SpotifyClient:
|
|
|
5797
6797
|
|
|
5798
6798
|
Args:
|
|
5799
6799
|
limit (int):
|
|
5800
|
-
The maximum number of items to return.
|
|
6800
|
+
The maximum number of items to return in a page of items.
|
|
5801
6801
|
Default: 20, Range: 1 to 50.
|
|
5802
6802
|
offset (int):
|
|
5803
|
-
The index of the first item to return.
|
|
6803
|
+
The page index offset of the first item to return.
|
|
5804
6804
|
Use with limit to get the next set of items.
|
|
5805
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)
|
|
5806
6812
|
|
|
5807
6813
|
Returns:
|
|
5808
6814
|
An `ShowPageSaved` object that contains saved show information.
|
|
@@ -5815,11 +6821,17 @@ class SpotifyClient:
|
|
|
5815
6821
|
If the method fails for any other reason.
|
|
5816
6822
|
|
|
5817
6823
|
<details>
|
|
5818
|
-
<summary>Sample Code</summary>
|
|
6824
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
5819
6825
|
```python
|
|
5820
6826
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetShowFavorites.py
|
|
5821
6827
|
```
|
|
5822
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>
|
|
5823
6835
|
"""
|
|
5824
6836
|
apiMethodName:str = 'GetShowFavorites'
|
|
5825
6837
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -5831,6 +6843,7 @@ class SpotifyClient:
|
|
|
5831
6843
|
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
5832
6844
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
5833
6845
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
6846
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
5834
6847
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the users show favorites", apiMethodParms)
|
|
5835
6848
|
|
|
5836
6849
|
# validations.
|
|
@@ -5838,6 +6851,16 @@ class SpotifyClient:
|
|
|
5838
6851
|
limit = 20
|
|
5839
6852
|
if offset is None:
|
|
5840
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()
|
|
5841
6864
|
|
|
5842
6865
|
# build spotify web api request parameters.
|
|
5843
6866
|
urlParms:dict = \
|
|
@@ -5846,14 +6869,48 @@ class SpotifyClient:
|
|
|
5846
6869
|
'offset': offset,
|
|
5847
6870
|
}
|
|
5848
6871
|
|
|
5849
|
-
#
|
|
5850
|
-
|
|
5851
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
5852
|
-
msg.UrlParameters = urlParms
|
|
5853
|
-
self.MakeRequest('GET', msg)
|
|
6872
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
6873
|
+
while True:
|
|
5854
6874
|
|
|
5855
|
-
|
|
5856
|
-
|
|
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)
|
|
5857
6914
|
|
|
5858
6915
|
# trace.
|
|
5859
6916
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
@@ -5927,6 +6984,9 @@ class SpotifyClient:
|
|
|
5927
6984
|
apiMethodParms.AppendKeyValue("market", market)
|
|
5928
6985
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for multiple shows", apiMethodParms)
|
|
5929
6986
|
|
|
6987
|
+
# ensure market was either supplied or implied; default if neither.
|
|
6988
|
+
market = self._ValidateMarket(market)
|
|
6989
|
+
|
|
5930
6990
|
# build spotify web api request parameters.
|
|
5931
6991
|
urlParms:dict = \
|
|
5932
6992
|
{
|
|
@@ -6095,6 +7155,7 @@ class SpotifyClient:
|
|
|
6095
7155
|
limit:int=20,
|
|
6096
7156
|
offset:int=0,
|
|
6097
7157
|
market:str=None,
|
|
7158
|
+
limitTotal:int=None
|
|
6098
7159
|
) -> TrackPageSaved:
|
|
6099
7160
|
"""
|
|
6100
7161
|
Get a list of the tracks saved in the current Spotify user's 'Your Library'.
|
|
@@ -6103,10 +7164,10 @@ class SpotifyClient:
|
|
|
6103
7164
|
|
|
6104
7165
|
Args:
|
|
6105
7166
|
limit (int):
|
|
6106
|
-
The maximum number of items to return.
|
|
7167
|
+
The maximum number of items to return in a page of items.
|
|
6107
7168
|
Default: 20, Range: 1 to 50.
|
|
6108
7169
|
offset (int):
|
|
6109
|
-
The index of the first item to return.
|
|
7170
|
+
The page index offset of the first item to return.
|
|
6110
7171
|
Use with limit to get the next set of items.
|
|
6111
7172
|
Default: 0 (the first item).
|
|
6112
7173
|
market (str):
|
|
@@ -6117,6 +7178,12 @@ class SpotifyClient:
|
|
|
6117
7178
|
Note: If neither market or user country are provided, the content is considered unavailable for the client.
|
|
6118
7179
|
Users can view the country that is associated with their account in the account settings.
|
|
6119
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)
|
|
6120
7187
|
|
|
6121
7188
|
Returns:
|
|
6122
7189
|
An `TrackPageSaved` object that contains saved track information.
|
|
@@ -6129,11 +7196,17 @@ class SpotifyClient:
|
|
|
6129
7196
|
If the method fails for any other reason.
|
|
6130
7197
|
|
|
6131
7198
|
<details>
|
|
6132
|
-
<summary>Sample Code</summary>
|
|
7199
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
6133
7200
|
```python
|
|
6134
7201
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetTrackFavorites.py
|
|
6135
7202
|
```
|
|
6136
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>
|
|
6137
7210
|
"""
|
|
6138
7211
|
apiMethodName:str = 'GetTrackFavorites'
|
|
6139
7212
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -6146,6 +7219,7 @@ class SpotifyClient:
|
|
|
6146
7219
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
6147
7220
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
6148
7221
|
apiMethodParms.AppendKeyValue("market", market)
|
|
7222
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
6149
7223
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get a list of the users track favorites", apiMethodParms)
|
|
6150
7224
|
|
|
6151
7225
|
# validations.
|
|
@@ -6153,6 +7227,19 @@ class SpotifyClient:
|
|
|
6153
7227
|
limit = 20
|
|
6154
7228
|
if offset is None:
|
|
6155
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)
|
|
6156
7243
|
|
|
6157
7244
|
# build spotify web api request parameters.
|
|
6158
7245
|
urlParms:dict = \
|
|
@@ -6163,15 +7250,49 @@ class SpotifyClient:
|
|
|
6163
7250
|
if market is not None:
|
|
6164
7251
|
urlParms['market'] = market
|
|
6165
7252
|
|
|
6166
|
-
#
|
|
6167
|
-
|
|
6168
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
6169
|
-
msg.UrlParameters = urlParms
|
|
6170
|
-
self.MakeRequest('GET', msg)
|
|
7253
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
7254
|
+
while True:
|
|
6171
7255
|
|
|
6172
|
-
|
|
6173
|
-
|
|
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)
|
|
6174
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
|
+
|
|
6175
7296
|
# trace.
|
|
6176
7297
|
_logsi.LogObject(SILevel.Verbose, (TRACE_METHOD_RESULT_TYPE + result.PagingInfo) % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
6177
7298
|
return result
|
|
@@ -6239,6 +7360,9 @@ class SpotifyClient:
|
|
|
6239
7360
|
apiMethodParms.AppendKeyValue("market", market)
|
|
6240
7361
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify catalog information for multiple tracks", apiMethodParms)
|
|
6241
7362
|
|
|
7363
|
+
# ensure market was either supplied or implied; default if neither.
|
|
7364
|
+
market = self._ValidateMarket(market)
|
|
7365
|
+
|
|
6242
7366
|
# build spotify web api request parameters.
|
|
6243
7367
|
urlParms:dict = \
|
|
6244
7368
|
{
|
|
@@ -6378,7 +7502,7 @@ class SpotifyClient:
|
|
|
6378
7502
|
|
|
6379
7503
|
Args:
|
|
6380
7504
|
limit (int):
|
|
6381
|
-
The maximum number of items to return.
|
|
7505
|
+
The maximum number of items to return in a page of items.
|
|
6382
7506
|
Default: 20, Range: 1 to 50.
|
|
6383
7507
|
market (str):
|
|
6384
7508
|
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
@@ -6609,6 +7733,9 @@ class SpotifyClient:
|
|
|
6609
7733
|
apiMethodParms.AppendKeyValue("targetValence", targetValence)
|
|
6610
7734
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get track recommendations for specified criteria", apiMethodParms)
|
|
6611
7735
|
|
|
7736
|
+
# ensure market was either supplied or implied; default if neither.
|
|
7737
|
+
market = self._ValidateMarket(market)
|
|
7738
|
+
|
|
6612
7739
|
# build spotify web api request parameters.
|
|
6613
7740
|
urlParms:dict = \
|
|
6614
7741
|
{
|
|
@@ -6939,7 +8066,8 @@ class SpotifyClient:
|
|
|
6939
8066
|
def GetUsersTopArtists(self,
|
|
6940
8067
|
timeRange:str='medium_term',
|
|
6941
8068
|
limit:int=20,
|
|
6942
|
-
offset:int=0
|
|
8069
|
+
offset:int=0,
|
|
8070
|
+
limitTotal:int=None
|
|
6943
8071
|
) -> ArtistPage:
|
|
6944
8072
|
"""
|
|
6945
8073
|
Get the current user's top artists based on calculated affinity.
|
|
@@ -6954,12 +8082,18 @@ class SpotifyClient:
|
|
|
6954
8082
|
Default: `medium_term`
|
|
6955
8083
|
Example: `long_term`
|
|
6956
8084
|
limit (int):
|
|
6957
|
-
The maximum number of items to return.
|
|
8085
|
+
The maximum number of items to return in a page of items.
|
|
6958
8086
|
Default: 20, Range: 1 to 50.
|
|
6959
8087
|
offset (int):
|
|
6960
|
-
The index of the first item to return.
|
|
8088
|
+
The page index offset of the first item to return.
|
|
6961
8089
|
Use with limit to get the next set of items.
|
|
6962
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)
|
|
6963
8097
|
|
|
6964
8098
|
Returns:
|
|
6965
8099
|
An `ArtistPage` object of matching results.
|
|
@@ -6972,11 +8106,17 @@ class SpotifyClient:
|
|
|
6972
8106
|
If the method fails for any other reason.
|
|
6973
8107
|
|
|
6974
8108
|
<details>
|
|
6975
|
-
<summary>Sample Code</summary>
|
|
8109
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
6976
8110
|
```python
|
|
6977
8111
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetUsersTopArtists.py
|
|
6978
8112
|
```
|
|
6979
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>
|
|
6980
8120
|
"""
|
|
6981
8121
|
apiMethodName:str = 'GetUsersTopArtists'
|
|
6982
8122
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -6989,6 +8129,7 @@ class SpotifyClient:
|
|
|
6989
8129
|
apiMethodParms.AppendKeyValue("timeRange", timeRange)
|
|
6990
8130
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
6991
8131
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
8132
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
6992
8133
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get the current user's top artists", apiMethodParms)
|
|
6993
8134
|
|
|
6994
8135
|
# validations.
|
|
@@ -6998,6 +8139,16 @@ class SpotifyClient:
|
|
|
6998
8139
|
limit = 20
|
|
6999
8140
|
if offset is None:
|
|
7000
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()
|
|
7001
8152
|
|
|
7002
8153
|
# build spotify web api request parameters.
|
|
7003
8154
|
urlParms:dict = \
|
|
@@ -7007,17 +8158,51 @@ class SpotifyClient:
|
|
|
7007
8158
|
'offset': offset,
|
|
7008
8159
|
}
|
|
7009
8160
|
|
|
7010
|
-
#
|
|
7011
|
-
|
|
7012
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
7013
|
-
msg.UrlParameters = urlParms
|
|
7014
|
-
self.MakeRequest('GET', msg)
|
|
8161
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
8162
|
+
while True:
|
|
7015
8163
|
|
|
7016
|
-
|
|
7017
|
-
|
|
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)
|
|
7018
8203
|
|
|
7019
8204
|
# trace.
|
|
7020
|
-
_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)
|
|
7021
8206
|
return result
|
|
7022
8207
|
|
|
7023
8208
|
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
@@ -7036,7 +8221,8 @@ class SpotifyClient:
|
|
|
7036
8221
|
def GetUsersTopTracks(self,
|
|
7037
8222
|
timeRange:str='medium_term',
|
|
7038
8223
|
limit:int=20,
|
|
7039
|
-
offset:int=0
|
|
8224
|
+
offset:int=0,
|
|
8225
|
+
limitTotal:int=None
|
|
7040
8226
|
) -> TrackPage:
|
|
7041
8227
|
"""
|
|
7042
8228
|
Get the current user's top tracks based on calculated affinity.
|
|
@@ -7051,12 +8237,18 @@ class SpotifyClient:
|
|
|
7051
8237
|
Default: `medium_term`
|
|
7052
8238
|
Example: `long_term`
|
|
7053
8239
|
limit (int):
|
|
7054
|
-
The maximum number of items to return.
|
|
8240
|
+
The maximum number of items to return in a page of items.
|
|
7055
8241
|
Default: 20, Range: 1 to 50.
|
|
7056
8242
|
offset (int):
|
|
7057
|
-
The index of the first item to return.
|
|
8243
|
+
The page index offset of the first item to return.
|
|
7058
8244
|
Use with limit to get the next set of items.
|
|
7059
|
-
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)
|
|
7060
8252
|
|
|
7061
8253
|
Returns:
|
|
7062
8254
|
An `TrackPage` object of matching results.
|
|
@@ -7069,11 +8261,17 @@ class SpotifyClient:
|
|
|
7069
8261
|
If the method fails for any other reason.
|
|
7070
8262
|
|
|
7071
8263
|
<details>
|
|
7072
|
-
<summary>Sample Code</summary>
|
|
8264
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
7073
8265
|
```python
|
|
7074
8266
|
.. include:: ../docs/include/samplecode/SpotifyClient/GetUsersTopTracks.py
|
|
7075
8267
|
```
|
|
7076
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>
|
|
7077
8275
|
"""
|
|
7078
8276
|
apiMethodName:str = 'GetUsersTopTracks'
|
|
7079
8277
|
apiMethodParms:SIMethodParmListContext = None
|
|
@@ -7086,6 +8284,7 @@ class SpotifyClient:
|
|
|
7086
8284
|
apiMethodParms.AppendKeyValue("timeRange", timeRange)
|
|
7087
8285
|
apiMethodParms.AppendKeyValue("limit", limit)
|
|
7088
8286
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
8287
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
7089
8288
|
_logsi.LogMethodParmList(SILevel.Verbose, "Get the current user's top tracks", apiMethodParms)
|
|
7090
8289
|
|
|
7091
8290
|
# validations.
|
|
@@ -7095,6 +8294,16 @@ class SpotifyClient:
|
|
|
7095
8294
|
limit = 20
|
|
7096
8295
|
if offset is None:
|
|
7097
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()
|
|
7098
8307
|
|
|
7099
8308
|
# build spotify web api request parameters.
|
|
7100
8309
|
urlParms:dict = \
|
|
@@ -7104,17 +8313,51 @@ class SpotifyClient:
|
|
|
7104
8313
|
'offset': offset,
|
|
7105
8314
|
}
|
|
7106
8315
|
|
|
7107
|
-
#
|
|
7108
|
-
|
|
7109
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
7110
|
-
msg.UrlParameters = urlParms
|
|
7111
|
-
self.MakeRequest('GET', msg)
|
|
8316
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
8317
|
+
while True:
|
|
7112
8318
|
|
|
7113
|
-
|
|
7114
|
-
|
|
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)
|
|
7115
8358
|
|
|
7116
8359
|
# trace.
|
|
7117
|
-
_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)
|
|
7118
8361
|
return result
|
|
7119
8362
|
|
|
7120
8363
|
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
@@ -9214,18 +10457,192 @@ class SpotifyClient:
|
|
|
9214
10457
|
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
9215
10458
|
|
|
9216
10459
|
|
|
9217
|
-
def Search(self,
|
|
9218
|
-
|
|
9219
|
-
|
|
9220
|
-
|
|
9221
|
-
|
|
9222
|
-
|
|
9223
|
-
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9228
|
-
|
|
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.
|
|
9229
10646
|
|
|
9230
10647
|
Args:
|
|
9231
10648
|
criteria (str):
|
|
@@ -9241,18 +10658,13 @@ class SpotifyClient:
|
|
|
9241
10658
|
The upc, tag:new and tag:hipster filters can only be used while searching albums.
|
|
9242
10659
|
The tag:new filter will return albums released in the past two weeks and tag:hipster
|
|
9243
10660
|
can be used to return only albums with the lowest 10% popularity.
|
|
9244
|
-
criteriaType (str):
|
|
9245
|
-
A comma-separated list of item types to search across.
|
|
9246
|
-
Search results include hits from all the specified item types.
|
|
9247
|
-
For example: "album,track" returns both albums and tracks matching criteria argument.
|
|
9248
|
-
Allowed values: "album", "artist", "playlist", "track", "show", "episode", "audiobook".
|
|
9249
10661
|
limit (int):
|
|
9250
|
-
The maximum number of items to return.
|
|
10662
|
+
The maximum number of items to return in a page of items.
|
|
9251
10663
|
Default: 20, Range: 1 to 50.
|
|
9252
10664
|
offset (int):
|
|
9253
|
-
The index of the first item to return.
|
|
10665
|
+
The page index offset of the first item to return.
|
|
9254
10666
|
Use with limit to get the next set of items.
|
|
9255
|
-
Default: 0 (the first item)
|
|
10667
|
+
Default: 0 (the first item). Range: 0 to 1000.
|
|
9256
10668
|
market (str):
|
|
9257
10669
|
An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that
|
|
9258
10670
|
is available in that market will be returned. If a valid user access token is specified
|
|
@@ -9266,6 +10678,12 @@ class SpotifyClient:
|
|
|
9266
10678
|
marks the content as playable in the response. By default externally hosted audio content is marked
|
|
9267
10679
|
as unplayable in the response.
|
|
9268
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)
|
|
9269
10687
|
|
|
9270
10688
|
Returns:
|
|
9271
10689
|
A `SearchResponse` object that contains the search results.
|
|
@@ -9277,61 +10695,26 @@ class SpotifyClient:
|
|
|
9277
10695
|
SpotifApiError:
|
|
9278
10696
|
If the method fails for any other reason.
|
|
9279
10697
|
|
|
9280
|
-
Note
|
|
9281
|
-
|
|
10698
|
+
Note that Spotify Web API automatically limits you to 1,000 max entries per type that can
|
|
10699
|
+
be returned with a search.
|
|
9282
10700
|
|
|
9283
10701
|
<details>
|
|
9284
|
-
<summary>Sample Code -
|
|
10702
|
+
<summary>Sample Code - Manual Paging</summary>
|
|
9285
10703
|
```python
|
|
9286
10704
|
.. include:: ../docs/include/samplecode/SpotifyClient/SearchAlbums.py
|
|
9287
10705
|
```
|
|
9288
10706
|
</details>
|
|
9289
|
-
|
|
9290
|
-
<details>
|
|
9291
|
-
<summary>Sample Code - Search Artists</summary>
|
|
9292
|
-
```python
|
|
9293
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/SearchArtists.py
|
|
9294
|
-
```
|
|
9295
|
-
</details>
|
|
9296
|
-
|
|
9297
|
-
<details>
|
|
9298
|
-
<summary>Sample Code - Search Audiobooks</summary>
|
|
9299
|
-
```python
|
|
9300
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/SearchAudiobooks.py
|
|
9301
|
-
```
|
|
9302
|
-
</details>
|
|
9303
|
-
|
|
9304
|
-
<details>
|
|
9305
|
-
<summary>Sample Code - Search Episodes</summary>
|
|
9306
|
-
```python
|
|
9307
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/SearchEpisodes.py
|
|
9308
|
-
```
|
|
9309
|
-
</details>
|
|
9310
|
-
|
|
9311
|
-
<details>
|
|
9312
|
-
<summary>Sample Code - Search Playlists</summary>
|
|
9313
|
-
```python
|
|
9314
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/SearchPlaylists.py
|
|
9315
|
-
```
|
|
9316
|
-
</details>
|
|
9317
|
-
|
|
9318
|
-
<details>
|
|
9319
|
-
<summary>Sample Code - Search Shows</summary>
|
|
9320
|
-
```python
|
|
9321
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/SearchShows.py
|
|
9322
|
-
```
|
|
9323
|
-
</details>
|
|
9324
|
-
|
|
9325
10707
|
<details>
|
|
9326
|
-
<summary>Sample Code -
|
|
10708
|
+
<summary>Sample Code - Auto Paging</summary>
|
|
9327
10709
|
```python
|
|
9328
|
-
.. include:: ../docs/include/samplecode/SpotifyClient/
|
|
10710
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/SearchAlbums_AutoPaging.py
|
|
9329
10711
|
```
|
|
9330
10712
|
</details>
|
|
9331
10713
|
"""
|
|
9332
|
-
apiMethodName:str = '
|
|
10714
|
+
apiMethodName:str = 'SearchAlbums'
|
|
9333
10715
|
apiMethodParms:SIMethodParmListContext = None
|
|
9334
|
-
|
|
10716
|
+
criteriaType:str = 'album'
|
|
10717
|
+
result:AlbumPageSimplified = None
|
|
9335
10718
|
|
|
9336
10719
|
try:
|
|
9337
10720
|
|
|
@@ -9343,13 +10726,26 @@ class SpotifyClient:
|
|
|
9343
10726
|
apiMethodParms.AppendKeyValue("offset", offset)
|
|
9344
10727
|
apiMethodParms.AppendKeyValue("market", market)
|
|
9345
10728
|
apiMethodParms.AppendKeyValue("includeExternal", includeExternal)
|
|
9346
|
-
|
|
10729
|
+
apiMethodParms.AppendKeyValue("limitTotal", limitTotal)
|
|
10730
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Searching Spotify catalog for %s information" % criteriaType, apiMethodParms)
|
|
9347
10731
|
|
|
9348
10732
|
# validations.
|
|
9349
10733
|
if limit is None:
|
|
9350
10734
|
limit = 20
|
|
9351
10735
|
if offset is None:
|
|
9352
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)
|
|
9353
10749
|
|
|
9354
10750
|
# build spotify web api request parameters.
|
|
9355
10751
|
urlParms:dict = \
|
|
@@ -9364,18 +10760,1203 @@ class SpotifyClient:
|
|
|
9364
10760
|
if includeExternal is not None:
|
|
9365
10761
|
urlParms['include_external'] = includeExternal
|
|
9366
10762
|
|
|
9367
|
-
#
|
|
9368
|
-
|
|
9369
|
-
msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
|
|
9370
|
-
msg.UrlParameters = urlParms
|
|
9371
|
-
self.MakeRequest('GET', msg)
|
|
10763
|
+
# handle pagination, as spotify limits us to a set # of items returned per response.
|
|
10764
|
+
while True:
|
|
9372
10765
|
|
|
9373
|
-
|
|
9374
|
-
|
|
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.
|
|
9375
10804
|
|
|
9376
10805
|
# trace.
|
|
9377
|
-
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
9378
|
-
|
|
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
|
|
9379
11960
|
|
|
9380
11961
|
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
9381
11962
|
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
@@ -9808,14 +12389,16 @@ class SpotifyClient:
|
|
|
9808
12389
|
|
|
9809
12390
|
# note that we cannot retrieve spotify user basic details, as the client credentials
|
|
9810
12391
|
# authentication type does not utilize an authorization token. in this case, we will
|
|
9811
|
-
# 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).
|
|
9812
12396
|
userProfile:UserProfile = UserProfile()
|
|
9813
12397
|
userProfile._DisplayName = 'Public Access'
|
|
9814
12398
|
userProfile._Followers = Followers()
|
|
9815
12399
|
userProfile._Followers._Total = 0
|
|
9816
12400
|
userProfile._Id = 'unknown'
|
|
9817
12401
|
userProfile._Uri = 'spotify.user.' + userProfile._Id
|
|
9818
|
-
userProfile._Country = 'unknown'
|
|
9819
12402
|
self._UserProfile = userProfile
|
|
9820
12403
|
|
|
9821
12404
|
# trace.
|