Collections¶

The Tidal service implements the standard collection interfaces that are common across all plistsync services. By inheriting from the base classes and conforming to the established protocols, Tidal provides a unified interface that works consistently with other services.

Library Collection¶

The TidalLibraryCollection represents the full Tidal catalog from the perspective of the authenticated user.

from plistsync.services.tidal import TidalLibraryCollection

library = TidalLibraryCollection()

Track Lookup¶

The Tidal library collections implements the GlobalLookup protocol, allowing you to search for tracks across Tidal’s entire music universe by their ids. Specifically, tidal supports lookups by isrc and tidal_id.

# By tidal id
if track1 := library.find_by_global_ids({"isrc": "GBBZH9601601"}):
    print(track1)

# By isrc
if track2 := library.find_by_global_ids({"tidal_id": "490839595"}):
    print(track2)

assert track1 == track2
Track[Origin Unknown > Valley Of The Shadows, hash: 7201758464017387873]
Track[Origin Unknown > Valley Of The Shadows, hash: 7201758464017387873]

Note

Track equality is determined by metadata and unique identifiers. On Tidal, identical tracks may have different IDs (e.g., due to different releases or versions), which can lead to false negatives during equality checks. While this may cause unexpected mismatches, it reflects the underlying truth: these are distinct track instances—even if sonically identical.

If you need/want to lookup many tracks at once, consider using TidalLibraryCollection.find_many_by_global_ids for better performance.

Playlist Collection¶

The TidalPlaylistCollection represents a playlist than is accessible by the currently authenticated user.

Retrieving playlists¶

You can retrieve all playlists of a user using the library’s TidalLibraryCollection.playlists property.

playlists = library.playlists
for playlist in playlists:
    print(f"Playlist: {playlist.name} ({len(playlist)} tracks)")
Playlist: plistsync (3 tracks)

If you just want a specific playlist, you can use the library’s TidalLibraryCollection.get_playlist method to retrieve a playlist.

pl = library.get_playlist(
    name="plistsync"
    # id = "23d960d6-07be-42f3-89ab-72ec339ca9ac"
    # url = "https://tidal.com/playlist/23d960d6-07be-42f3-89ab-72ec339ca9ac"
)
if pl is not None:
    print(f"Found playlist: {pl.name} ({len(pl)} tracks)")
else:
    print("Playlist not found.")
Found playlist: plistsync (3 tracks)

Note

This method supports lookup by various identifiers, including name=, id=, or url=. Lookup by name will return None if no matching playlist is found, while lookups by other identifiers will raise a ValueError if the playlist cannot be resolved.

Creating playlists¶

Use {py.class}TidalPlaylistCollection <plistsync.services.tidal.TidalPlaylistCollection> to model a playlist locally, then (optionally) create/associate it on Tidal.

from plistsync.services.tidal import TidalPlaylistCollection

pl = TidalPlaylistCollection(
    library,
    name="My New Playlist",
    description="Created via plistsync",
)
assert pl.remote_associated == False

To remotly create the same playlist use the TidalPlaylistCollection.remote_create method.

pl.remote_create()
assert pl.remote_associated == True

Updating a playlist¶

For updating a playlist, you should use the playlist’s TidalPlaylistCollection.edit context manager. This ensures that all changes are properly saved back to Tidal when you exit the context. This also minifies changes and therefore reduces API calls.

# Updating a playlist description/name
with pl.remote_edit():
    pl.description = "Created via plistsync"

pl.description
'Created via plistsync'

You can add tracks to a playlist using the same context manager, again this will add the tracks when you exit the context.

from plistsync.services.tidal import TidalPlaylistTrack

new_track_1 = library.find_by_global_ids({"isrc": "GBBZH9601601"})
new_track_2 = library.find_by_global_ids({"isrc": "GBXJH1000082"})
assert new_track_1 is not None
assert new_track_2 is not None

with pl.remote_edit():
    # TODO: We should reevaluate the type hierarchy here.
    # for now, we have to manually cast TidalTrack to TidalPlaylistTrack.
    # this will become more convenient, eventually.
    pl.tracks.append(TidalPlaylistTrack(new_track_1))
    pl.tracks.append(TidalPlaylistTrack(new_track_2))

pl.tracks
[Track[Origin Unknown > Valley Of The Shadows, hash: 7201758464017387873],
 Track[Kyo > If I Could, hash: -1600195561874309738]]
# Remove a track
with pl.remote_edit():
    pl.tracks.pop()

To reorder tracks in a playlist, you can change the order of the TidalPlaylistCollection.tracks list within the context manager.

with pl.remote_edit():
    pl.tracks.insert(0, pl.tracks.pop())

Delete a playlist¶

You can also delete the playlist again on tidal.

pl.remote_delete()
assert pl.remote_associated == False