Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactor method track_search #35

Merged
merged 2 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pymusixmatch/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,8 @@ class Country(Enum):
class Format(Enum):
JSON = "json"
XML = "xml"


class Ordering(Enum):
ASC = "asc"
DESC = "desc"
105 changes: 65 additions & 40 deletions pymusixmatch/musixmatch.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Optional
import requests

from pymusixmatch.enums import Country, Format, Route
from pymusixmatch.enums import Country, Format, Ordering, Route


class Musixmatch(object):
Expand Down Expand Up @@ -103,7 +103,7 @@ def chart_tracks_get(
f_has_lyrics: bool,
country: Optional[Country] = Country.US.value,
_format: Optional[Format] = Format.JSON.value,
):
) -> dict:
"""This api provides you the list
of the top songs of a given country.

Expand Down Expand Up @@ -132,54 +132,79 @@ def chart_tracks_get(

def track_search(
self,
q_track,
q_artist,
page_size,
page,
s_track_rating,
_format="json",
):
page: int,
page_size: int,
q_track: Optional[str] = "",
q_artist: Optional[str] = "",
q_lyrics: Optional[str] = "",
q_track_artist: Optional[str] = "",
q_writer: Optional[str] = "",
q: Optional[str] = "",
f_artist_id: Optional[int] = "",
f_music_genre_id: Optional[int] = "",
f_lyrics_language: Optional[str] = "",
f_has_lyrics: Optional[bool] = "",
f_track_release_group_first_release_date_min: Optional[str] = "",
f_track_release_group_first_release_date_max: Optional[str] = "",
s_artist_rating: Optional[Ordering] = Ordering.DESC.value,
s_track_rating: Optional[Ordering] = Ordering.DESC.value,
quorum_factor: Optional[float] = "",
) -> dict:
"""Search for track in our database.

Parameters:

q_track - The song title.
q_artist - The song artist.
q_lyrics - Any word in the lyrics.
f_artist_id - When set, filter by this artist id.
f_music_genre_id - When set, filter by this music category id.
f_lyrics_language - Filter by the lyrics language (en,it,..).
f_has_lyrics - When set, filter only contents with lyrics.
f_track_release_group_first_release_date_min - When set, filter
the tracks with release date newer than value, format is YYYYMMDD.
f_track_release_group_first_release_date_max - When set, filter
the tracks with release date older than value, format is YYYYMMDD.
s_artist_rating - Sort by our popularity index for artists (asc|desc).
s_track_rating - Sort by our popularity index for tracks (asc|desc).
quorum_factor - Search only a part of the given query string.
Allowed range is (0.1 – 0.9).
page - Define the page number for paginated results.
page_size - Define the page size for paginated results.
Range is 1 to 100.
callback - jsonp callback.
format - Decide the output type json or xml (default json).
q_track (str): The song title
q_artist (str): The song artist
q_lyrics (str): Any word in the lyrics
q_track_artist (str): Any word in the song title or artist name
q_writer (str): Search among writers
q (str): Any word in the song title or artist name or lyrics
f_artist_id (int): When set, filter by this artist id
f_music_genre_id (int): When set, filter by this music category id
f_lyrics_language (str): Filter by the lyrics language (en,it,..)
f_has_lyrics (bool): When set, filter only contents with lyrics
f_track_release_group_first_release_date_min (str): When set, filter the tracks with release date newer than value, format is YYYYMMDD
f_track_release_group_first_release_date_max (str): When set, filter the tracks with release date older than value, format is YYYYMMDD
s_artist_rating (Ordering): Sort by our popularity index for artists (asc|desc)
s_track_rating (Ordering): Sort by our popularity index for tracks (asc|desc)
quorum_factor (float): Search only a part of the given query string.Allowed range is (0.1 – 0.9)
page (int): Define the page number for paginated results
page_size (int): Define the page size for paginated results. Range is 1 to 100.

Note: This method requires a commercial plan.
"""

if s_artist_rating not in Ordering._value2member_map_:
raise ValueError(
f"Invalid artist rating: {s_artist_rating}, please use a valid artist rating."
)

if s_track_rating not in Ordering._value2member_map_:
raise ValueError(
f"Invalid track rating: {s_track_rating}, please use a valid track rating."
)

data = self._request(
self._get_url(
"track.search?"
"q_track={}&q_artist={}"
"&page_size={}"
"&page={}"
"&s_track_rating={}&format={}".format(
q_track,
q_artist,
self._set_page_size(page_size),
page,
s_track_rating,
_format,
),
f"q_track={q_track}&"
f"q_artist={q_artist}&"
f"q_lyrics={q_lyrics}&"
f"q_track_artist={q_track_artist}&"
f"q_writer={q_writer}&"
f"q={q}&"
f"f_artist_id={f_artist_id}&"
f"f_music_genre_id={f_music_genre_id}&"
f"f_lyrics_language={f_lyrics_language}&"
f"f_has_lyrics={f_has_lyrics}&"
f"f_track_release_group_first_release_date_min={f_track_release_group_first_release_date_min}&"
f"f_track_release_group_first_release_date_max={f_track_release_group_first_release_date_max}&"
f"s_artist_rating={s_artist_rating}&"
f"s_track_rating={s_track_rating}&"
f"quorum_factor={quorum_factor}&"
f"page={page}&"
f"page_size={self._set_page_size(page_size)}"
),
)
return data
Expand Down
16 changes: 16 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,19 @@ def track_snippet() -> dict:
},
}
}


@pytest.fixture
def track_search() -> dict:
return {
"message": {
"header": {"status_code": 200, "execute_time": 0.00136, "available": 646},
"body": {
"track_list": [
{"track": "track'"},
{"track": "track'"},
{"track": "track'"},
]
},
}
}
63 changes: 54 additions & 9 deletions tests/test_musixmatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ def test_set_page_size_with_invalid_page_size(
def test_chart_artists(self, requests_mock, chart_artists: dict) -> None:
url = "https://api.musixmatch.com/ws/1.1/chart.artists.get?page=1&page_size=1&country=us&format=json"
requests_mock.get(url=url, json=chart_artists)
request = self.musixmatch.chart_artists(1, 1)
assert chart_artists == request
assert chart_artists == self.musixmatch.chart_artists(1, 1)

def test_chart_artists_with_invalid_country(
self, requests_mock, chart_artists: dict
Expand All @@ -62,8 +61,7 @@ def test_chart_artists_with_invalid_format(
def test_chart_tracks_get(self, requests_mock, tracks: dict) -> None:
url = "https://api.musixmatch.com/ws/1.1/chart.tracks.get?page=1&page_size=1&country=us&format=json&f_has_lyrics=1"
requests_mock.get(url=url, json=tracks)
request = self.musixmatch.chart_tracks_get(1, 1, 1)
assert tracks == request
assert tracks == self.musixmatch.chart_tracks_get(1, 1, 1)

def test_chart_tracks_get_with_invalid_country(
self, requests_mock, tracks: dict
Expand All @@ -81,19 +79,66 @@ def test_chart_tracks_get_with_invalid_format(
with pytest.raises(ValueError):
self.musixmatch.chart_tracks_get(1, 1, 1, _format="invalid")

@pytest.mark.skip("Refactor test")
def test_track_search(self):
self.assertEqual(
def test_track_search(self, requests_mock, track_search: dict) -> None:
url = "https://api.musixmatch.com/ws/1.1/track.search?q_track=Let%20Me%20Love%20You&q_artist=justinbieber&q_lyrics=&q_track_artist=&q_writer=&q=&f_artist_id=&f_music_genre_id=&f_lyrics_language=&f_has_lyrics=&f_track_release_group_first_release_date_min=&f_track_release_group_first_release_date_max=&s_artist_rating=desc&s_track_rating=desc&quorum_factor=&page=1&page_size=10&apikey=test"
requests_mock.get(url=url, json=track_search)

assert (
self.musixmatch.track_search(
q_track="Let Me Love You",
q_artist="justinbieber",
page_size=10,
page=1,
s_track_rating="desc",
)["message"]["body"]["track_list"],
[],
)
== track_search
)

def test_track_search_with_invalid_page_size(
self, requests_mock, track_search: dict
) -> None:
url = "https://api.musixmatch.com/ws/1.1/track.search?q_track=Let%20Me%20Love%20You&q_artist=justinbieber&q_lyrics=&q_track_artist=&q_writer=&q=&f_artist_id=&f_music_genre_id=&f_lyrics_language=&f_has_lyrics=&f_track_release_group_first_release_date_min=&f_track_release_group_first_release_date_max=&s_artist_rating=desc&s_track_rating=desc&quorum_factor=&page=1&page_size=101&apikey=test"
requests_mock.get(url=url, json=track_search)

with pytest.raises(ValueError):
self.musixmatch.track_search(
q_track="Let Me Love You",
q_artist="justinbieber",
page_size=101,
page=1,
s_track_rating="desc",
)

def test_track_search_with_invalid_s_artist_rating(
self, requests_mock, track_search: dict
) -> None:
url = "https://api.musixmatch.com/ws/1.1/track.search?q_track=Let%20Me%20Love%20You&q_artist=justinbieber&q_lyrics=&q_track_artist=&q_writer=&q=&f_artist_id=&f_music_genre_id=&f_lyrics_language=&f_has_lyrics=&f_track_release_group_first_release_date_min=&f_track_release_group_first_release_date_max=&s_artist_rating=invalid&s_track_rating=desc&quorum_factor=&page=1&page_size=10&apikey=test"
requests_mock.get(url=url, json=track_search)

with pytest.raises(ValueError):
self.musixmatch.track_search(
q_track="Let Me Love You",
q_artist="justinbieber",
page_size=10,
page=1,
s_artist_rating="invalid",
)

def test_track_search_with_invalid_s_track_rating(
self, requests_mock, track_search: dict
) -> None:
url = "https://api.musixmatch.com/ws/1.1/track.search?q_track=Let%20Me%20Love%20You&q_artist=justinbieber&q_lyrics=&q_track_artist=&q_writer=&q=&f_artist_id=&f_music_genre_id=&f_lyrics_language=&f_has_lyrics=&f_track_release_group_first_release_date_min=&f_track_release_group_first_release_date_max=&s_artist_rating=desc&s_track_rating=invalid&quorum_factor=&page=1&page_size=10&apikey=test"
requests_mock.get(url=url, json=track_search)

with pytest.raises(ValueError):
self.musixmatch.track_search(
q_track="Let Me Love You",
q_artist="justinbieber",
page_size=10,
page=1,
s_track_rating="invalid",
)

@pytest.mark.skip("Refactor test")
def test_track_get(self):
self.assertEqual(
Expand Down
Loading