Changelog¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.7.0] - Upcoming¶
Breaking Changes¶
Refactored playlist identifier handling across the codebase by replacing service-specific
PlaylistIdsdictionaries with strongly typed, immutablePlaylistIDdataclasses for each service (e.g. Spotify, Plex).Removed obsolete playlist ID extraction utilities that are no longer required under the new identifier system.
Updated all playlist operations and internal synchronization flows to use the new typed identifier model consistently.
This improves type safety, clarity, and extensibility for playlist identification and lookup operations. All playlist-related APIs and synchronization logic now operate on explicit identifier types instead of loosely structured dictionaries.
Added¶
Added typed
Servicemarker class withtrack_cls,library_cls,playlist_clsattributes and module-inferrednameproperty, enabling single-handle access to all a service’s core types. (#95)Added a migration example to fully copy a playlist from an arbitrary service to another. (#60)
Fixed¶
When syncing playlists to traktor, we now insert missing tracks into the library collection. This avoids those track to disappear from the playlist when launching Traktor after the sync. (#54)
Adjusted spotify api layer for deprecations
Changes¶
Introduced a OfflineTrack class mirroring the idea behind the OfflinePlaylist. This allows us to preserve track information even after deletion from the remote service, and to keep the Playlist class hierarchy cleanly separated between in-memory and service-synced implementations.
[0.6.0] - 2026-04-18¶
Breaking Changes¶
Playlist Class Hierarchy Refactor¶
The playlist class hierarchy has been redesigned for clearer separation of concerns:
Renamed Classes:
PlaylistCollection→Playlist(base protocol)SpotifyPlaylistCollection→SpotifyPlaylistTidalPlaylistCollection→TidalPlaylistPlexPlaylistCollection→PlexPlaylistNMLPlaylistCollection→NMLPlaylist
Library Classes Renamed:
SpotifyLibraryCollection→SpotifyLibraryTidalLibraryCollection→TidalLibraryPlexLibrarySectionCollection→PlexLibraryNMLLibraryCollection→NMLLibrary
New Abstractions:
OfflinePlaylist— In-memory playlist with no service synchronizationServicePlaylist— Base for playlists synchronized with music servicesMultiRequestServicePlaylist— For APIs requiring multi-request modificationsPlaylistIDs— Unified TypedDict for cross-service playlist identification
Method Changes:
Old |
New |
Notes |
|---|---|---|
|
|
Context manager for transactional edits |
|
|
Returns |
|
|
Factory method on library |
|
|
Bulk sync to remote |
|
Removed |
Service playlists always correspond to remote |
Migration:
# Old
pl = SpotifyPlaylistCollection(library, "Name", "desc")
pl.remote_create()
with pl.remote_edit():
pl.tracks.append(track)
# New
pl = library.create_playlist("Name", "desc")
with pl.edit():
pl.tracks.append(track)
Auth commands are now available via
plistsync auth [service]instead ofplistsync [service] auth
Added¶
Split Playlist ABC into two classes: one for simple services, like filesystems, where states can be pushed via a single API call (
PlaylistCollection) and one where multiple API calls are required (MultiRequestPlaylistCollection), e.g. when a playlists description cannot be pushed in the same call as track changes.Added
allservicesdependency group to allow a loaded pip install with batteries included.Added
plistsync --versioncommand to show the currently installed version of the library
Fixed¶
Fixed lazy track loading when playlist has 0 tracks (
force=Truelogic in_load_tracks)In rare cases, spotify playlists can contain invalid items, which do not appear in the web interface (but through the api). We now filter and remove them.
Fixed an issue with the spotify api returning duplicate playlists on pagination borders.
In rare cases, spotify playlists can contain invalid items, which do not appear in the web interface (but through the api). We now filter and remove them.
[0.5.1] - 2026-03-16¶
Fixed¶
Add missing platformdirs dependency
0.5.0 - 2026-03-15¶
This marks the first public release of plistsync, a major milestone for the project! 🎉
While the library is now in a very usable state and suitable for real-world music library synchronization, we’re still actively refining the public API. As such, breaking changes to function signatures, module structure, or core abstractions may occur without deprecation warnings until we reach version 1.0.0.
We encourage early adopters to:
Experiment freely and share feedback (via GitHub Issues or Discussions)
Pin to this version if stability is critical
Expect occasional breaking changes as we iterate toward a stable
1.0.0API
Added¶
Traktor config option
backup_before_write(enabled by default), which creates a backup of the NML file before each write operation.pyproject.tomlmetadata enhancements: updatedreadme,license,authors,project_urls, andclassifiersfor better discoverability and packaging.Support for batched remote operations, enabling efficient minification of expensive network requests (e.g., bulk playlist updates across services).
Improved examples: now hosted in
docs/examples(full-fledged Jupyter notebooks by the core team) anddocs/examples/community(community-contributed scripts, including simple CLI workflows).
Changed¶
Unified
__repr__format across all core classes toClassName(key=value)for consistent, debug-friendly output.Standardized
get_playlist()behavior across all services: now consistently returnsNonewhen no playlist is found, regardless of the lookup identifier used. Introducedget_playlist_or_raise()for predictable, exception-raising behavior when a playlist must exist.
0.4.0 - 2026-03-07¶
Added¶
Enhanced documentation around traktor
Plex authentication flow: Automated token retrieval replaces manual web page searches
Config refactoring: Replaced hardcoded YAML defaults with dataclass fields (Note: requires config file recreation)
Unified CLI authentication: Standardized parameters across Spotify, Tidal, and Plex services
Configuration files can now be placed in multiple locations with clear precedence:
Environment variable:
PSYNC_CONFIG_DIR=/path/to/configGlobal directory: User’s config folder (automatic fallback)
Verify jupyter notebooks are runnable and output via nbmake
Added configurable logging (
logging.handler:rich|basic), improved CLI verbosity (-v) behavior and documented advanced logging.Renewed icon
Added integration tests that use github secrets for tidal and spotify auth, and config yaml
Added check for notebook consistency via nbmake
Changed¶
Traktor playlist
NMLPlaylistCollectionis now aligned with thePlaylistCollectionprotocolEnhanced typing for
Matchesclass and collection protocols by using a TypeVar for Tracks.Nbstripout keeps outputs now
0.3.0 - 2026-02-16¶
Added¶
Collection protocol modernization:
TrackStreamnow exposes an explicit.tracksproperty (instead of__iter__), and library collections expose.playlists.Added default
LocalLookup.find_many_by_local_ids()batch helper (iterative fallback; services can override for true batching).
Transactional remote playlist operations:
New
PlaylistInfounified structure (name,description, …) shared across services.PlaylistCollection.remote_edit()context manager applies a diff on exit and rolls back local state on errors.PlaylistCollection.remote_create()scaffolding for creating playlists online before editing.Playlist remote operations are now modeled explicitly via abstract
_remote_*methods (insert/delete/move/update/create), with a shared diff-driven apply loop.
Service improvements & new helpers:
Spotify: playlist ID extraction from URL/URI (
extract_spotify_playlist_id) + test coverage.Tidal: playlist ID extraction from URL (
extract_tidal_playlist_id); added API helper to fetch playlist items (get_items).Plex: expanded playlist API wrapper (create/update/delete/add/remove/move/clear) to support richer remote playlist edits.
Documentation:
New service collection notebooks for Spotify and Plex; expanded/rewritten Tidal collections notebook with playlist CRUD + editing examples.
Added developer debugging guide (
docs/dev/debug.md) and wired it into the contribution docs toctree.
Changed¶
Plex authentication flow: Automated token retrieval replaces manual web page searches.
Config refactoring: Replaced hardcoded YAML defaults with dataclass fields (Note: requires config file recreation).
Unified CLI authentication: Standardized parameters across Spotify, Tidal, and Plex services.
Diff algorithm overhaul:
Improved handling of duplicates and complex reorders using a “delete extras first” strategy.
Operations now track a
live_listsnapshot to support stable index reasoning during remote edits.
Playlist / collection API updates across the codebase:
Examples and services migrated from
for track in pl:tofor track in pl.tracks.Library
get_playlist()is now a kwarg-based resolver (e.g.name=,id=,url=,uri=depending on service) with consistent “name returns None, id/url/uri raise” behavior.
Plex service refactor:
PlexTrack.plex_idrenamed to.id.Playlist fetching now uses
PlexLibrarySectionCollection.get_playlist()and sorted.playlists.
Path rewriting now preserves path types (
PurePosixPath/PureWindowsPath) via generic typing/coercion.Track model behavior:
Added
Track.__eq__andTrack.__hash__for data-based equality/hash semantics.Track.__repr__now prints an explicit hash field.
Tooling: Ruff target-version bumped from Python 3.10 to 3.11.
Test suite reorganization:
Beets and Traktor tests moved under
tests/services/...; Traktor tests now skip cleanly when optional dependencies are missing.
Enhanced README, added LICENCE, reformatted CHANGELOG.
0.2.0 - 2025-10-30¶
Added¶
Added changelog reminder as GitHub Action.
Playlist abstraction layer for easier cross-service syncing.
Spotify service integration.
Tidal service integration.
Example notebooks for Spotify and Tidal usage.
Changed¶
Enabled Ruff in
.ipynbfiles.Updated
eyeconfdependency to 0.3.0.Updated Spotify and Tidal API implementations for better reliability.
Updated
eyeconfdependency.Improved test coverage for core modules.
Other¶
Enhanced test coverage for core modules.
Fixed multiple issues with the documentation build process.
Fixed¶
Documentation build issues.
ISRC lookup and API scope handling bugs.
0.1.0 - 2025-09-08¶
Added¶
Initial release with core abstractions for tracks and collections.
Integrations with Plex, Traktor, Beets, and Local services.
Documentation setup and first examples.
Basic CI/CD workflows.