Skip to content

Commit be387a0

Browse files
authored
feat: add primary_artists, writer_artists, producer_artists to Song (#304) (#334)
Resolves #304
1 parent 3538bb1 commit be387a0

6 files changed

Lines changed: 121 additions & 3 deletions

File tree

lyricsgenius/types/song.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ def __init__(self, lyrics: str, body: dict[str, Any]) -> None:
4545
self.title_with_featured: str | None = body.get("title_with_featured")
4646
self.url: str | None = body.get("url")
4747
self.featured_artists: list[dict[str, Any]] = body.get("featured_artists", [])
48+
self.primary_artists: list[dict[str, Any]] = body.get("primary_artists", [])
49+
self.writer_artists: list[dict[str, Any]] = body.get("writer_artists", [])
50+
self.producer_artists: list[dict[str, Any]] = body.get("producer_artists", [])
4851

4952
@property
5053
def _text_data(self) -> str:

main.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import lyricsgenius
2+
3+
genius = lyricsgenius.Genius()
4+
5+
song = genius.search_song("Dr Hansjakobli und ds Babettli", "Mani Matter")
6+
7+
song = genius.search_song("Dr Hansjakobli u ds Babettli", "Mani Matter")
8+
9+
10+
if song is not None:
11+
print(song.lyrics)
12+
song.save_lyrics("/Users/john/Downloads/song.txt", extension="txt", overwrite=True)
13+
14+
song = genius.search_song("dua lipa", "new rules", False, False)
15+
if song is not None:
16+
print(song.lyrics)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "lyricsgenius"
7-
version = "3.9.0"
7+
version = "3.10.0"
88
dependencies = ["beautifulsoup4>=4.12.3", "requests>=2.27.1"]
99
requires-python = ">=3.11"
1010
authors = [{ name = "John W. R. Miller", email = "john.w.millr+lg@gmail.com" }]

tests/fixtures/song_info_mocked.json

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,53 @@
156156
"unreviewed_annotations": 3,
157157
"hot": false
158158
},
159-
"featured_artists": []
159+
"featured_artists": [
160+
{
161+
"id": 555555,
162+
"name": "Mock Feature",
163+
"api_path": "/artists/555555",
164+
"header_image_url": "https://images.genius.com/mockfeature.jpg",
165+
"image_url": "https://images.genius.com/mockfeature.jpg",
166+
"is_meme_verified": false,
167+
"is_verified": false,
168+
"url": "https://genius.com/artists/Mock-feature"
169+
}
170+
],
171+
"primary_artists": [
172+
{
173+
"id": 424242,
174+
"name": "Py Testerson",
175+
"api_path": "/artists/424242",
176+
"header_image_url": "https://images.genius.com/fakepythonartist.jpg",
177+
"image_url": "https://images.genius.com/fakepythonartist.jpg",
178+
"is_meme_verified": true,
179+
"is_verified": false,
180+
"url": "https://genius.com/artists/Py-testerson"
181+
}
182+
],
183+
"writer_artists": [
184+
{
185+
"id": 666666,
186+
"name": "Test Writer",
187+
"api_path": "/artists/666666",
188+
"header_image_url": "https://images.genius.com/testwriter.jpg",
189+
"image_url": "https://images.genius.com/testwriter.jpg",
190+
"is_meme_verified": false,
191+
"is_verified": false,
192+
"url": "https://genius.com/artists/Test-writer"
193+
}
194+
],
195+
"producer_artists": [
196+
{
197+
"id": 777777,
198+
"name": "Test Producer",
199+
"api_path": "/artists/777777",
200+
"header_image_url": "https://images.genius.com/testproducer.jpg",
201+
"image_url": "https://images.genius.com/testproducer.jpg",
202+
"is_meme_verified": false,
203+
"is_verified": false,
204+
"url": "https://genius.com/artists/Test-producer"
205+
}
206+
]
160207
}
161208
]

tests/test_song.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,58 @@ def test_song_artist(song_object: Song, mock_song_data: dict[str, Any]) -> None:
8181
assert song_object.artist == mock_song_data["primary_artist"]["name"]
8282

8383

84+
def test_song_primary_artists(
85+
song_object: Song, mock_song_data: dict[str, Any]
86+
) -> None:
87+
"""Test if primary_artists is populated correctly."""
88+
assert song_object.primary_artists == mock_song_data["primary_artists"]
89+
assert song_object.primary_artists[0]["name"] == "Py Testerson"
90+
91+
92+
def test_song_writer_artists(song_object: Song, mock_song_data: dict[str, Any]) -> None:
93+
"""Test if writer_artists is populated correctly."""
94+
assert song_object.writer_artists == mock_song_data["writer_artists"]
95+
assert song_object.writer_artists[0]["name"] == "Test Writer"
96+
97+
98+
def test_song_producer_artists(
99+
song_object: Song, mock_song_data: dict[str, Any]
100+
) -> None:
101+
"""Test if producer_artists is populated correctly."""
102+
assert song_object.producer_artists == mock_song_data["producer_artists"]
103+
assert song_object.producer_artists[0]["name"] == "Test Producer"
104+
105+
106+
def test_song_featured_artists(
107+
song_object: Song, mock_song_data: dict[str, Any]
108+
) -> None:
109+
"""Test if featured_artists is populated correctly."""
110+
assert song_object.featured_artists == mock_song_data["featured_artists"]
111+
assert song_object.featured_artists[0]["name"] == "Mock Feature"
112+
113+
114+
def test_song_artist_fields_default_empty(
115+
mock_song_data: dict[str, Any], mock_lyrics: str
116+
) -> None:
117+
"""Test that artist list fields default to empty lists when absent from body."""
118+
body = {
119+
k: v
120+
for k, v in mock_song_data.items()
121+
if k
122+
not in (
123+
"primary_artists",
124+
"writer_artists",
125+
"producer_artists",
126+
"featured_artists",
127+
)
128+
}
129+
song = Song(mock_lyrics, body)
130+
assert song.primary_artists == []
131+
assert song.writer_artists == []
132+
assert song.producer_artists == []
133+
assert song.featured_artists == []
134+
135+
84136
def test_to_dict(
85137
song_object: Song, mock_song_data: dict[str, Any], mock_lyrics: str
86138
) -> None:

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)