yutipy 1.3.1__tar.gz → 1.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of yutipy might be problematic. Click here for more details.

Files changed (52) hide show
  1. {yutipy-1.3.1 → yutipy-1.3.2}/PKG-INFO +1 -1
  2. {yutipy-1.3.1 → yutipy-1.3.2}/docs/usage_examples.rst +4 -4
  3. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/deezer.py +5 -2
  4. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/itunes.py +5 -2
  5. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/kkbox.py +5 -2
  6. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/musicyt.py +5 -2
  7. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/spotify.py +6 -3
  8. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/yutipy_music.py +30 -13
  9. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy.egg-info/PKG-INFO +1 -1
  10. {yutipy-1.3.1 → yutipy-1.3.2}/.gitattributes +0 -0
  11. {yutipy-1.3.1 → yutipy-1.3.2}/.github/FUNDING.yml +0 -0
  12. {yutipy-1.3.1 → yutipy-1.3.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  13. {yutipy-1.3.1 → yutipy-1.3.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  14. {yutipy-1.3.1 → yutipy-1.3.2}/.github/workflows/pytest-unit-testing.yml +0 -0
  15. {yutipy-1.3.1 → yutipy-1.3.2}/.github/workflows/release.yml +0 -0
  16. {yutipy-1.3.1 → yutipy-1.3.2}/.gitignore +0 -0
  17. {yutipy-1.3.1 → yutipy-1.3.2}/.readthedocs.yaml +0 -0
  18. {yutipy-1.3.1 → yutipy-1.3.2}/LICENSE +0 -0
  19. {yutipy-1.3.1 → yutipy-1.3.2}/MANIFEST.in +0 -0
  20. {yutipy-1.3.1 → yutipy-1.3.2}/README.md +0 -0
  21. {yutipy-1.3.1 → yutipy-1.3.2}/docs/Makefile +0 -0
  22. {yutipy-1.3.1 → yutipy-1.3.2}/docs/_static/yutipy_header.png +0 -0
  23. {yutipy-1.3.1 → yutipy-1.3.2}/docs/_static/yutipy_logo.png +0 -0
  24. {yutipy-1.3.1 → yutipy-1.3.2}/docs/api_reference.rst +0 -0
  25. {yutipy-1.3.1 → yutipy-1.3.2}/docs/available_platforms.rst +0 -0
  26. {yutipy-1.3.1 → yutipy-1.3.2}/docs/conf.py +0 -0
  27. {yutipy-1.3.1 → yutipy-1.3.2}/docs/faq.rst +0 -0
  28. {yutipy-1.3.1 → yutipy-1.3.2}/docs/index.rst +0 -0
  29. {yutipy-1.3.1 → yutipy-1.3.2}/docs/installation.rst +0 -0
  30. {yutipy-1.3.1 → yutipy-1.3.2}/docs/make.bat +0 -0
  31. {yutipy-1.3.1 → yutipy-1.3.2}/docs/requirements.txt +0 -0
  32. {yutipy-1.3.1 → yutipy-1.3.2}/pyproject.toml +0 -0
  33. {yutipy-1.3.1 → yutipy-1.3.2}/requirements-dev.txt +0 -0
  34. {yutipy-1.3.1 → yutipy-1.3.2}/requirements.txt +0 -0
  35. {yutipy-1.3.1 → yutipy-1.3.2}/setup.cfg +0 -0
  36. {yutipy-1.3.1 → yutipy-1.3.2}/tests/__init__.py +0 -0
  37. {yutipy-1.3.1 → yutipy-1.3.2}/tests/test_deezer.py +0 -0
  38. {yutipy-1.3.1 → yutipy-1.3.2}/tests/test_itunes.py +0 -0
  39. {yutipy-1.3.1 → yutipy-1.3.2}/tests/test_kkbox.py +0 -0
  40. {yutipy-1.3.1 → yutipy-1.3.2}/tests/test_models.py +0 -0
  41. {yutipy-1.3.1 → yutipy-1.3.2}/tests/test_musicyt.py +0 -0
  42. {yutipy-1.3.1 → yutipy-1.3.2}/tests/test_spotify.py +0 -0
  43. {yutipy-1.3.1 → yutipy-1.3.2}/tests/test_utils.py +0 -0
  44. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/__init__.py +0 -0
  45. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/exceptions.py +0 -0
  46. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/models.py +0 -0
  47. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/utils/__init__.py +0 -0
  48. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy/utils/cheap_utils.py +0 -0
  49. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy.egg-info/SOURCES.txt +0 -0
  50. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy.egg-info/dependency_links.txt +0 -0
  51. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy.egg-info/requires.txt +0 -0
  52. {yutipy-1.3.1 → yutipy-1.3.2}/yutipy.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yutipy
3
- Version: 1.3.1
3
+ Version: 1.3.2
4
4
  Summary: A simple package for retrieving music information from various music platforms APIs.
5
5
  Author: Cheap Nightbot
6
6
  Author-email: Cheap Nightbot <hi@cheapnightbot.slmail.me>
@@ -5,7 +5,7 @@ Usage Examples
5
5
  Here's a quick example of how to use the **yutipy** package to search for a song:
6
6
 
7
7
  .. important::
8
- All examples here—except for the `YouTube Music`_ & `Yutipy Music`_—use the ``with`` context manager to initialize an instance of the respective class,
8
+ All examples here—except for the `YouTube Music`_—use the ``with`` context manager to initialize an instance of the respective class,
9
9
  as those classes internally use ``requests.Session()`` for making requests to APIs.
10
10
  This approach ensures that the session is automatically closed once you exit the context. Although using ``with`` is not mandatory,
11
11
  if you instantiate an object without it, you are responsible for closing the session after use by calling the ``close_session()`` method on that object.
@@ -118,6 +118,6 @@ Yutipy Music
118
118
 
119
119
  from yutipy.yutify_music import YutipyMusic
120
120
 
121
- yutipy_music = YutipyMusic()
122
- result = yutify_music.search("Artist Name", "Song Title")
123
- print(result)
121
+ with YutipyMusic() as yutipy_music:
122
+ result = yutify_music.search("Artist Name", "Song Title")
123
+ print(result)
@@ -41,7 +41,7 @@ class Deezer:
41
41
  """Checks if the session is closed."""
42
42
  return self._is_session_closed
43
43
 
44
- def search(self, artist: str, song: str) -> Optional[MusicInfo]:
44
+ def search(self, artist: str, song: str, limit: int = 10) -> Optional[MusicInfo]:
45
45
  """
46
46
  Searches for a song by artist and title.
47
47
 
@@ -51,6 +51,9 @@ class Deezer:
51
51
  The name of the artist.
52
52
  song : str
53
53
  The title of the song.
54
+ limit: int, optional
55
+ The number of items to retrieve from API.
56
+ ``limit >=1 and <= 50``. Default is ``10``.
54
57
 
55
58
  Returns
56
59
  -------
@@ -66,7 +69,7 @@ class Deezer:
66
69
 
67
70
  for search_type in search_types:
68
71
  endpoint = f"{self.api_url}/search/{search_type}"
69
- query = f'?q=artist:"{artist}" {search_type}:"{song}"&limit=10'
72
+ query = f'?q=artist:"{artist}" {search_type}:"{song}"&limit={limit}'
70
73
  query_url = endpoint + query
71
74
 
72
75
  try:
@@ -42,7 +42,7 @@ class Itunes:
42
42
  """Checks if the session is closed."""
43
43
  return self._is_session_closed
44
44
 
45
- def search(self, artist: str, song: str) -> Optional[MusicInfo]:
45
+ def search(self, artist: str, song: str, limit: int = 10) -> Optional[MusicInfo]:
46
46
  """
47
47
  Searches for a song by artist and title.
48
48
 
@@ -52,6 +52,9 @@ class Itunes:
52
52
  The name of the artist.
53
53
  song : str
54
54
  The title of the song.
55
+ limit: int, optional
56
+ The number of items to retrieve from API.
57
+ ``limit >=1 and <= 50``. Default is ``10``.
55
58
 
56
59
  Returns
57
60
  -------
@@ -66,7 +69,7 @@ class Itunes:
66
69
  entities = ["song", "album"]
67
70
  for entity in entities:
68
71
  endpoint = f"{self.api_url}/search"
69
- query = f"?term={artist} - {song}&media=music&entity={entity}&limit=10"
72
+ query = f"?term={artist} - {song}&media=music&entity={entity}&limit={limit}"
70
73
  query_url = endpoint + query
71
74
 
72
75
  try:
@@ -134,7 +134,7 @@ class KKBox:
134
134
  self.__start_time = time.time()
135
135
 
136
136
  def search(
137
- self, artist: str, song: str, territory: str = "TW"
137
+ self, artist: str, song: str, territory: str = "TW", limit: int = 10,
138
138
  ) -> Optional[MusicInfo]:
139
139
  """
140
140
  Searches for a song by artist and title.
@@ -148,6 +148,9 @@ class KKBox:
148
148
  territory : str
149
149
  Two-letter country codes from ISO 3166-1 alpha-2.
150
150
  Allowed values: ``HK``, ``JP``, ``MY``, ``SG``, ``TW``.
151
+ limit: int, optional
152
+ The number of items to retrieve from API.
153
+ ``limit >=1 and <= 50``. Default is ``10``.
151
154
 
152
155
  Returns
153
156
  -------
@@ -161,7 +164,7 @@ class KKBox:
161
164
 
162
165
  self.__refresh_token_if_expired()
163
166
 
164
- query = f"?q={artist} - {song}&type=track,album&territory={territory}&limit=10"
167
+ query = f"?q={artist} - {song}&type=track,album&territory={territory}&limit={limit}"
165
168
  query_url = f"{self.api_url}/search{query}"
166
169
 
167
170
  try:
@@ -20,7 +20,7 @@ class MusicYT:
20
20
  """Initializes the YouTube Music class and sets up the session."""
21
21
  self.ytmusic = YTMusic()
22
22
 
23
- def search(self, artist: str, song: str) -> Optional[MusicInfo]:
23
+ def search(self, artist: str, song: str, limit: int = 10) -> Optional[MusicInfo]:
24
24
  """
25
25
  Searches for a song by artist and title.
26
26
 
@@ -30,6 +30,9 @@ class MusicYT:
30
30
  The name of the artist.
31
31
  song : str
32
32
  The title of the song.
33
+ limit: int, optional
34
+ The number of items to retrieve from API.
35
+ ``limit >=1 and <= 50``. Default is ``10``.
33
36
 
34
37
  Returns
35
38
  -------
@@ -44,7 +47,7 @@ class MusicYT:
44
47
  query = f"{artist} - {song}"
45
48
 
46
49
  try:
47
- results = self.ytmusic.search(query=query)
50
+ results = self.ytmusic.search(query=query, limit=limit)
48
51
  except exceptions.YTMusicServerError as e:
49
52
  raise NetworkException(f"Network error occurred: {e}")
50
53
 
@@ -138,7 +138,7 @@ class Spotify:
138
138
  self.__header, self.__expires_in = self.__authenticate()
139
139
  self.__start_time = time.time()
140
140
 
141
- def search(self, artist: str, song: str) -> Optional[MusicInfo]:
141
+ def search(self, artist: str, song: str, limit: int = 10) -> Optional[MusicInfo]:
142
142
  """
143
143
  Searches for a song by artist and title.
144
144
 
@@ -148,6 +148,9 @@ class Spotify:
148
148
  The name of the artist.
149
149
  song : str
150
150
  The title of the song.
151
+ limit: int, optional
152
+ The number of items to retrieve from API.
153
+ ``limit >=1 and <= 50``. Default is ``10``.
151
154
 
152
155
  Returns
153
156
  -------
@@ -161,8 +164,8 @@ class Spotify:
161
164
 
162
165
  music_info = None
163
166
  queries = [
164
- f"?q=artist:{artist} track:{song}&type=track&limit=10",
165
- f"?q=artist:{artist} album:{song}&type=album&limit=10",
167
+ f"?q=artist:{artist} track:{song}&type=track&limit={limit}",
168
+ f"?q=artist:{artist} album:{song}&type=album&limit={limit}",
166
169
  ]
167
170
 
168
171
  for query in queries:
@@ -22,9 +22,22 @@ class YutipyMusic:
22
22
  def __init__(self) -> None:
23
23
  """Initializes the YutipyMusic class."""
24
24
  self.music_info = MusicInfos()
25
- self.album_art_priority = ["deezer", "kkbox", "spotify", "musicyt", "itunes"]
26
-
27
- def search(self, artist: str, song: str) -> Optional[MusicInfos]:
25
+ self.album_art_priority = ["deezer", "kkbox", "spotify", "ytmusic", "itunes"]
26
+ self.services = {
27
+ "deezer": Deezer(),
28
+ "itunes": Itunes(),
29
+ "kkbox": KKBox(),
30
+ "ytmusic": MusicYT(),
31
+ "spotify": Spotify(),
32
+ }
33
+
34
+ def __enter__(self) -> "YutipyMusic":
35
+ return self
36
+
37
+ def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
38
+ self.close_sessions()
39
+
40
+ def search(self, artist: str, song: str, limit: int = 5) -> Optional[MusicInfos]:
28
41
  """
29
42
  Searches for a song by artist and title.
30
43
 
@@ -34,6 +47,9 @@ class YutipyMusic:
34
47
  The name of the artist.
35
48
  song : str
36
49
  The title of the song.
50
+ limit: int, optional
51
+ The number of items to retrieve from all APIs.
52
+ ``limit >=1 and <= 50``. Default is ``5``.
37
53
 
38
54
  Returns
39
55
  -------
@@ -45,18 +61,12 @@ class YutipyMusic:
45
61
  "Artist and song names must be valid strings and can't be empty."
46
62
  )
47
63
 
48
- services = [
49
- (Deezer, "deezer"),
50
- (Itunes, "itunes"),
51
- (KKBox, "kkbox"),
52
- (MusicYT, "musicyt"),
53
- (Spotify, "spotify"),
54
- ]
55
-
56
64
  with ThreadPoolExecutor() as executor:
57
65
  futures = {
58
- executor.submit(service().search, artist, song): name
59
- for service, name in services
66
+ executor.submit(
67
+ service.search, artist=artist, song=song, limit=limit
68
+ ): name
69
+ for name, service in self.services.items()
60
70
  }
61
71
 
62
72
  for future in as_completed(futures):
@@ -117,9 +127,16 @@ class YutipyMusic:
117
127
  self.music_info.id[service_name] = result.id
118
128
  self.music_info.url[service_name] = result.url
119
129
 
130
+ def close_sessions(self) -> None:
131
+ """Closes the sessions for all services."""
132
+ for service in self.services.values():
133
+ if hasattr(service, "close_session"):
134
+ service.close_session()
135
+
120
136
 
121
137
  if __name__ == "__main__":
122
138
  yutipy_music = YutipyMusic()
123
139
  artist_name = input("Artist Name: ")
124
140
  song_name = input("Song Name: ")
125
141
  pprint(yutipy_music.search(artist_name, song_name))
142
+ yutipy_music.close_sessions()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yutipy
3
- Version: 1.3.1
3
+ Version: 1.3.2
4
4
  Summary: A simple package for retrieving music information from various music platforms APIs.
5
5
  Author: Cheap Nightbot
6
6
  Author-email: Cheap Nightbot <hi@cheapnightbot.slmail.me>
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes