mirror of
https://github.com/spotipy-dev/spotipy.git
synced 2026-06-19 09:13:53 +00:00
Fix return object formatting for multi-market searches (#527)
* resolve return object formatting issues referened in #526 * resolve comments from @ritiek * create separate method to search multiple markets * Use old description again * market -> markets + fix test * pep8 * Use break Co-authored-by: Stephane Bruckert <contact@stephanebruckert.com>
This commit is contained in:
parent
7eb0eaaebc
commit
f7fb8757e9
@ -508,40 +508,49 @@ class Spotify(object):
|
|||||||
tlist = [self._get_id("episode", e) for e in episodes]
|
tlist = [self._get_id("episode", e) for e in episodes]
|
||||||
return self._get("episodes/?ids=" + ",".join(tlist), market=market)
|
return self._get("episodes/?ids=" + ",".join(tlist), market=market)
|
||||||
|
|
||||||
def search(self, q, limit=10, offset=0, type="track", market=None, total=None):
|
def search(self, q, limit=10, offset=0, type="track", market=None):
|
||||||
""" searches for an item
|
""" searches for an item
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- q - the search query (see how to write a query in the
|
||||||
|
official documentation https://developer.spotify.com/documentation/web-api/reference/search/search/) # noqa
|
||||||
|
- limit - the number of items to return (min = 1, default = 10, max = 50)
|
||||||
|
- offset - the index of the first item to return
|
||||||
|
- type - the type of item to return. One of 'artist', 'album',
|
||||||
|
'track', 'playlist', 'show', or 'episode'
|
||||||
|
- market - An ISO 3166-1 alpha-2 country code or the string
|
||||||
|
from_token.
|
||||||
|
"""
|
||||||
|
return self._get(
|
||||||
|
"search", q=q, limit=limit, offset=offset, type=type, market=market
|
||||||
|
)
|
||||||
|
|
||||||
|
def search_markets(self, q, limit=10, offset=0, type="track", markets=None, total=None):
|
||||||
|
""" searches multple markets for an item
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
- q - the search query (see how to write a query in the
|
- q - the search query (see how to write a query in the
|
||||||
official documentation https://developer.spotify.com/documentation/web-api/reference/search/search/) # noqa
|
official documentation https://developer.spotify.com/documentation/web-api/reference/search/search/) # noqa
|
||||||
- limit - the number of items to return (min = 1, default = 10, max = 50). If a search is to be done on multiple
|
- limit - the number of items to return (min = 1, default = 10, max = 50). If a search is to be done on multiple
|
||||||
markets, then this limit is applied to each market. (e.g. search US, CA, MX each with a limit of 10).
|
markets, then this limit is applied to each market. (e.g. search US, CA, MX each with a limit of 10).
|
||||||
- offset - the index of the first item to return
|
- offset - the index of the first item to return
|
||||||
- type - the type of item to return. One of 'artist', 'album',
|
- type - the type's of item's to return. One or more of 'artist', 'album',
|
||||||
'track', 'playlist', 'show', or 'episode'
|
'track', 'playlist', 'show', or 'episode'. If multiple types are desired, pass in a comma separated list.
|
||||||
- market - An ISO 3166-1 alpha-2 country code or the string
|
- markets - A list of ISO 3166-1 alpha-2 country codes. Search all country markets by default.
|
||||||
from_token. Can supply list of markets. Pass "ALL" to search all country codes.
|
|
||||||
- total - the total number of results to return if multiple markets are supplied in the search.
|
- total - the total number of results to return if multiple markets are supplied in the search.
|
||||||
|
If multiple types are specified, this only applies to the first type.
|
||||||
"""
|
"""
|
||||||
|
if not markets:
|
||||||
|
markets = self.country_codes
|
||||||
|
|
||||||
if (isinstance(market, str) and market.upper() == "ALL"):
|
if not (isinstance(markets, list) or isinstance(markets, tuple)):
|
||||||
warnings.warn(
|
markets = []
|
||||||
"Searching all markets is poorly performing.",
|
|
||||||
UserWarning,
|
|
||||||
)
|
|
||||||
return self._search_multiple_markets(q, limit, offset, type, self.country_codes, total)
|
|
||||||
|
|
||||||
elif isinstance(market, list) or isinstance(market, tuple):
|
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"Searching multiple markets is poorly performing.",
|
"Searching multiple markets is poorly performing.",
|
||||||
UserWarning,
|
UserWarning,
|
||||||
)
|
)
|
||||||
return self._search_multiple_markets(q, limit, offset, type, market, total)
|
return self._search_multiple_markets(q, limit, offset, type, markets, total)
|
||||||
|
|
||||||
else:
|
|
||||||
return self._get(
|
|
||||||
"search", q=q, limit=limit, offset=offset, type=type, market=market
|
|
||||||
)
|
|
||||||
|
|
||||||
def user(self, user):
|
def user(self, user):
|
||||||
""" Gets basic profile information about a Spotify User
|
""" Gets basic profile information about a Spotify User
|
||||||
@ -1562,26 +1571,30 @@ class Spotify(object):
|
|||||||
return "spotify:" + type + ":" + self._get_id(type, id)
|
return "spotify:" + type + ":" + self._get_id(type, id)
|
||||||
|
|
||||||
def _search_multiple_markets(self, q, limit, offset, type, markets, total):
|
def _search_multiple_markets(self, q, limit, offset, type, markets, total):
|
||||||
results = {
|
if total and limit > total:
|
||||||
type + 's': {
|
limit = total
|
||||||
'href': [],
|
warnings.warn(
|
||||||
'items': [],
|
"limit was auto-adjusted to equal {} as it must not be higher than total".format(
|
||||||
'limit': limit,
|
total),
|
||||||
'next': None,
|
UserWarning,
|
||||||
'offset': 0,
|
)
|
||||||
'previous': None,
|
|
||||||
'total': 0
|
results = {}
|
||||||
}
|
first_type = type.split(",")[0] + 's'
|
||||||
}
|
count = 0
|
||||||
|
|
||||||
for country in markets:
|
for country in markets:
|
||||||
result = self._get(
|
result = self._get(
|
||||||
"search", q=q, limit=limit, offset=offset, type=type, market=country
|
"search", q=q, limit=limit, offset=offset, type=type, market=country
|
||||||
)
|
)
|
||||||
results[type + 's']['href'].append(result[type + 's']['href'])
|
results[country] = result
|
||||||
results[type + 's']['items'] += result[type + 's']['items']
|
|
||||||
results[type + 's']['total'] += result[type + 's']['total']
|
count += len(result[first_type]['items'])
|
||||||
if total and len(results[type + 's']['items']) >= total:
|
if total and count >= total:
|
||||||
# splice 'items' to only include number of results requested
|
break
|
||||||
results[type + 's']['items'] = results[type + 's']['items'][:total]
|
if total and limit > total - count:
|
||||||
return results
|
# when approaching `total` results, adjust `limit` to not request more
|
||||||
|
# items than needed
|
||||||
|
limit = total - count
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|||||||
@ -176,38 +176,48 @@ class AuthTestSpotipy(unittest.TestCase):
|
|||||||
self.assertTrue(results['artists']['items'][0]['name'] == 'Weezer')
|
self.assertTrue(results['artists']['items'][0]['name'] == 'Weezer')
|
||||||
|
|
||||||
def test_artist_search_with_multiple_markets(self):
|
def test_artist_search_with_multiple_markets(self):
|
||||||
TOTAL = 3
|
total = 5
|
||||||
results_single = self.spotify.search(q='weezer', type='artist', market='US')
|
countries_list = ['GB', 'US', 'AU']
|
||||||
results_multiple = self.spotify.search(q='weezer', type='artist',
|
countries_tuple = ('GB', 'US', 'AU')
|
||||||
market=['GB', 'US', 'AU'])
|
|
||||||
results_all = self.spotify.search(q='weezer', type='artist', market="ALL")
|
|
||||||
results_limited = self.spotify.search(q='weezer', type='artist',
|
|
||||||
market=['GB', 'US', 'AU'], total=TOTAL)
|
|
||||||
|
|
||||||
results_tuple = self.spotify.search(q='weezer', type='artist',
|
results_multiple = self.spotify.search_markets(q='weezer', type='artist',
|
||||||
market=('GB', 'US', 'AU'), total=TOTAL)
|
markets=countries_list)
|
||||||
|
results_all = self.spotify.search_markets(q='weezer', type='artist')
|
||||||
|
results_tuple = self.spotify.search_markets(q='weezer', type='artist',
|
||||||
|
markets=countries_tuple)
|
||||||
|
results_limited = self.spotify.search_markets(q='weezer', limit=3, type='artist',
|
||||||
|
markets=countries_list, total=total)
|
||||||
|
|
||||||
self.assertTrue('artists' in results_multiple)
|
self.assertTrue(
|
||||||
self.assertTrue('artists' in results_all)
|
all('artists' in results_multiple[country] for country in results_multiple))
|
||||||
self.assertTrue('artists' in results_limited)
|
self.assertTrue(all('artists' in results_all[country] for country in results_all))
|
||||||
self.assertTrue('artists' in results_tuple)
|
self.assertTrue(all('artists' in results_tuple[country] for country in results_tuple))
|
||||||
|
self.assertTrue(all('artists' in results_limited[country] for country in results_limited))
|
||||||
|
|
||||||
self.assertTrue(len(results_multiple['artists']['items']) > 0)
|
self.assertTrue(
|
||||||
self.assertTrue(len(results_all['artists']['items']) > 0)
|
all(len(results_multiple[country]['artists']['items']) > 0 for country in
|
||||||
self.assertTrue(len(results_limited['artists']['items']) > 0)
|
results_multiple))
|
||||||
self.assertTrue(len(results_tuple['artists']['items']) > 0)
|
self.assertTrue(all(len(results_all[country]['artists']
|
||||||
|
['items']) > 0 for country in results_all))
|
||||||
|
self.assertTrue(
|
||||||
|
all(len(results_tuple[country]['artists']['items']) > 0 for country in results_tuple))
|
||||||
|
self.assertTrue(
|
||||||
|
all(len(results_limited[country]['artists']['items']) > 0 for country in
|
||||||
|
results_limited))
|
||||||
|
|
||||||
self.assertTrue(len(results_all['artists']['items']) >
|
self.assertTrue(all(results_multiple[country]['artists']['items']
|
||||||
len(results_multiple['artists']['items']))
|
[0]['name'] == 'Weezer' for country in results_multiple))
|
||||||
self.assertTrue(len(results_multiple['artists']['items'])
|
self.assertTrue(all(results_all[country]['artists']['items']
|
||||||
> len(results_single['artists']['items']))
|
[0]['name'] == 'Weezer' for country in results_all))
|
||||||
|
self.assertTrue(all(results_tuple[country]['artists']['items']
|
||||||
|
[0]['name'] == 'Weezer' for country in results_tuple))
|
||||||
|
self.assertTrue(all(results_limited[country]['artists']['items']
|
||||||
|
[0]['name'] == 'Weezer' for country in results_limited))
|
||||||
|
|
||||||
self.assertTrue(results_multiple['artists']['items'][0]['name'] == 'Weezer')
|
total_limited_results = 0
|
||||||
self.assertTrue(results_all['artists']['items'][0]['name'] == 'Weezer')
|
for country in results_limited:
|
||||||
self.assertTrue(results_limited['artists']['items'][0]['name'] == 'Weezer')
|
total_limited_results += len(results_limited[country]['artists']['items'])
|
||||||
self.assertTrue(results_tuple['artists']['items'][0]['name'] == 'Weezer')
|
self.assertTrue(total_limited_results <= total)
|
||||||
|
|
||||||
self.assertTrue(len(results_limited['artists']['items']) <= TOTAL)
|
|
||||||
|
|
||||||
def test_artist_albums(self):
|
def test_artist_albums(self):
|
||||||
results = self.spotify.artist_albums(self.weezer_urn)
|
results = self.spotify.artist_albums(self.weezer_urn)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user