Skip to content

Commit

Permalink
feat: ability to update playlist details like name description collab…
Browse files Browse the repository at this point in the history
…orative, spotify has its own bug on changing privacy settings, which doest not work
  • Loading branch information
supermandee committed Dec 17, 2024
1 parent 45b157b commit 1a43764
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Hey there! Meet MySpotiPal - your AI-powered music buddy that knows your Spotify
"Please remove the song Sunset Lover from my playlist Beach Lounge Vibes"
"Create a playlist called '80s Rock' and add some hair metal classics from the 80s"
```
Automatically create playlists and manage them in your Spotify account; this includes adding and deleting tracks
Automatically create playlists and manage them in your Spotify account; this includes adding and deleting tracks, updating the name, description, privacy and collaborative settings

### Check Your Music Taste 🎧
```
Expand Down
27 changes: 27 additions & 0 deletions ai_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,25 @@
}
}
},
{
"type": "function",
"function": {
"name": "update_playlist_details",
"description": "Update the name and description of a Spotify playlist in the user's library or change the playlist to private or public, or make the playlist collaborative",
"parameters": {
"type": "object",
"properties": {
"playlist_id": {"type": "string"},
"name": {"type": "string"},
"public": {"type": "boolean"},
"collaborative": {"type": "boolean"},
"description": {"type": "string"}
},
"required": ["playlist_id"],
"strict": True
}
}
}
]


Expand Down Expand Up @@ -246,5 +265,13 @@ def execute_function(self, tool_call) -> dict:
uris=args["uris"],
snapshot_id=args.get("snapshot_id")
)
elif name == "update_playlist_details":
return self.spotify_helpers.update_playlist_details(
playlist_id=args["playlist_id"],
name=args.get("name"),
public=args.get("public"),
collaborative=args.get("collaborative"),
description=args.get("description")
)
else:
raise ValueError(f"Unknown function: {name}")
20 changes: 20 additions & 0 deletions spotify_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,26 @@ def remove_playlist_items_raw(self, playlist_id: str, uris: List[str], snapshot_

return response.json()

def update_playlist_details_raw(self, playlist_id: str, payload: Dict) -> Optional[Dict]:
"""
Update playlist details with raw Spotify API call.
Args:
playlist_id (str): Spotify playlist ID.
payload (Dict): JSON payload with the details to update.
Returns:
Optional[Dict]: API response.
"""
url = f'{self.base_url}/playlists/{playlist_id}'
response = requests.put(url, headers=self.headers, json=payload)

if response.status_code != 200:
logger.error(f"Failed to update playlist details. Status: {response.status_code}, Response: {response.text}")
return None

return {"status": "success"}

def get_saved_audiobooks_raw(self, limit: int = 20, offset: int = 0) -> Optional[Dict]:
"""
Get raw API response for user's saved audiobooks.
Expand Down
35 changes: 35 additions & 0 deletions spotify_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,41 @@ def remove_playlist_items(self, playlist_id: str, uris: List[str], snapshot_id:
'status': 'success',
'items_removed': len(uris)
}

def update_playlist_details(self, playlist_id: str, name: Optional[str] = None,
public: Optional[bool] = None, collaborative: Optional[bool] = None,
description: Optional[str] = None) -> Optional[Dict]:
"""
Update playlist details.
Args:
playlist_id (str): Spotify playlist ID.
name (Optional[str]): New playlist name.
public (Optional[bool]): Public/private status.
collaborative (Optional[bool]): Collaborative status.
description (Optional[str]): New playlist description.
Returns:
Optional[Dict]: API response or None if failed.
"""
payload = {}
if name is not None:
payload['name'] = name
if public is not None:
payload['public'] = public
if collaborative is not None:
payload['collaborative'] = collaborative
if description is not None:
payload['description'] = description

result = self.client.update_playlist_details_raw(playlist_id, payload)
if not result:
return None

return {
"status": "success",
"message": f"Playlist {playlist_id} updated successfully."
}


@staticmethod
Expand Down

0 comments on commit 1a43764

Please sign in to comment.