Skip to content

song

Song module that hold the Song and SongList classes.

Song dataclass ¤

Song class. Contains all the information about a song.

display_name: str property ¤

Returns a display name for the song.

Returns¤
  • The display name.

json: Dict[str, Any] property ¤

Returns a dictionary of the song's data.

Returns¤
  • The dictionary.

from_data_dump(data) classmethod ¤

Create a Song object from a data dump.

Arguments¤
  • data: The data dump.
Returns¤
  • The Song object.
Source code in spotdl/types/song.py
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
@classmethod
def from_data_dump(cls, data: str) -> "Song":
    """
    Create a Song object from a data dump.

    ### Arguments
    - data: The data dump.

    ### Returns
    - The Song object.
    """

    # Create dict from json string
    data_dict = json.loads(data)

    # Return product object
    return cls(**data_dict)

from_dict(data) classmethod ¤

Create a Song object from a dictionary.

Arguments¤
  • data: The dictionary.
Returns¤
  • The Song object.
Source code in spotdl/types/song.py
214
215
216
217
218
219
220
221
222
223
224
225
226
227
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "Song":
    """
    Create a Song object from a dictionary.

    ### Arguments
    - data: The dictionary.

    ### Returns
    - The Song object.
    """

    # Return product object
    return cls(**data)

from_missing_data(**kwargs) classmethod ¤

Create a Song object from a dictionary with missing data. For example, data dict doesn't contain all the required attributes for the Song class.

Arguments¤
  • data: The dictionary.
Returns¤
  • The Song object.
Source code in spotdl/types/song.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
@classmethod
def from_missing_data(cls, **kwargs) -> "Song":
    """
    Create a Song object from a dictionary with missing data.
    For example, data dict doesn't contain all the required
    attributes for the Song class.

    ### Arguments
    - data: The dictionary.

    ### Returns
    - The Song object.
    """

    song_data: Dict[str, Any] = {}
    for key in cls.__dataclass_fields__:  # pylint: disable=E1101
        song_data.setdefault(key, kwargs.get(key))

    return cls(**song_data)

from_search_term(search_term) classmethod ¤

Creates a list of Song objects from a search term.

Arguments¤
  • search_term: The search term to use.
Returns¤
  • The Song object.
Source code in spotdl/types/song.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
@classmethod
def from_search_term(cls, search_term: str) -> "Song":
    """
    Creates a list of Song objects from a search term.

    ### Arguments
    - search_term: The search term to use.

    ### Returns
    - The Song object.
    """

    raw_search_results = Song.search(search_term)

    if len(raw_search_results["tracks"]["items"]) == 0:
        raise SongError(f"No results found for: {search_term}")

    return Song.from_url(
        "http://open.spotify.com/track/"
        + raw_search_results["tracks"]["items"][0]["id"]
    )

from_url(url) classmethod ¤

Creates a Song object from a URL.

Arguments¤
  • url: The URL of the song.
Returns¤
  • The Song object.
Source code in spotdl/types/song.py
 61
 62
 63
 64
 65
 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
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
@classmethod
def from_url(cls, url: str) -> "Song":
    """
    Creates a Song object from a URL.

    ### Arguments
    - url: The URL of the song.

    ### Returns
    - The Song object.
    """

    if "open.spotify.com" not in url or "track" not in url:
        raise SongError(f"Invalid URL: {url}")

    # query spotify for song, artist, album details
    spotify_client = SpotifyClient()

    # get track info
    raw_track_meta = spotify_client.track(url)

    if raw_track_meta is None:
        raise SongError(
            "Couldn't get metadata, check if you have passed correct track id"
        )

    if raw_track_meta["duration_ms"] == 0 or raw_track_meta["name"].strip() == "":
        raise SongError(f"Track no longer exists: {url}")

    # get artist info
    primary_artist_id = raw_track_meta["artists"][0]["id"]
    raw_artist_meta: Dict[str, Any] = spotify_client.artist(primary_artist_id)  # type: ignore

    # get album info
    album_id = raw_track_meta["album"]["id"]
    raw_album_meta: Dict[str, Any] = spotify_client.album(album_id)  # type: ignore

    # create song object
    return cls(
        name=raw_track_meta["name"],
        artists=[artist["name"] for artist in raw_track_meta["artists"]],
        artist=raw_track_meta["artists"][0]["name"],
        album_id=album_id,
        album_name=raw_album_meta["name"],
        album_artist=raw_album_meta["artists"][0]["name"],
        copyright_text=raw_album_meta["copyrights"][0]["text"]
        if raw_album_meta["copyrights"]
        else None,
        genres=raw_album_meta["genres"] + raw_artist_meta["genres"],
        disc_number=raw_track_meta["disc_number"],
        disc_count=int(raw_album_meta["tracks"]["items"][-1]["disc_number"]),
        duration=raw_track_meta["duration_ms"] / 1000,
        year=int(raw_album_meta["release_date"][:4]),
        date=raw_album_meta["release_date"],
        track_number=raw_track_meta["track_number"],
        tracks_count=raw_album_meta["total_tracks"],
        isrc=raw_track_meta.get("external_ids", {}).get("isrc"),
        song_id=raw_track_meta["id"],
        explicit=raw_track_meta["explicit"],
        publisher=raw_album_meta["label"],
        url=raw_track_meta["external_urls"]["spotify"],
        popularity=raw_track_meta["popularity"],
        cover_url=max(
            raw_album_meta["images"], key=lambda i: i["width"] * i["height"]
        )["url"]
        if raw_album_meta["images"]
        else None,
    )

list_from_search_term(search_term) classmethod ¤

Creates a list of Song objects from a search term.

Arguments¤
  • search_term: The search term to use.
Returns¤
  • The list of Song objects.
Source code in spotdl/types/song.py
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
@classmethod
def list_from_search_term(cls, search_term: str) -> "List[Song]":
    """
    Creates a list of Song objects from a search term.

    ### Arguments
    - search_term: The search term to use.

    ### Returns
    - The list of Song objects.
    """

    raw_search_results = Song.search(search_term)

    songs = []
    for idx, _ in enumerate(raw_search_results.get("tracks", []).get("items", [])):
        songs.append(
            Song.from_url(
                "http://open.spotify.com/track/"
                + raw_search_results["tracks"]["items"][idx]["id"]
            )
        )

    return songs

search(search_term) staticmethod ¤

Searches for Songs from a search term.

Arguments¤
  • search_term: The search term to use.
Returns¤
  • The raw search results
Source code in spotdl/types/song.py
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
@staticmethod
def search(search_term: str):
    """
    Searches for Songs from a search term.

    ### Arguments
    - search_term: The search term to use.

    ### Returns
    - The raw search results
    """
    spotify_client = SpotifyClient()
    raw_search_results = spotify_client.search(search_term)

    if raw_search_results is None:
        raise SongError(f"Spotipy error, no response: {search_term}")

    return raw_search_results

SongError ¤

Bases: Exception

Base class for all exceptions related to songs.

SongList dataclass ¤

SongList class. Base class for all other song lists subclasses.

json: Dict[str, Any] property ¤

Returns a dictionary of the song list's data.

Returns¤
  • The dictionary.

length: int property ¤

Get list length (number of songs).

Returns¤
  • The list length.

from_search_term(search_term, fetch_songs=True) classmethod ¤

Creates a SongList object from a search term.

Arguments¤
  • search_term: The search term to use.
Returns¤
  • The SongList object.
Source code in spotdl/types/song.py
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
@classmethod
def from_search_term(cls, search_term: str, fetch_songs: bool = True):
    """
    Creates a SongList object from a search term.

    ### Arguments
    - search_term: The search term to use.

    ### Returns
    - The SongList object.
    """

    list_type = cls.__name__.lower()
    spotify_client = SpotifyClient()
    raw_search_results = spotify_client.search(search_term, type=list_type)

    if (
        raw_search_results is None
        or len(raw_search_results.get(f"{list_type}s", {}).get("items", [])) == 0
    ):
        raise SongListError(
            f"No {list_type} matches found on spotify for '{search_term}'"
        )

    list_id = raw_search_results[f"{list_type}s"]["items"][0]["id"]
    return cls.from_url(
        f"http://open.spotify.com/{list_type}/{list_id}",
        fetch_songs,
    )

from_url(url, fetch_songs=True) classmethod ¤

Create a SongList object from a url.

Arguments¤
  • url: The url of the list.
  • fetch_songs: Whether to fetch missing metadata for songs.
Returns¤
  • The SongList object.
Source code in spotdl/types/song.py
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
@classmethod
def from_url(cls, url: str, fetch_songs: bool = True):
    """
    Create a SongList object from a url.

    ### Arguments
    - url: The url of the list.
    - fetch_songs: Whether to fetch missing metadata for songs.

    ### Returns
    - The SongList object.
    """

    metadata, songs = cls.get_metadata(url)
    urls = [song.url for song in songs]

    if fetch_songs:
        songs = [Song.from_url(song.url) for song in songs]

    return cls(**metadata, urls=urls, songs=songs)

get_metadata(url) staticmethod ¤

Get metadata for a song list.

Arguments¤
  • url: The url of the song list.
Returns¤
  • The metadata.
Source code in spotdl/types/song.py
356
357
358
359
360
361
362
363
364
365
366
367
368
@staticmethod
def get_metadata(url: str) -> Tuple[Dict[str, Any], List[Song]]:
    """
    Get metadata for a song list.

    ### Arguments
    - url: The url of the song list.

    ### Returns
    - The metadata.
    """

    raise NotImplementedError

SongListError ¤

Bases: Exception

Base class for all exceptions related to song lists.