Skip to content

Get home page using updated endpoint (Fixes #324) #352

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

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions tidalapi/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
from tidalapi.request import Requests
from tidalapi.session import Session

from . import album, artist, media, mix, playlist

PageCategories = Union[
"Album",
"PageLinks",
Expand All @@ -68,13 +70,15 @@ class Page:
_categories_iter: Optional[Iterator["AllCategories"]] = None
_items_iter: Optional[Iterator[Callable[..., Any]]] = None
page_category: "PageCategory"
page_category_v2: "PageCategoryV2"
request: "Requests"

def __init__(self, session: "Session", title: str):
self.request = session.request
self.categories = None
self.title = title
self.page_category = PageCategory(session)
self.page_category_v2 = PageCategoryV2(session)

def __iter__(self) -> "Page":
if self.categories is None:
Expand Down Expand Up @@ -114,6 +118,14 @@ def parse(self, json_obj: JsonObj) -> "Page":

return copy.copy(self)

def parseV2(self, json_obj: JsonObj) -> "Page":
self.categories = []
for item in json_obj["items"]:
page_item = self.page_category_v2.parse(item)
self.categories.append(page_item)

return copy.copy(self)

def get(self, endpoint: str, params: Optional[Dict[str, Any]] = None) -> "Page":
"""Retrieve a page from the specified endpoint, overwrites the calling page.

Expand Down Expand Up @@ -168,6 +180,7 @@ def __init__(self, session: "Session"):
def parse(self, json_obj: JsonObj) -> AllCategories:
result = None
category_type = json_obj["type"]
print(category_type)
if category_type in ("PAGE_LINKS_CLOUD", "PAGE_LINKS"):
category: PageCategories = PageLinks(self.session)
elif category_type in ("FEATURED_PROMOTIONS", "MULTIPLE_TOP_PROMOTIONS"):
Expand Down Expand Up @@ -215,6 +228,82 @@ def show_more(self) -> Optional[Page]:
)


class PageCategoryV2:
type = None
title: Optional[str] = None
description: Optional[str] = ""
request: "Requests"

def __init__(self, session: "Session"):
self.session = session
self.request = session.request

def parse(self, json_obj: JsonObj) -> AllCategories:
category_type = json_obj["type"]
print(category_type)
if category_type == "TRACK_LIST":
category = TrackList(self.session)
elif category_type == "SHORTCUT_LIST":
category = ShortcutList(self.session)
elif category_type == "HORIZONTAL_LIST":
category = HorizontalList(self.session)
else:
raise NotImplementedError(f"PageType {category_type} not implemented")

return category.parse(json_obj)


class SimpleList(PageCategory):
"""A simple list of different items for the home page V2"""

items: Optional[List[Any]] = None

def __init__(self, session: "Session"):
super().__init__(session)
self.session = session

def parse(self, json_obj: JsonObj) -> "SimpleList":
self.items = []
self.title = json_obj["title"]

for item in json_obj["items"]:
self.items.append(self.get_item(item))

return self

def get_item(self, json_obj):
item_type = json_obj["type"]
# item_data = json_obj["data"]

print(item_type)

try:
if item_type == "PLAYLIST":
return self.session.parse_playlist(json_obj)
elif item_type == "VIDEO":
return self.session.parse_video(json_obj["data"])
elif item_type == "TRACK":
return self.session.parse_track(json_obj["data"])
elif item_type == "ARTIST":
return self.session.parse_artist(json_obj["data"])
elif item_type == "ALBUM":
return self.session.parse_album(json_obj["data"])
# elif item_type == "MIX":
# return self.session.mix(json_obj["data"]["id"])
except Exception as e:
print(e)
# raise NotImplementedError
return None


class HorizontalList(SimpleList):
...


class ShortcutList(SimpleList):
...


class FeaturedItems(PageCategory):
"""Items that have been featured by TIDAL."""

Expand Down Expand Up @@ -293,6 +382,27 @@ def parse(self, json_obj: JsonObj) -> "ItemList":
return copy.copy(self)


class TrackList(PageCategory):
"""A list of track from TIDAL."""

items: Optional[List[Any]] = None

def parse(self, json_obj: JsonObj) -> "TrackList":
"""Parse a list of tracks on TIDAL from the pages endpoints.

:param json_obj: The json from TIDAL to be parsed
:return: A copy of the TrackList with a list of items
"""
self.title = json_obj["title"]

self.items = []

for item in json_obj["items"]:
self.items.append(self.session.parse_track(item["data"]))

return copy.copy(self)


class PageLink:
"""A Link to another :class:`.Page` on TIDAL, Call get() to retrieve the Page."""

Expand Down
2 changes: 2 additions & 0 deletions tidalapi/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ def basic_request(
if not headers:
headers = {}

headers["x-tidal-client-version"] = "2025.7.16"

if "User-Agent" not in headers:
headers["User-Agent"] = self.user_agent

Expand Down
14 changes: 13 additions & 1 deletion tidalapi/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -1094,7 +1094,19 @@ def home(self) -> page.Page:

:return: A :class:`.Page` object with the :class:`.PageCategory` list from the home page
"""
return self.page.get("pages/home")
params = {}
params["deviceType"] = "BROWSER"
params["countryCode"] = "IT"
params["locale"] = "en_US"
params["platform"] = "WEB"

json_obj = self.request.request(
"GET",
"home/feed/static",
base_url=self.config.api_v2_location,
params=params,
).json()
return self.page.parseV2(json_obj)

def explore(self) -> page.Page:
"""
Expand Down
Loading