Create a playlist of your followed artists’ latest music
- In this example, you will:
Load information about your followed artists
Load the tracks released by these artists between two dates
Create a playlist containing these tracks
Set up logging
Set up logging to ensure you can see all info reported by the later operations.
Libraries log info about loaded objects to the custom STAT
level.
import logging
import sys
from musify.logger import STAT
logging.basicConfig(format="%(message)s", level=STAT, stream=sys.stdout)
Create the playlist
Create a
RemoteAPI
object:Note
This step uses the
SpotifyLibrary
, but any supported music streaming service can be used in generally the same way. Just modify the imports and classes as required.from musify.libraries.remote.spotify.api import SpotifyAPI api = SpotifyAPI( client_id="<YOUR CLIENT ID>", client_secret="<YOUR CLIENT SECRET>", scope=[ "user-library-read", "user-follow-read", "playlist-read-collaborative", "playlist-read-private", "playlist-modify-public", "playlist-modify-private" ], # providing a `token_file_path` will save the generated token to your system # for quicker authorisations in future token_file_path="<PATH TO JSON TOKEN>" )
If you haven’t already, you will need to load and enrich data about your followed artists. You may use this helper function to help do so:
from musify.libraries.remote.core.library import RemoteLibrary async def load_artists(library: RemoteLibrary) -> None: """Loads the artists followed by a given user in their given ``library`` and enriches them.""" async with library: await library.load_saved_artists() await library.enrich_saved_artists(types=("album", "single"))
Define helper function for filtering albums:
from datetime import date from musify.libraries.remote.core.object import RemoteAlbum def match_date(alb: RemoteAlbum, start: date, end: date) -> bool: """Match ``start`` and ``end`` dates to the release date of the given ``alb``""" if alb.date: return start <= alb.date <= end if alb.month: return start.year <= alb.year <= end.year and start.month <= alb.month <= end.month if alb.year: return start.year <= alb.year <= end.year return False
Define helper function for filtering the albums and loading the tracks for only these albums:
from musify.libraries.remote.core.types import RemoteObjectType from musify.libraries.remote.core.object import RemoteAlbum async def get_albums(library: RemoteLibrary, start: date, end: date) -> list[RemoteAlbum]: """ Get the albums that match the ``start`` and ``end`` date range from a given ``library`` and get the tracks on those albums if needed. """ albums = [album for artist in library.artists for album in artist.albums if match_date(album, start, end)] albums_need_extend = [album for album in albums if len(album.tracks) < album.track_total] if not albums_need_extend: return albums kind = RemoteObjectType.ALBUM key = api.collection_item_map[kind] async with library: await library.logger.get_asynchronous_iterator( (api.extend_items(album.response, kind=kind, key=key) for album in albums), desc="Getting album tracks", unit="albums" ) for album in albums: album.refresh(skip_checks=False) return albums
Define driver function for creating the playlist:
from musify.libraries.remote.spotify.object import SpotifyPlaylist async def create_new_music_playlist(name: str, library: RemoteLibrary, start: date, end: date) -> None: """ Create a playlist with the given ``name`` in the given ``library`` featuring new music by followed artists released between ``start`` date and ``end`` date. """ await load_artists(library) albums = await get_albums(library, start, end) # log stats about the loaded artists library.log_artists() async with library: playlist = await SpotifyPlaylist.create(api=api, name=name) tracks = [track for album in sorted(albums, key=lambda x: x.date, reverse=True) for track in album] playlist.extend(tracks, allow_duplicates=False) # sync the object with Spotify and log the results results = await playlist.sync(kind="refresh", reload=False, dry_run=False) library.log_sync({name: results})
Define the required parameters and run the operation:
import asyncio from datetime import datetime, timedelta from musify.libraries.remote.spotify.library import SpotifyLibrary playlist_name = "New Music Playlist" library = SpotifyLibrary(api=api) end = datetime.now().date() start = end - timedelta(weeks=4) asyncio.run(create_new_music_playlist(playlist_name, library, start, end))