Skip to content

Commit

Permalink
Add recordings recommendation (#4)
Browse files Browse the repository at this point in the history
* Add function and test to fetch recommended recordings

* Send params correctly

* Add support for similar artist_type and more tests.
  • Loading branch information
mayhem authored Jul 23, 2020
1 parent 001d22c commit 6a0c546
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
37 changes: 37 additions & 0 deletions pylistenbrainz/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,3 +362,40 @@ def get_user_releases(self, username, count=25, offset=0, time_range='all_time')
:rtype: dict
"""
return self._get_user_entity(username, 'releases', count, offset, time_range)


def get_user_recommendation_recordings(self, username, artist_type='top', count=25, offset=0):
""" Get recommended recordings for a user.
:param username: the username of the user whose recommended tracks are to be fetched.
:type username: str
:param artist_type: The type of filtering applied to the recommended tracks.
'top' for filtering by top artists or
'similar' for filtering by similar artists
:type artist_type: str
:param count: the number of recordings to fetch, defaults to 25, maximum is 100.
:type count: int, optional
:param offset: the number of releases to skip from the beginning, for pagination, defaults to 0.
:type offset: int, optional
:return: the recommended recordings as other data returned by the API
:rtype: dict
"""

if artist_type not in ('top', 'similar'):
raise ValueError("artist_type must be either top or similar.")
params = {
'artist_type': artist_type,
'count': count,
'offset': offset
}
try:
return self._get('/1/cf/recommendation/user/{}/recording'.format(username), params=params)
except errors.ListenBrainzAPIException as e:
if e.status_code == 204:
return None
else:
raise
33 changes: 33 additions & 0 deletions pylistenbrainz/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,36 @@ def test_get_api_exceptions(self, mock_requests_get):
# assert that getting listens raises a ListenBrainzAPIException
with self.assertRaises(errors.ListenBrainzAPIException):
self.client.get_listens('iliekcomputers')


@mock.patch('pylistenbrainz.client.requests.get')
def test_get_user_recommendation_recordings(self, mock_requests_get):
mock_requests_get.return_value = mock.MagicMock()
with self.assertRaises(ValueError):
self.client.get_user_recommendation_recordings("boo", "bad artist type")

mock_requests_get.reset_mock()
mock_requests_get.return_value = mock.MagicMock()
self.client.get_user_recommendation_recordings("iliekcomputers", "top", offset=3, count=2)
mock_requests_get.assert_called_once_with(
'https://api.listenbrainz.org/1/cf/recommendation/user/iliekcomputers/recording',
params={
'artist_type': 'top',
'count': 2,
'offset': 3
},
headers={},
)

mock_requests_get.reset_mock()
mock_requests_get.return_value = mock.MagicMock()
self.client.get_user_recommendation_recordings("iliekcomputers", "similar", offset=3, count=2)
mock_requests_get.assert_called_once_with(
'https://api.listenbrainz.org/1/cf/recommendation/user/iliekcomputers/recording',
params={
'artist_type': 'similar',
'count': 2,
'offset': 3
},
headers={},
)

0 comments on commit 6a0c546

Please sign in to comment.