yutipy 0.1.1__py3-none-any.whl → 1.0.0__py3-none-any.whl
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.
- yutipy/models.py +55 -55
- yutipy/spotify.py +24 -23
- {yutipy-0.1.1.dist-info → yutipy-1.0.0.dist-info}/LICENSE +21 -21
- {yutipy-0.1.1.dist-info → yutipy-1.0.0.dist-info}/METADATA +140 -140
- yutipy-1.0.0.dist-info/RECORD +14 -0
- {yutipy-0.1.1.dist-info → yutipy-1.0.0.dist-info}/WHEEL +1 -1
- yutipy/__pycache__/__init__.cpython-312.pyc +0 -0
- yutipy/__pycache__/deezer.cpython-312.pyc +0 -0
- yutipy/__pycache__/exceptions.cpython-312.pyc +0 -0
- yutipy/__pycache__/itunes.cpython-312.pyc +0 -0
- yutipy/__pycache__/models.cpython-312.pyc +0 -0
- yutipy/__pycache__/musicyt.cpython-312.pyc +0 -0
- yutipy/__pycache__/spotify.cpython-312.pyc +0 -0
- yutipy/utils/__pycache__/__init__.cpython-312.pyc +0 -0
- yutipy/utils/__pycache__/cheap_utils.cpython-312.pyc +0 -0
- yutipy-0.1.1.dist-info/RECORD +0 -23
- {yutipy-0.1.1.dist-info → yutipy-1.0.0.dist-info}/top_level.txt +0 -0
yutipy/models.py
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@dataclass
|
|
6
|
-
class MusicInfo:
|
|
7
|
-
"""
|
|
8
|
-
A data class to store music information.
|
|
9
|
-
|
|
10
|
-
Attributes
|
|
11
|
-
----------
|
|
12
|
-
album_art : Optional[str]
|
|
13
|
-
URL to the album art.
|
|
14
|
-
album_title : Optional[str]
|
|
15
|
-
Title of the album.
|
|
16
|
-
album_type : Optional[str]
|
|
17
|
-
Type of the album (e.g., album, single).
|
|
18
|
-
artists : str
|
|
19
|
-
Name(s) of the artist(s).
|
|
20
|
-
genre : Optional[str]
|
|
21
|
-
Genre of the music.
|
|
22
|
-
id : str
|
|
23
|
-
Unique identifier for the music.
|
|
24
|
-
isrc : Optional[str]
|
|
25
|
-
International Standard Recording Code.
|
|
26
|
-
lyrics : Optional[str]
|
|
27
|
-
Lyrics of the song.
|
|
28
|
-
release_date : Optional[str]
|
|
29
|
-
Release date of the music.
|
|
30
|
-
tempo : Optional[float]
|
|
31
|
-
Tempo of the music in BPM.
|
|
32
|
-
title : str
|
|
33
|
-
Title of the music.
|
|
34
|
-
type : Optional[str]
|
|
35
|
-
Type of the music (e.g., track, album).
|
|
36
|
-
upc : Optional[str]
|
|
37
|
-
Universal Product Code.
|
|
38
|
-
url : str
|
|
39
|
-
URL to the music on the platform.
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
album_art: Optional[str]
|
|
43
|
-
album_title: Optional[str]
|
|
44
|
-
album_type: Optional[str]
|
|
45
|
-
artists: str
|
|
46
|
-
genre: Optional[str]
|
|
47
|
-
id: str
|
|
48
|
-
isrc: Optional[str]
|
|
49
|
-
lyrics: Optional[str]
|
|
50
|
-
release_date: Optional[str]
|
|
51
|
-
tempo: Optional[float]
|
|
52
|
-
title: str
|
|
53
|
-
type: Optional[str]
|
|
54
|
-
upc: Optional[str]
|
|
55
|
-
url: str
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class MusicInfo:
|
|
7
|
+
"""
|
|
8
|
+
A data class to store music information.
|
|
9
|
+
|
|
10
|
+
Attributes
|
|
11
|
+
----------
|
|
12
|
+
album_art : Optional[str]
|
|
13
|
+
URL to the album art.
|
|
14
|
+
album_title : Optional[str]
|
|
15
|
+
Title of the album.
|
|
16
|
+
album_type : Optional[str]
|
|
17
|
+
Type of the album (e.g., album, single).
|
|
18
|
+
artists : str
|
|
19
|
+
Name(s) of the artist(s).
|
|
20
|
+
genre : Optional[str]
|
|
21
|
+
Genre of the music.
|
|
22
|
+
id : str
|
|
23
|
+
Unique identifier for the music.
|
|
24
|
+
isrc : Optional[str]
|
|
25
|
+
International Standard Recording Code.
|
|
26
|
+
lyrics : Optional[str]
|
|
27
|
+
Lyrics of the song.
|
|
28
|
+
release_date : Optional[str]
|
|
29
|
+
Release date of the music.
|
|
30
|
+
tempo : Optional[float]
|
|
31
|
+
Tempo of the music in BPM.
|
|
32
|
+
title : str
|
|
33
|
+
Title of the music.
|
|
34
|
+
type : Optional[str]
|
|
35
|
+
Type of the music (e.g., track, album).
|
|
36
|
+
upc : Optional[str]
|
|
37
|
+
Universal Product Code.
|
|
38
|
+
url : str
|
|
39
|
+
URL to the music on the platform.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
album_art: Optional[str]
|
|
43
|
+
album_title: Optional[str]
|
|
44
|
+
album_type: Optional[str]
|
|
45
|
+
artists: str
|
|
46
|
+
genre: Optional[str]
|
|
47
|
+
id: str
|
|
48
|
+
isrc: Optional[str]
|
|
49
|
+
lyrics: Optional[str]
|
|
50
|
+
release_date: Optional[str]
|
|
51
|
+
tempo: Optional[float]
|
|
52
|
+
title: str
|
|
53
|
+
type: Optional[str]
|
|
54
|
+
upc: Optional[str]
|
|
55
|
+
url: str
|
yutipy/spotify.py
CHANGED
|
@@ -23,20 +23,20 @@ from yutipy.utils.cheap_utils import (
|
|
|
23
23
|
|
|
24
24
|
load_dotenv()
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
SPOTIFY_CLIENT_ID = os.getenv("SPOTIFY_CLIENT_ID")
|
|
27
|
+
SPOTIFY_CLIENT_SECRET = os.getenv("SPOTIFY_CLIENT_SECRET")
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class Spotify:
|
|
31
31
|
"""
|
|
32
32
|
A class to interact with the Spotify API.
|
|
33
33
|
|
|
34
|
-
This class reads the ``
|
|
35
|
-
Alternatively,
|
|
34
|
+
This class reads the ``SPOTIFY_CLIENT_ID`` and ``SPOTIFY_CLIENT_SECRET`` from environment variables or the ``.env`` file by default.
|
|
35
|
+
Alternatively, you can manually provide these values when creating an object.
|
|
36
36
|
"""
|
|
37
37
|
|
|
38
38
|
def __init__(
|
|
39
|
-
self, client_id: str =
|
|
39
|
+
self, client_id: str = SPOTIFY_CLIENT_ID, client_secret: str = SPOTIFY_CLIENT_SECRET
|
|
40
40
|
) -> None:
|
|
41
41
|
"""
|
|
42
42
|
Initializes the Spotify class and sets up the session.
|
|
@@ -44,20 +44,20 @@ class Spotify:
|
|
|
44
44
|
Parameters
|
|
45
45
|
----------
|
|
46
46
|
client_id : str, optional
|
|
47
|
-
The
|
|
47
|
+
The Client ID for the Spotify API. Defaults to ``SPOTIFY_CLIENT_ID`` from .env file.
|
|
48
48
|
client_secret : str, optional
|
|
49
|
-
The
|
|
49
|
+
The Client secret for the Spotify API. Defaults to ``SPOTIFY_CLIENT_SECRET`` from .env file.
|
|
50
50
|
"""
|
|
51
51
|
if not client_id or not client_secret:
|
|
52
52
|
raise SpotifyException(
|
|
53
|
-
"Failed to read
|
|
53
|
+
"Failed to read `SPOTIFY_CLIENT_ID` and `SPOTIFY_CLIENT_SECRET` from environment variables. Client ID and Client Secret must be provided."
|
|
54
54
|
)
|
|
55
55
|
|
|
56
56
|
self.client_id = client_id
|
|
57
57
|
self.client_secret = client_secret
|
|
58
58
|
self._session = requests.Session()
|
|
59
59
|
self.api_url = "https://api.spotify.com/v1"
|
|
60
|
-
self.__header = self.__authenticate()
|
|
60
|
+
self.__header, self.__expires_in = self.__authenticate()
|
|
61
61
|
self.__start_time = time.time()
|
|
62
62
|
self._is_session_closed = False
|
|
63
63
|
|
|
@@ -80,7 +80,7 @@ class Spotify:
|
|
|
80
80
|
"""Checks if the session is closed."""
|
|
81
81
|
return self._is_session_closed
|
|
82
82
|
|
|
83
|
-
def __authenticate(self) ->
|
|
83
|
+
def __authenticate(self) -> tuple:
|
|
84
84
|
"""
|
|
85
85
|
Authenticates with the Spotify API and returns the authorization header.
|
|
86
86
|
|
|
@@ -90,14 +90,14 @@ class Spotify:
|
|
|
90
90
|
The authorization header.
|
|
91
91
|
"""
|
|
92
92
|
try:
|
|
93
|
-
token = self.__get_spotify_token()
|
|
94
|
-
return {"Authorization": f"Bearer {token}"}
|
|
93
|
+
token, expires_in = self.__get_spotify_token()
|
|
94
|
+
return {"Authorization": f"Bearer {token}"}, expires_in
|
|
95
95
|
except Exception as e:
|
|
96
96
|
raise AuthenticationException(
|
|
97
97
|
"Failed to authenticate with Spotify API"
|
|
98
98
|
) from e
|
|
99
99
|
|
|
100
|
-
def __get_spotify_token(self) ->
|
|
100
|
+
def __get_spotify_token(self) -> tuple:
|
|
101
101
|
"""
|
|
102
102
|
Gets the Spotify API token.
|
|
103
103
|
|
|
@@ -125,14 +125,16 @@ class Spotify:
|
|
|
125
125
|
raise NetworkException(f"Network error occurred: {e}")
|
|
126
126
|
|
|
127
127
|
try:
|
|
128
|
-
|
|
128
|
+
response_json = response.json()
|
|
129
|
+
return response_json.get("access_token"), response_json.get("expires_in")
|
|
129
130
|
except (KeyError, ValueError) as e:
|
|
130
131
|
raise InvalidResponseException(f"Invalid response received: {e}")
|
|
131
132
|
|
|
132
133
|
def __refresh_token_if_expired(self):
|
|
133
134
|
"""Refreshes the token if it has expired."""
|
|
134
|
-
if time.time() - self.__start_time >=
|
|
135
|
-
self.__header = self.__authenticate()
|
|
135
|
+
if time.time() - self.__start_time >= self.__expires_in:
|
|
136
|
+
self.__header, self.__expires_in = self.__authenticate()
|
|
137
|
+
self.__start_time = time.time()
|
|
136
138
|
|
|
137
139
|
def search(self, artist: str, song: str) -> Optional[MusicInfo]:
|
|
138
140
|
"""
|
|
@@ -166,12 +168,11 @@ class Spotify:
|
|
|
166
168
|
except requests.RequestException as e:
|
|
167
169
|
raise NetworkException(f"Network error occurred: {e}")
|
|
168
170
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
except (KeyError, ValueError) as e:
|
|
172
|
-
raise InvalidResponseException(f"Invalid response received: {e}")
|
|
171
|
+
if response.status_code != 200:
|
|
172
|
+
raise SpotifyException(f"Failed to search for music: {response.json()}")
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
artist_ids = self._get_artists_ids(artist)
|
|
175
|
+
return self._find_music_info(artist, song, response.json(), artist_ids)
|
|
175
176
|
|
|
176
177
|
def search_advanced(
|
|
177
178
|
self, artist: str, song: str, isrc: str = None, upc: str = None
|
|
@@ -403,11 +404,11 @@ class Spotify:
|
|
|
403
404
|
|
|
404
405
|
|
|
405
406
|
if __name__ == "__main__":
|
|
406
|
-
Spotify = Spotify(
|
|
407
|
+
Spotify = Spotify(SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET)
|
|
407
408
|
|
|
408
409
|
try:
|
|
409
410
|
artist_name = input("Artist Name: ")
|
|
410
411
|
song_name = input("Song Name: ")
|
|
411
412
|
pprint(Spotify.search(artist_name, song_name))
|
|
412
413
|
finally:
|
|
413
|
-
Spotify.
|
|
414
|
+
Spotify.close_session()
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Cheap Nightbot
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Cheap Nightbot
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
Metadata-Version: 2.2
|
|
2
|
-
Name: yutipy
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: A simple package for retrieving music information from various music platforms APIs.
|
|
5
|
-
Author: Cheap Nightbot
|
|
6
|
-
Author-email: Cheap Nightbot <hi@cheapnightbot.slmail.me>
|
|
7
|
-
Maintainer-email: Cheap Nightbot <hi@cheapnightbot.slmail.me>
|
|
8
|
-
License: MIT License
|
|
9
|
-
|
|
10
|
-
Copyright (c) 2025 Cheap Nightbot
|
|
11
|
-
|
|
12
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
-
in the Software without restriction, including without limitation the rights
|
|
15
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
-
furnished to do so, subject to the following conditions:
|
|
18
|
-
|
|
19
|
-
The above copyright notice and this permission notice shall be included in all
|
|
20
|
-
copies or substantial portions of the Software.
|
|
21
|
-
|
|
22
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
-
SOFTWARE.
|
|
29
|
-
|
|
30
|
-
Project-URL: Homepage, https://github.com/CheapNightbot/yutipy
|
|
31
|
-
Project-URL: Documentation, https://yutipy.readthedocs.io/
|
|
32
|
-
Project-URL: Repository, https://github.com/CheapNightbot/yutipy.git
|
|
33
|
-
Project-URL: Issues, https://github.com/CheapNightbot/yutipy/issues
|
|
34
|
-
Project-URL: Changelog, https://github.com/CheapNightbot/yutipy/blob/master/CHANGELOG.md
|
|
35
|
-
Project-URL: funding, https://ko-fi.com/cheapnightbot
|
|
36
|
-
Keywords: music,API,Deezer,iTunes,Spotify,YouTube Music,search,retrieve,information,yutify
|
|
37
|
-
Classifier: Development Status :: 4 - Beta
|
|
38
|
-
Classifier: Intended Audience :: Developers
|
|
39
|
-
Classifier: Topic :: Software Development :: Libraries
|
|
40
|
-
Classifier: Programming Language :: Python :: 3
|
|
41
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
42
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
43
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
44
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
45
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
46
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
47
|
-
Classifier: Operating System :: OS Independent
|
|
48
|
-
Requires-Python: >=3.8
|
|
49
|
-
Description-Content-Type: text/markdown
|
|
50
|
-
License-File: LICENSE
|
|
51
|
-
Requires-Dist: python-dotenv==1.0.1
|
|
52
|
-
Requires-Dist: rapidfuzz==3.12.1
|
|
53
|
-
Requires-Dist: requests==2.32.3
|
|
54
|
-
Requires-Dist: ytmusicapi==1.10.1
|
|
55
|
-
Provides-Extra: dev
|
|
56
|
-
Requires-Dist: pytest; extra == "dev"
|
|
57
|
-
|
|
58
|
-
<p align="center">
|
|
59
|
-
<img src="https://raw.githubusercontent.com/CheapNightbot/yutipy/main/docs/_static/yutipy_header.png" alt="yutipy" />
|
|
60
|
-
</p>
|
|
61
|
-
|
|
62
|
-
<p align="center">
|
|
63
|
-
<a href="https://github.com/CheapNightbot/yutipy/actions/workflows/tests.yml">
|
|
64
|
-
<img alt="GitHub Actions Workflow Status" src="https://img.shields.io/github/actions/workflow/status/cheapnightbot/yutipy/pytest-unit-testing.yml?style=for-the-badge&label=Pytest">
|
|
65
|
-
</a>
|
|
66
|
-
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
</
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
- [
|
|
89
|
-
- [
|
|
90
|
-
- [
|
|
91
|
-
- [
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
- Retrieve detailed music information, including album art, release dates, ISRC, and UPC codes.
|
|
99
|
-
|
|
100
|
-
## Installation
|
|
101
|
-
|
|
102
|
-
You can install the package using pip. Make sure you have Python 3.8 or higher installed.
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
pip install -U yutipy
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Usage Example
|
|
109
|
-
|
|
110
|
-
Here's a quick example of how to use the `yutipy` package to search for a song:
|
|
111
|
-
|
|
112
|
-
### Deezer
|
|
113
|
-
|
|
114
|
-
```python
|
|
115
|
-
from yutipy.deezer import Deezer
|
|
116
|
-
|
|
117
|
-
with Deezer() as deezer:
|
|
118
|
-
result = deezer.search("Artist Name", "Song Title")
|
|
119
|
-
print(result)
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
For more usage examples, see the [Usage Examples](https://yutipy.readthedocs.io/en/latest/usage_examples.html) page in docs.
|
|
123
|
-
|
|
124
|
-
## Contributing
|
|
125
|
-
|
|
126
|
-
Contributions are welcome! Please follow these steps:
|
|
127
|
-
|
|
128
|
-
1. Fork the repository.
|
|
129
|
-
2. Optionally, create an issue to discuss the changes you plan to make.
|
|
130
|
-
3. Create a new branch linked to that issue.
|
|
131
|
-
4. Make your changes in the new branch.
|
|
132
|
-
5. Write tests if you add new functionality.
|
|
133
|
-
6. Ensure all tests pass before opening a pull request.
|
|
134
|
-
7. Open a pull request for review.
|
|
135
|
-
|
|
136
|
-
Thank you for your contributions!
|
|
137
|
-
|
|
138
|
-
## License
|
|
139
|
-
|
|
140
|
-
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: yutipy
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A simple package for retrieving music information from various music platforms APIs.
|
|
5
|
+
Author: Cheap Nightbot
|
|
6
|
+
Author-email: Cheap Nightbot <hi@cheapnightbot.slmail.me>
|
|
7
|
+
Maintainer-email: Cheap Nightbot <hi@cheapnightbot.slmail.me>
|
|
8
|
+
License: MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2025 Cheap Nightbot
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
|
|
30
|
+
Project-URL: Homepage, https://github.com/CheapNightbot/yutipy
|
|
31
|
+
Project-URL: Documentation, https://yutipy.readthedocs.io/
|
|
32
|
+
Project-URL: Repository, https://github.com/CheapNightbot/yutipy.git
|
|
33
|
+
Project-URL: Issues, https://github.com/CheapNightbot/yutipy/issues
|
|
34
|
+
Project-URL: Changelog, https://github.com/CheapNightbot/yutipy/blob/master/CHANGELOG.md
|
|
35
|
+
Project-URL: funding, https://ko-fi.com/cheapnightbot
|
|
36
|
+
Keywords: music,API,Deezer,iTunes,Spotify,YouTube Music,search,retrieve,information,yutify
|
|
37
|
+
Classifier: Development Status :: 4 - Beta
|
|
38
|
+
Classifier: Intended Audience :: Developers
|
|
39
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
40
|
+
Classifier: Programming Language :: Python :: 3
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
44
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
45
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
46
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
47
|
+
Classifier: Operating System :: OS Independent
|
|
48
|
+
Requires-Python: >=3.8
|
|
49
|
+
Description-Content-Type: text/markdown
|
|
50
|
+
License-File: LICENSE
|
|
51
|
+
Requires-Dist: python-dotenv==1.0.1
|
|
52
|
+
Requires-Dist: rapidfuzz==3.12.1
|
|
53
|
+
Requires-Dist: requests==2.32.3
|
|
54
|
+
Requires-Dist: ytmusicapi==1.10.1
|
|
55
|
+
Provides-Extra: dev
|
|
56
|
+
Requires-Dist: pytest; extra == "dev"
|
|
57
|
+
|
|
58
|
+
<p align="center">
|
|
59
|
+
<img src="https://raw.githubusercontent.com/CheapNightbot/yutipy/main/docs/_static/yutipy_header.png" alt="yutipy" />
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<a href="https://github.com/CheapNightbot/yutipy/actions/workflows/tests.yml">
|
|
64
|
+
<img alt="GitHub Actions Workflow Status" src="https://img.shields.io/github/actions/workflow/status/cheapnightbot/yutipy/pytest-unit-testing.yml?style=for-the-badge&label=Pytest">
|
|
65
|
+
</a>
|
|
66
|
+
<a href="https://pypi.org/project/yutipy/">
|
|
67
|
+
<img src="https://img.shields.io/pypi/v/yutipy?style=for-the-badge" alt="PyPI" />
|
|
68
|
+
</a>
|
|
69
|
+
<a href="https://yutipy.readthedocs.io/en/latest/">
|
|
70
|
+
<img src="https://img.shields.io/readthedocs/yutipy?style=for-the-badge" alt="Documentation Status" />
|
|
71
|
+
</a>
|
|
72
|
+
<a href="https://github.com/CheapNightbot/yutipy/blob/master/LICENSE">
|
|
73
|
+
<img src="https://img.shields.io/github/license/CheapNightbot/yutipy?style=for-the-badge" alt="License" />
|
|
74
|
+
</a>
|
|
75
|
+
<a href="https://github.com/CheapNightbot/yutipy/stargazers">
|
|
76
|
+
<img src="https://img.shields.io/github/stars/CheapNightbot/yutipy?style=for-the-badge" alt="Stars" />
|
|
77
|
+
</a>
|
|
78
|
+
<a href="https://github.com/CheapNightbot/yutipy/issues">
|
|
79
|
+
<img src="https://img.shields.io/github/issues/CheapNightbot/yutipy?style=for-the-badge" alt="Issues" />
|
|
80
|
+
</a>
|
|
81
|
+
</p>
|
|
82
|
+
|
|
83
|
+
A _**simple**_ Python package for searching and retrieving music information from various music platforms APIs, including Deezer, iTunes, Spotify, and YouTube Music.
|
|
84
|
+
|
|
85
|
+
## Table of Contents
|
|
86
|
+
|
|
87
|
+
- [Features](#features)
|
|
88
|
+
- [Installation](#installation)
|
|
89
|
+
- [Usage Example](#usage-example)
|
|
90
|
+
- [Contributing](#contributing)
|
|
91
|
+
- [License](#license)
|
|
92
|
+
|
|
93
|
+
## Features
|
|
94
|
+
|
|
95
|
+
- Simple & Easy integration with popular music APIs.
|
|
96
|
+
- Search for music by artist and song title across multiple platforms.
|
|
97
|
+
- It uses `RapidFuzz` to compare & return the best match so that you can be sure you got what you asked for without having to worry and doing all that work by yourself.
|
|
98
|
+
- Retrieve detailed music information, including album art, release dates, lyrics, ISRC, and UPC codes.
|
|
99
|
+
|
|
100
|
+
## Installation
|
|
101
|
+
|
|
102
|
+
You can install the package using pip. Make sure you have Python 3.8 or higher installed.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
pip install -U yutipy
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Usage Example
|
|
109
|
+
|
|
110
|
+
Here's a quick example of how to use the `yutipy` package to search for a song:
|
|
111
|
+
|
|
112
|
+
### Deezer
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from yutipy.deezer import Deezer
|
|
116
|
+
|
|
117
|
+
with Deezer() as deezer:
|
|
118
|
+
result = deezer.search("Artist Name", "Song Title")
|
|
119
|
+
print(result)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
For more usage examples, see the [Usage Examples](https://yutipy.readthedocs.io/en/latest/usage_examples.html) page in docs.
|
|
123
|
+
|
|
124
|
+
## Contributing
|
|
125
|
+
|
|
126
|
+
Contributions are welcome! Please follow these steps:
|
|
127
|
+
|
|
128
|
+
1. Fork the repository.
|
|
129
|
+
2. Optionally, create an issue to discuss the changes you plan to make.
|
|
130
|
+
3. Create a new branch linked to that issue.
|
|
131
|
+
4. Make your changes in the new branch.
|
|
132
|
+
5. Write tests if you add new functionality.
|
|
133
|
+
6. Ensure all tests pass before opening a pull request.
|
|
134
|
+
7. Open a pull request for review.
|
|
135
|
+
|
|
136
|
+
Thank you for your contributions!
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
yutipy/__init__.py,sha256=t0w-pRLjIGD3UtDyd-JpeL-RrMona7YTV_0lZCpGLEc,232
|
|
2
|
+
yutipy/deezer.py,sha256=TbPk6f1ytrtk9GHXOoRZ948fcgOi0619-rQC9xfTYu0,8641
|
|
3
|
+
yutipy/exceptions.py,sha256=QDfOkaeZtSNg1lhXZ872yNJwbof68eVHDezZeZh8DiU,1029
|
|
4
|
+
yutipy/itunes.py,sha256=NhrllA3U0PUY3dNoMyiG1oZuyvdMQKYRBHzYSkt8ikM,5843
|
|
5
|
+
yutipy/models.py,sha256=RnfWjoNO1UoNsRvNRYd-4TpkU-4jHKu5t394vIqOOgw,1360
|
|
6
|
+
yutipy/musicyt.py,sha256=kvRYuhlNVuvy-WahJq895T3JAzmGTTiKB89r_uTMTAI,7155
|
|
7
|
+
yutipy/spotify.py,sha256=ZFn73iHtXczO4Dq3ZfYquwtP_fyfHBK2sJTFrcv_xYE,13232
|
|
8
|
+
yutipy/utils/__init__.py,sha256=7UFcFZ7fBtNXOTngjnRD3MeobT3x5UT2Gag94TXVgLk,169
|
|
9
|
+
yutipy/utils/cheap_utils.py,sha256=LIuEHib_97NuLahXxdHJUD9v-ccXNUc3NrLYk8EQ52A,1652
|
|
10
|
+
yutipy-1.0.0.dist-info/LICENSE,sha256=_89JsS2QnBG8tAb5-VWbJDj_uJ002zPJAYBJJdh3DPY,1071
|
|
11
|
+
yutipy-1.0.0.dist-info/METADATA,sha256=b8VSSJH__Ii-QJOfCszX4pBWEx6sKAmHcL9t4_qPVHQ,5897
|
|
12
|
+
yutipy-1.0.0.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
|
13
|
+
yutipy-1.0.0.dist-info/top_level.txt,sha256=t2A5V2_mUcfnHkbCy6tAQlb3909jDYU5GQgXtA4756I,7
|
|
14
|
+
yutipy-1.0.0.dist-info/RECORD,,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
yutipy-0.1.1.dist-info/RECORD
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
yutipy/__init__.py,sha256=t0w-pRLjIGD3UtDyd-JpeL-RrMona7YTV_0lZCpGLEc,232
|
|
2
|
-
yutipy/deezer.py,sha256=TbPk6f1ytrtk9GHXOoRZ948fcgOi0619-rQC9xfTYu0,8641
|
|
3
|
-
yutipy/exceptions.py,sha256=QDfOkaeZtSNg1lhXZ872yNJwbof68eVHDezZeZh8DiU,1029
|
|
4
|
-
yutipy/itunes.py,sha256=NhrllA3U0PUY3dNoMyiG1oZuyvdMQKYRBHzYSkt8ikM,5843
|
|
5
|
-
yutipy/models.py,sha256=-UEi05on5XsKjFSqUNt1yZnLod_A9upqh2nIPWTtEEI,1415
|
|
6
|
-
yutipy/musicyt.py,sha256=kvRYuhlNVuvy-WahJq895T3JAzmGTTiKB89r_uTMTAI,7155
|
|
7
|
-
yutipy/spotify.py,sha256=YYTF1git7mRVFWWGM1TILIIyZMPPDbD_F_BLjfqU6cI,12906
|
|
8
|
-
yutipy/__pycache__/__init__.cpython-312.pyc,sha256=q-CaghM107NTOH0ZfH9LKDDUZJuGA_teF1QyoO1wNb8,392
|
|
9
|
-
yutipy/__pycache__/deezer.cpython-312.pyc,sha256=UfRxyBobsocMxkpF4HP06EpFsAz96ZHU4QlYn8EzQcY,10588
|
|
10
|
-
yutipy/__pycache__/exceptions.cpython-312.pyc,sha256=Zc73Tr79emWJ9pmpAVoL12YnBBOWJulV1hxtSso4hy8,2096
|
|
11
|
-
yutipy/__pycache__/itunes.cpython-312.pyc,sha256=59fJpxL2ZjQoyzq_1U6sesJEuNrfa62kvtPYeSwzZNg,7521
|
|
12
|
-
yutipy/__pycache__/models.cpython-312.pyc,sha256=KJUa3-C67TMq1EAGuQlZYT99JS1AEDUi74KY8bEHkkg,1848
|
|
13
|
-
yutipy/__pycache__/musicyt.cpython-312.pyc,sha256=y508WR8Cl8DtisJli3FwNDEC6CJZajiZdcWJLN7xXyY,9176
|
|
14
|
-
yutipy/__pycache__/spotify.cpython-312.pyc,sha256=0Knor0AN6zG6ATYSGL0YPb6b7rrT2krnpBv-e2ynam8,15870
|
|
15
|
-
yutipy/utils/__init__.py,sha256=7UFcFZ7fBtNXOTngjnRD3MeobT3x5UT2Gag94TXVgLk,169
|
|
16
|
-
yutipy/utils/cheap_utils.py,sha256=LIuEHib_97NuLahXxdHJUD9v-ccXNUc3NrLYk8EQ52A,1652
|
|
17
|
-
yutipy/utils/__pycache__/__init__.cpython-312.pyc,sha256=_ldEMv66ELlrY1M7fN_2r5XySvgAsqTE0U8ASGXx8bs,286
|
|
18
|
-
yutipy/utils/__pycache__/cheap_utils.cpython-312.pyc,sha256=i6nRmXcRtCkTzKQ1mWyjN7Xz4NapqgBdXA33so8xgLU,2376
|
|
19
|
-
yutipy-0.1.1.dist-info/LICENSE,sha256=Tymbhvk1F_6BDFE0X8BBiQp7cBCjbzKfRAITmvxJIyA,1092
|
|
20
|
-
yutipy-0.1.1.dist-info/METADATA,sha256=nWGLHD2t-1GvvU9vUXcU5TtvLe05_w2G0U8pKhWw_Uc,5865
|
|
21
|
-
yutipy-0.1.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
22
|
-
yutipy-0.1.1.dist-info/top_level.txt,sha256=t2A5V2_mUcfnHkbCy6tAQlb3909jDYU5GQgXtA4756I,7
|
|
23
|
-
yutipy-0.1.1.dist-info/RECORD,,
|
|
File without changes
|