commit 600f02e3c109462ae6655fe0344dcb0541c3f21a
parent 070a73a9c03f377a248c60afcd7a8ee7123924f0
Author: ashermorgan <59518073+ashermorgan@users.noreply.github.com>
Date: Mon, 19 Feb 2024 17:45:00 -0800
Implement get_song_data function
Diffstat:
4 files changed, 114 insertions(+), 0 deletions(-)
diff --git a/requirements.txt b/requirements.txt
@@ -0,0 +1,2 @@
+python-dotenv
+requests
diff --git a/songs2slides/utils.py b/songs2slides/utils.py
@@ -0,0 +1,52 @@
+from dotenv import load_dotenv
+
+import os
+import requests
+
+class SongData:
+ """
+ Represents data about a song
+
+ Attributes:
+ -----------
+ title : str
+ The title of the song
+ artist : str
+ The artist of the song
+ lyrics : str
+ The song's lyrics, with double newlines separating stanzas
+ """
+
+ def __init__(self, title: str, artist: str, lyrics: str):
+ self.title = title
+ self.artist = artist
+ self.lyrics = lyrics
+
+def get_song_data(title: str, artist:str):
+ """
+ Get song data from an external API
+
+ Parameters:
+ -----------
+ title : str
+ The title of the song
+ artist : str
+ The artist of the song
+
+ Returns
+ -------
+ SongData
+ The song data
+ """
+
+ url = os.getenv('API_URL')
+ if url is None:
+ raise Exception()
+ url = url.replace('{title}', title, 1)
+ url = url.replace('{artist}', artist, 1)
+ data = requests.get(url).json()
+
+ if 'lyrics' in data.keys():
+ return SongData(data['title'], data['artist'], data['lyrics'])
+ else:
+ raise Exception()
diff --git a/requirements.txt b/tests/__init__.py
diff --git a/tests/test_core.py b/tests/test_core.py
@@ -0,0 +1,60 @@
+import unittest
+from unittest.mock import patch
+
+from songs2slides import utils
+
+class TestUtils(unittest.TestCase):
+ def test_get_song_data_success(self):
+ with patch('songs2slides.utils.os.getenv') as mocked_env, \
+ patch('songs2slides.utils.requests.get') as mocked_get:
+
+ # Mock os.getenv and requests.get
+ mocked_env.return_value = 'api://lyrics/{artist}/{title}'
+ mocked_get.return_value.text = b'{"lyrics":"Test1\nTest2\nTest3\nTest4","title":"Foo","artist":"Bar","image":null}'
+ mocked_get.return_value.json.return_value = {
+ 'lyrics': 'Test1\nTest2\nTest3\nTest4',
+ 'title': 'Foo',
+ 'artist': 'Bar',
+ }
+ mocked_get.return_value.status_code = 200
+
+ # Get song data
+ song_data = utils.get_song_data('foo', 'bar')
+
+ # Assert song data is correct
+ mocked_get.assert_called_with('api://lyrics/bar/foo')
+ self.assertEqual(song_data.title, 'Foo')
+ self.assertEqual(song_data.artist, 'Bar')
+ self.assertEqual(song_data.lyrics, 'Test1\nTest2\nTest3\nTest4')
+
+ def test_get_song_data_no_url(self):
+ with patch('songs2slides.utils.os.getenv') as mocked_env, \
+ patch('songs2slides.utils.requests.get') as mocked_get:
+
+ # Mock os.getenv and requests.get
+ mocked_env.return_value = None
+ mocked_get.return_value.text = b'{}'
+ mocked_get.return_value.status_code = 200
+
+ # Try to get song data
+ with self.assertRaises(Exception):
+ song_data = utils.get_song_data('foo', 'bar')
+
+ # Assert request was not called
+ mocked_get.assert_not_called()
+
+ def test_get_song_data_not_found(self):
+ with patch('songs2slides.utils.os.getenv') as mocked_env, \
+ patch('songs2slides.utils.requests.get') as mocked_get:
+
+ # Mock os.getenv and requests.get
+ mocked_env.return_value = 'api://lyrics/{artist}/{title}'
+ mocked_get.return_value.text = b'{}'
+ mocked_get.return_value.status_code = 200
+
+ # Try to get song data
+ with self.assertRaises(Exception):
+ song_data = utils.get_song_data('foo', 'bar')
+
+ # Assert request was called
+ mocked_get.assert_called_with('api://lyrics/bar/foo')