mirror of
https://github.com/sigma67/ytmusicapi.git
synced 2026-04-25 15:26:01 +03:00
[GH-ISSUE #703] yt.add_history_item() fails silently #457
Labels
No labels
a/b
bug
documentation
enhancement
good first issue
help wanted
invalid
pull-request
question
wontfix
yt-error
yt-update
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/ytmusicapi#457
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Batwam on GitHub (Dec 26, 2024).
Original GitHub issue: https://github.com/sigma67/ytmusicapi/issues/703
Describe the bug
I have a script which runs automatically in the background and sends my play history to yt music using ytmusicapi (to improve the quality of my music recommendations). I recently lost authentication (solved now) and being set up to check for 204 response, my script didn't return any error, so, it took me 5 days to realise that it was broken.
Turns out that yt.add_history_item() appears to return Response [204] in cases the request fails. In fact, I don't think that I ever got anything else than 204. This might be due to YT Music return success status regardless of the query but it would be good to flag this to the user.
My solution currently is to wait a few seconds and check the videoId of the last history item to make sure it is matching but ideally the Response would be sufficient or there would be some built-in check to at least make sure add_history_item() is done through an authenticated session (like what is done when adding items to playlists I believe).
As an added secondary observation/bug I noticed that the history is only updated if get_song() is obtained also using an authenticated session. I'm not sure why this is the case as I would have thought that it's the same song regardless. Just putting it out there too (see test case #2)
To Reproduce
Run this test script:
Script Result
@Batwam commented on GitHub (Dec 27, 2024):
I compared the anonymous and authenticated results for get_song() and they are indeed different in quite a few areas. I'm not sure why but either way, the non-authenticated result doesn't work when trying to use it with add_history_item so, that's good to know I guess.
@ImpenetrableNoble commented on GitHub (Dec 27, 2024):
@Batwam The issue with
yt.add_history_item()always returns a204response sometimes so I can agree, even when the request fails, it can be addressed by manually verifying if the item was added to the history by fetching the last history item and comparing itsvideoId, or by explicitly checking if the session is authenticated before making the call, and if the library lacks proper error handling, consider wrapping the call in a try-except block or raising a feature request for improved response handling.Especially the observation that history only updates when
get_song()is called with an authenticated session suggests that YouTube Music tracks user-specific metadata differently when authenticated, so ensureget_song()is always called with an authenticated session, and if this behavior is unintuitive, consider raising an issue with the library maintainers for clarification or fixes.Try it out yourself, until the developer update a fix for it.
@Batwam commented on GitHub (Dec 27, 2024):
Yeah, I already successfully implemented all these checks, that's why I mentioned them above and also included the 5s delay before checking the history (without the delay, it doesn't have sufficient time to update). I'm also now checking authentication by making sure there is a handle by using get_info().
My aim here is mostly to share/flag this in case we believe that it should get picked up automatically to save other people having to do the troubleshooting I just did, especially since this doesn't appear to be captured in the documentation
For instance, I'm not sure at what level it's getting picked up but I'm pretty sure that you'd get an error if you tried to submit a playlist item without being authenticated.
@ImpenetrableNoble commented on GitHub (Dec 27, 2024):
@Batwam The documentation should include a note about the authentication requirement and suggest using
get_info()or similar methods to verify authentication beforehand.Otherwise, the library will just seem unreliable or buggy.
The library should be updated to explicitly check for authentication before attempting to add a history item and raise a clear error if any user isn’t authenticated.
@sigma67 commented on GitHub (Dec 27, 2024):
@Batwam this is not really a bug. I don't know why you'd use different sessions for both calls. I agree that the guard
check_authshould be added toadd_history_item. PR welcome@ImpenetrableNoble get out of here with your "AI" generated nonsense
@Batwam commented on GitHub (Dec 27, 2024):
@sigma67 The reason for the unauthenticated search isn't obvious in this short example but came up in my scrobbling script code and this is something I was going to raise separately.
Basically to do my yt scrobbling, I'm pulling the history from LastFM, doing a
yt.search(song)to figure out the videoId and then a searchget_song(videoId), then passing the result to add_playlist_item. The problem I found with doing an authorised search song is that it fills my search bar with all the searches made by the script.I then realised that the search doesn't need to be authenticated so I started doing unauthenticated
search()which did what I wanted (gets me the same result but doesn't fill my search history)andget_song(), followed by an authenticatedadd_history_item. This gave me response 204 but actually didn't update the history (case 2 above). That's when I realised that I also had to authenticated get_song() which is why I shared case 2 above.Essentially the unauthenticated search is so it doesn't fill the yt music search history. It's not a massive issue but I would ideally suggest to either make this unauthenticated search an option within search() or perhaps make the search unauthenticated by default as the results are the same but it doesn't "pollute" the search history.
It works fine the way I'm doing it with the 2 instances so that's doesn't bother me but let me know if you see any value in this idea and I can document it separately as a feature request.
@sigma67 commented on GitHub (Dec 28, 2024):
That's not really an option. It makes sense for your use case but the solution with two instances is sufficient. It would be confusing to anyone else.
It would be a good idea to document the fact that
searchhas the side effect of adding history items in thesearchdocumentation. You can always remove them again withremove_history_items@Batwam commented on GitHub (Dec 28, 2024):
No problem, as you said, it's relatively easy to work around but probably worth documenting.