python-tidal
python-tidal copied to clipboard
Is there anyway to modify playlists?
Not right now, shouldn't be too difficult to add it though.
Following on this, is there any way to add a playlist to a user? Or duplicate it?
Here is a short script for the time in between the versions that shows how to edit playlists. Create a playlist, add a song, delete the song and delete the playlist again. Should also work with multiple songs.
import tidalapi
from time import sleep
session = tidalapi.Session()
uname = "[email protected]"
pw="password"
try:
session.login(uname,pw)
except:
print("Couldn't login to Tidal!")
sleep(3)
exit()
uid = session.user.id
# Create new playlist
result = session.request('POST','users/%s/playlists' % uid ,data={'title': 'testauto'})
print(result)
# Get playlist name
playlists = session.get_user_playlists(uid)
for i,ps in enumerate(playlists,1):
print("[" +str(i)+ "] "+ps.name)
selection1 = int(input("Wähle Playlist Nummer : "))-1
playlist_id = playlists[selection1].id
print(playlist_id)
# Add Tracks to playlist
track_id_list = ["33500418"]
to_index = 0
etag = session.request('GET','playlists/%s' % playlist_id).headers['ETag']
headers = {'if-none-match' : etag}
data = {
'trackIds' : ",".join(track_id_list),
'toIndex' : to_index
}
result = session.request('POST', 'playlists/%s/tracks' % playlist_id, data = data ,headers = headers)
sleep(10)
# Delete track from Playlist
track_index_list=["0"]
etag = session.request('GET','playlists/%s/tracks' % playlist_id).headers['ETag']
headers = {'if-none-match' : etag}
track_index_string = ",".join(track_index_list)
result = session.request('DELETE','playlists/%s/tracks/%s'%(playlist_id,track_index_string),headers=headers)
# Delete Playlist
etag = session.request('GET','playlists/%s' % playlist_id).headers['ETag']
headers = {'if-none-match' : etag}
result = session.request('DELETE', 'playlists/%s' % playlist_id, headers = headers)
print( result )
Thanks @Husky22 for this! Was hoping for a more API-ish way to do this, but I guess meanwhile this can work too.
Well I was working on integrating it into the api but as long as 0.7 isn't available I don't mind finishing it. But it's actually straight forward to integrate it into tidalapi. If it helps you i can update my fork tomorrow to provide you a more API-ish experience.
Please don't do this just for me 😅 I'll use the the above code example you posted and wait patiently for the 0.7 release. Thank you!
Hi, could you execute code for adding songs to a playlist? I'm trying it but it doesn't work for me...
EDIT: oops! now I found the problem!
The session.request()
method doesn't have the headers
parameter, but I just had to add it and pass it to the requests.request()
call inside it. Now it works! 👏
By the way, how did you discover these endpoints? :)
You can ignore the rest of this message.
I was getting this error:
TypeError: request() got an unexpected keyword argument 'headers'
If I removed the headers
argument I got:
requests.exceptions.HTTPError: 412 Client Error: Precondition Failed for url
I took inspiration from the C# Tidal API OpenTidl. But how to get to these endpoints in general, I don't really know. The Node.js TidalAPI gives some hints on how to decrypt HTTPS traffic with Fiddler: https://github.com/lucaslg26/TidalAPI#obtain-the-tidal-token-needed-to-use-this-api I think this would be the way by observing the traffic of the original tidal app.
Thank you @Husky22 !
By the way, I implemented that method to add tracks to a playlist. I also fixed the Favorites.playlists()
because it doesn't work. Maybe they removed that alternative path in /favorites
, so maybe you just want to remove that method from Favorites
.
Does it make sense to make a pull request? When do you think you're going to release the 0.7 version?
Not very certain about when it will be released, but hopefully within the next months, so i think people can wait. I don't want to spend time looking at a pull request when it's just going to get removed either way. If you add tests so i can just git pull and run the tests i guess you can submit a PR, but i don't think it's worth the time for you either.
Here's the script I used to add these methods. Serves my purposes for the moment; hope it helps.
class FavoritesExtended(Favorites):
def add_playlist(self, playlist_name: str) -> str:
url = (
"https://listen.tidal.com/v1/users/"
+ str(self._session.user.id)
+ "/playlists"
)
r = requests.post(
url,
data={"title": playlist_name, "description": ""},
headers={"x-tidal-sessionid": self._session.session_id},
)
r.raise_for_status()
return r.json()["uuid"]
def add_track_to_playlist(self, playlist_id: str, track_id: str) -> Response:
url = urljoin(
self._session._config.api_location, "playlists/%s/tracks" % playlist_id
)
return requests.request(
"POST",
url,
data={"trackIds": track_id, "toIndex": 1},
headers={
"x-tidal-sessionid": self._session.session_id,
"if-none-match": "*",
},
params={
"sessionId": self._session.session_id,
"countryCode": self._session.country_code,
"limit": "999",
},
)
def _remove_playlist(self, playlist_id: str) -> Response:
playlist_url = "https://listen.tidal.com/v1/playlists/" + playlist_id
return requests.delete(
playlist_url, headers={"x-tidal-sessionid": self._session.session_id}
)