Skip to content

Commit c412d7c

Browse files
apastelsigma67
andauthored
Implement get_account_info() to get authenticated user's account info (sigma67#556) (sigma67#557)
* implement get_account_info to provide information about the authenticated user's account (sigma67#556) * Apply suggestions from code review to tests/README.rst Co-authored-by: sigma67 <[email protected]> * simplify get_account_info by moving code out of parsers.py and navigation.py * test with non-auth account * format * update .pre-commit-config.yaml --------- Co-authored-by: sigma67 <[email protected]> Co-authored-by: sigma67 <[email protected]>
1 parent 13701c4 commit c412d7c

File tree

6 files changed

+60
-1
lines changed

6 files changed

+60
-1
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
33
# Ruff version.
4-
rev: v0.2.0
4+
rev: v0.3.0
55
hooks:
66
# Run the linter.
77
- id: ruff

docs/source/reference.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Library
6161
.. automethod:: YTMusic.rate_playlist
6262
.. automethod:: YTMusic.subscribe_artists
6363
.. automethod:: YTMusic.unsubscribe_artists
64+
.. automethod:: YTMusic.get_account_info
6465

6566
Playlists
6667
---------

tests/README.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ The entry descriptions should be self-explanatory.
2424
For the headers_raw, you need to indent the overflowing lines with a tab character. For the upload test you need a suitable music file in the test directory.
2525
Adjust the file to contain appropriate information for your YouTube account and local setup.
2626

27+
``account_name`` and ``channel_handle`` for test.cfg can be obtained by visiting either YouTube or YouTube Music and
28+
clicking your profile picture icon in the top right while signed in with your test account.
29+
2730
Brand accounts can be created by first signing into the google account you wish to have as the parent/controlling
2831
account then navigating `here. <https://www.youtube.com/create_channel?action_create_new_channel_redirect=true>`_
2932

tests/mixins/test_library.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from urllib.parse import urlparse
2+
13
import pytest
24

35

@@ -109,3 +111,12 @@ def test_rate_playlist(self, yt_auth):
109111
def test_subscribe_artists(self, yt_auth):
110112
yt_auth.subscribe_artists(["UCUDVBtnOQi4c7E8jebpjc9Q"])
111113
yt_auth.unsubscribe_artists(["UCUDVBtnOQi4c7E8jebpjc9Q"])
114+
115+
def test_get_account_info(self, config, yt, yt_oauth):
116+
with pytest.raises(Exception, match="Please provide authentication"):
117+
yt.get_account_info()
118+
119+
account_info = yt_oauth.get_account_info()
120+
assert account_info["accountName"] == config.get("auth", "account_name")
121+
assert account_info["channelHandle"] == config.get("auth", "channel_handle")
122+
assert bool(urlparse(account_info["accountPhotoUrl"]))

tests/test.example.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
[auth]
22
brand_account = 101234229123420379537
33
brand_account_empty = 1123456629123420379537
4+
account_name = Sample Account
5+
channel_handle = @SampleAccount
46
headers = headers_auth_json_as_string
57
headers_empty = headers_account_with_empty_library_as_json_as_string
68
browser_file = ./browser.json

ytmusicapi/mixins/library.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,3 +324,45 @@ def unsubscribe_artists(self, channelIds: List[str]) -> Dict:
324324
body = {"channelIds": channelIds}
325325
endpoint = "subscription/unsubscribe"
326326
return self._send_request(endpoint, body)
327+
328+
def get_account_info(self) -> Dict:
329+
"""
330+
Gets information about the currently authenticated user's account.
331+
332+
:return: Dictionary with user's account name, channel handle, and URL of their account photo.
333+
334+
Example::
335+
336+
{
337+
"accountName": "Sample User",
338+
"channelHandle": "@SampleUser
339+
"accountPhotoUrl": "https://yt3.ggpht.com/sample-user-photo"
340+
}
341+
"""
342+
self._check_auth()
343+
endpoint = "account/account_menu"
344+
response = self._send_request(endpoint, {})
345+
346+
ACCOUNT_INFO = [
347+
"actions",
348+
0,
349+
"openPopupAction",
350+
"popup",
351+
"multiPageMenuRenderer",
352+
"header",
353+
"activeAccountHeaderRenderer",
354+
]
355+
ACCOUNT_RUNS_TEXT = ["runs", 0, "text"]
356+
ACCOUNT_NAME = [*ACCOUNT_INFO, "accountName", *ACCOUNT_RUNS_TEXT]
357+
ACCOUNT_CHANNEL_HANDLE = [*ACCOUNT_INFO, "channelHandle", *ACCOUNT_RUNS_TEXT]
358+
ACCOUNT_PHOTO_URL = [*ACCOUNT_INFO, "accountPhoto", "thumbnails", 0, "url"]
359+
360+
account_name = nav(response, ACCOUNT_NAME)
361+
channel_handle = nav(response, ACCOUNT_CHANNEL_HANDLE)
362+
account_photo_url = nav(response, ACCOUNT_PHOTO_URL)
363+
364+
return {
365+
"accountName": account_name,
366+
"channelHandle": channel_handle,
367+
"accountPhotoUrl": account_photo_url,
368+
}

0 commit comments

Comments
 (0)