-
Notifications
You must be signed in to change notification settings - Fork 216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Authentication refactor #488
Conversation
…formance increase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jcbirdwell , thanks so much for contributing this back. Glad to accept this contribution with a few changes.
Please also add documentation in the Setup section (new chapter in Oauth section). How could one obtain such custom credentials?
Requesting a review from @MarvinSchenkel who contributed #396
I will wait for these changes before running the tests myself, I assume you have done so on your machine
ytmusicapi/mixins/explore.py
Outdated
has_genres = country == 'US' | ||
has_trending = country != 'ZZ' | ||
# songs section appears to no longer exist, extra length check avoids |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose the previous check was too simple since you'd actually need to check for a premium subscriber instead of a just a logged-in user. Should probably add a separate account to the tests that is authenticated but not subscribed
So I think we can just remove the bool(self.auth)
part altogether since it does not actually make a difference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was indeed performing all tests using non-premium accounts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we can remove bool(self.auth) and
?
I ended up going with a mix of my original issue solution alternative 2 and the dataclass implementation mentioned previously. While I was adding a credential dataclass I was reminded of why I was originally trying to pass the YTMusicOAuth instance from YTMusic, it was to prevent recreating the OAuth class on every single request. I believe the original intent was to ensure that the authorization field of the header was always up-to-date, this version accomplishes that but instead of rebuilding all the headers each time it just does authorization/ones that update. It also catches #492 in the crossfire and I believe the issue @heisen273 was having with mixins, but I couldn't replicate it so I'm unsure. It's a decent chunk of changes, but should act as a drop-in replacement. I added custom oauth handling and believe it maintains compatibility with #396, but I don't think there is a test for it. I haven't written any of the docs or additional feature tests yet as I wanted to get feedback before tackling em, but I'm getting a full pass for existing tests. In light of that, I'd convert the pull request to a draft, but I'm not positive what that does and don't want to mess anything up. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this second changeset was needed based on what you wanted to achieve. But I like the improvements in general, so let's try to make it work.
I have a very hard time verifying that everything is still working, considering that 18 tests are breaking for me locally even after updating the test.cfg (those changes are quite welcome, thanks).
I suspect most failures have the same origin, some sort of (breaking?) change to the local oauth.json file that I have on my machine. I have attached my test log, maybe you can point out what's wrong.
tests.log
I will also state here that this MR should be free of any breaking changes to the public facing API.
Don't worry about draft mode, it has no effect in this repo (since we're currently not running tests on PRs due to somewhat sensitive nature of the credentials)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message has changed slightly, but I'm still getting this:
======================================================================
ERROR: test_search_library (test.TestYTMusic.test_search_library)
----------------------------------------------------------------------
Traceback (most recent call last):
File "\ytmusicapi\tests\test.py", line 164, in test_search_library
results = self.yt_oauth.search(config['queries']['library_any'], scope="library")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "\ytmusicapi\ytmusicapi\mixins\search.py", line 165, in search
response = self._send_request(endpoint, body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "\ytmusicapi\ytmusicapi\ytmusic.py", line 200, in _send_request
if 'X-Goog-Visitor-Id' not in self.headers:
^^^^^^^^^^^^
File "\ytmusicapi\ytmusicapi\ytmusic.py", line 191, in headers
self._headers['authorization'] = self._token.as_auth()
^^^^^^^^^^^^^^^^^^^^^
File "\ytmusicapi\ytmusicapi\auth\oauth.py", line 85, in as_auth
return f'{self.token_type} {self.access_token}'
^^^^^^^^^^^^^^^^^
File "\ytmusicapi\ytmusicapi\auth\oauth.py", line 178, in access_token
self.token = self.credentials.refresh_token(self.token.refresh_token)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "\ytmusicapi\ytmusicapi\auth\oauth.py", line 141, in refresh_token
return OAuthToken.from_response(response)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "\ytmusicapi\ytmusicapi\auth\oauth.py", line 30, in from_response
return cls(**data)
^^^^^^^^^^^
TypeError: OAuthToken.__init__() missing 1 required positional argument: 'refresh_token'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for all the comments, I'd consider this to be the final review hopefully.
Tests are passing for me.
This one's come a long way and I think it's in a great state now.
Really need to add a proper linter like ruff and some sort of basic no-oauth PR pipeline...
ytmusicapi/mixins/explore.py
Outdated
has_genres = country == 'US' | ||
has_trending = country != 'ZZ' | ||
# songs section appears to no longer exist, extra length check avoids |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we can remove bool(self.auth) and
?
|
||
@property | ||
def token_type(self): | ||
return self.token.token_type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l.51 through l. 73 can be removed as they are not used anywhere, unless I'm missing something
Perhaps a leftover from the refactor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this has not been resolved
@@ -16,7 +17,7 @@ | |||
from ytmusicapi.mixins.library import LibraryMixin | |||
from ytmusicapi.mixins.playlists import PlaylistsMixin | |||
from ytmusicapi.mixins.uploads import UploadsMixin | |||
from ytmusicapi.auth.oauth import YTMusicOAuth, is_oauth | |||
from ytmusicapi.auth.oauth import OAuthCredentials, is_oauth, RefreshingToken, OAuthToken | |||
|
|||
|
|||
class YTMusic(BrowsingMixin, SearchMixin, WatchMixin, ExploreMixin, LibraryMixin, PlaylistsMixin, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to this line, but please add/update documentation in docs/source/setup
I really appreciate all the continued feedback on this PR and I'm satisfied with the direction we indeed up taking as a result. I'll be busy for the next few days, but it shouldn't take long to wrap up the final stuff when I can get back on it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for these changes again. It would be great if you could turn all the comments into proper docstrings (most of the comments I added are just todo items regarding this):
https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#directive-autoproperty
See the class example here for properly documenting instance variables.
You can use either style - just add a colon to the current comments or place them in the line above with #:
(the latter is my preferred style)
Other than that there is only one finding left regarding a try-catch you added
Hi @jcbirdwell , I fixed the remaining issues & merged. Feel free to add the documentation in a separate PR |
This is the implementation of #487. It also fixes some issues I ran across while writing the tests for my proposed feature that were preventing a full pass. I can open issues for each or all together if needed, just let me know. Otherwise, they were: