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:
Nathan LeRoyandStephane Bruckert authored and GitHub committed 2020-07-07 07:20:23 +01:00
1 parent 7eb0eaaebc
commit f7fb8757e9
2 files changed
+90 -67

No files matched your search

+53 -40
View File
@@ -508,40 +508,49 @@ class Spotify(object):
tlist = [self._get_id("episode", e) for e in episodes]
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
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:
- 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). 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).
- 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. Can supply list of markets. Pass "ALL" to search all country codes.
- type - the type's of item's to return. One or more of 'artist', 'album',
'track', 'playlist', 'show', or 'episode'. If multiple types are desired, pass in a comma separated list.
- markets - A list of ISO 3166-1 alpha-2 country codes. Search all country markets by default.
- 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"):
warnings.warn(
"Searching all markets is poorly performing.",
UserWarning,
)
return self._search_multiple_markets(q, limit, offset, type, self.country_codes, total)
if not (isinstance(markets, list) or isinstance(markets, tuple)):
markets = []
elif isinstance(market, list) or isinstance(market, tuple):
warnings.warn(
"Searching multiple markets is poorly performing.",
UserWarning,
)
return self._search_multiple_markets(q, limit, offset, type, market, total)
else:
return self._get(
"search", q=q, limit=limit, offset=offset, type=type, market=market
)
warnings.warn(
"Searching multiple markets is poorly performing.",
UserWarning,
)
return self._search_multiple_markets(q, limit, offset, type, markets, total)
def user(self, user):
""" Gets basic profile information about a Spotify User
@@ -1562,26 +1571,30 @@ class Spotify(object):
return "spotify:" + type + ":" + self._get_id(type, id)
def _search_multiple_markets(self, q, limit, offset, type, markets, total):
results = {
type + 's': {
'href': [],
'items': [],
'limit': limit,
'next': None,
'offset': 0,
'previous': None,
'total': 0
}
}
if total and limit > total:
limit = total
warnings.warn(
"limit was auto-adjusted to equal {} as it must not be higher than total".format(
total),
UserWarning,
)
results = {}
first_type = type.split(",")[0] + 's'
count = 0
for country in markets:
result = self._get(
"search", q=q, limit=limit, offset=offset, type=type, market=country
)
results[type + 's']['href'].append(result[type + 's']['href'])
results[type + 's']['items'] += result[type + 's']['items']
results[type + 's']['total'] += result[type + 's']['total']
if total and len(results[type + 's']['items']) >= total:
# splice 'items' to only include number of results requested
results[type + 's']['items'] = results[type + 's']['items'][:total]
return results
results[country] = result
count += len(result[first_type]['items'])
if total and count >= total:
break
if total and limit > total - count:
# when approaching `total` results, adjust `limit` to not request more
# items than needed
limit = total - count
return results