Sync data between local and remote libraries

In this example, you will:
  • Search for local tracks on a music streaming service and assign unique remote IDs to tags in your local tracks

  • Get tags and images for a track from a music stream service and save it them to your local track file

  • Create remote playlists from your local playlists

Note

This guide will use Spotify, but any supported music streaming service can be used in generally the same way. Just modify the imports and classes as required.

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
from musify.log import STAT

logging.basicConfig(format="%(message)s", level=STAT)

Sync data

  1. Set up and load at least one local library with a remote wrangler attached, and one remote API object:

    from musify.libraries.local.library import LocalLibrary
    from musify.libraries.remote.spotify.processors import SpotifyDataWrangler
    
    local_library = LocalLibrary(
        library_folders=["<PATH TO YOUR LIBRARY FOLDER>", ...],
        playlist_folder="<PATH TO YOUR PLAYLIST FOLDER>",
        # this wrangler will be needed to interpret matched URIs as valid
        remote_wrangler=SpotifyDataWrangler(),
    )
    local_library.load()
    
    from musify.libraries.remote.spotify.api import SpotifyAPI
    
    api = SpotifyAPI(
        client_id="<YOUR CLIENT ID>",
        client_secret="<YOUR CLIENT SECRET>",
        scopes=[
            "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>"
    )
    
    # authorise the program to access your Spotify data in your web browser
    api.authorise()
    
  2. Search for tracks and check the results:

    from musify.libraries.remote.core.processors.search import RemoteItemSearcher
    from musify.libraries.remote.core.processors.check import RemoteItemChecker
    from musify.libraries.remote.spotify.factory import SpotifyObjectFactory
    
    albums = local_library.albums[:3]
    factory = SpotifyObjectFactory(api=api)
    
    searcher = RemoteItemSearcher(matcher=ItemMatcher(), object_factory=factory)
    searcher.search(albums)
    
    checker = RemoteItemChecker(matcher=ItemMatcher(), object_factory=factory)
    checker.check(albums)
    
  3. Load the matched tracks, get tags from the music streaming service, and save the tags to the file:

    Note

    By default, URIs are saved to the comments tag.

    from musify.libraries.remote.spotify.object import SpotifyTrack
    
    for album in albums:
        for local_track in album:
            remote_track = SpotifyTrack.load(local_track.uri, api=api)
    
            local_track.title = remote_track.title
            local_track.artist = remote_track.artist
            local_track.date = remote_track.date
            local_track.genres = remote_track.genres
            local_track.image_links = remote_track.image_links
    
            # alternatively, just merge all tags
            local_track |= remote_track
    
            # save the track here or...
            local_track.save(replace=True, dry_run=False)
    
        # ...save all tracks on the album at once here
        album.save_tracks(replace=True, dry_run=False)
    
  4. Once all tracks in a playlist have URIs assigned, sync the local playlist with a remote playlist:

    from musify.libraries.remote.spotify.library import SpotifyLibrary
    
    remote_library = SpotifyLibrary(api=api)
    remote_library.load_playlists()
    
    local_playlist = local_library.playlists["<YOUR PLAYLIST'S NAME>"]  # case sensitive
    remote_playlist = remote_library.playlists["<YOUR PLAYLIST'S NAME>"]  # case sensitive
    
    # sync the object with Spotify and pretty print info about the reloaded remote playlist
    remote_playlist.sync(items=local_playlist, kind="new", reload=True, dry_run=False)
    print(remote_playlist)