Source code for minim.api.tidal._api.albums

from __future__ import annotations
from typing import TYPE_CHECKING

from ...._types import COLLECTION_TYPES, ORDERED_COLLECTION_TYPES
from ..._shared import TTLCache, _copy_docstring
from ._shared import TIDALResourceAPI
from .search import SearchAPI
from .users import UsersAPI

if TYPE_CHECKING:
    from typing import Any

    from ...._types import Collection


[docs] class AlbumsAPI(TIDALResourceAPI): """ Albums API endpoints for the TIDAL API. .. important:: This class is managed by :class:`~minim.api.tidal.TIDALAPIClient` and should not be instantiated directly. """ _RELATIONSHIPS = { "albumStatistics", "artists", "coverArt", "genres", "items", "owners", "priceConfig", "providers", "replacement", "shares", "similarAlbums", "suggestedCoverArts", "usageRules", } _SORT_FIELDS = {"createdAt", "title"} __slots__ = ()
[docs] @TTLCache.cached_method(ttl="popularity") def get_albums( self, album_ids: int | str | Collection[int | str] | None = None, /, *, barcodes: int | str | Collection[int | str] | None = None, owner_ids: int | str | Collection[int | str] | None = None, country_code: str | None = None, expand: str | Collection[str] | None = None, cursor: str | None = None, sort_by: str | None = None, share_code: str | None = None, ) -> dict[str, Any]: """ `Albums > Get Single Album <https://tidal-music.github.io /tidal-api-reference/#/albums/get_albums__id_>`_: Get TIDAL catalog information for an album․ `Albums > Get Multiple Albums <https://tidal-music.github.io /tidal-api-reference/#/albums/get_albums>`_: Get TIDAL catalog information for multiple albums. .. admonition:: User authentication :class: entitlement dropdown .. tab-set:: .. tab-item:: Optional User authentication Access information for a resource's owners. .. important:: Exactly one of `album_ids`, `barcodes`, or `owner_ids` must be provided. When `barcodes` or `owner_ids` is specified, the request will always be sent to the endpoint for multiple albums. Parameters ---------- album_ids : int, str, or Collection[int | str]; \ positional-only; optional TIDAL IDs of the albums. **Examples**: :code:`46369321`, :code:`"251380836"`, :code:`[46369321, "251380836"]`. barcodes : int, str, or Collection[int | str]; keyword-only; \ optional Barcodes (UPCs and/or EANs) of the albums. **Examples**: :code:`602448438034`, :code:`"075678671173"`, :code:`[602448438034, "075678671173"]` owner_ids : int, str, or Collection[int | str]; keyword-only; \ optional TIDAL IDs of the album resources' owners. If authenticated, :code:`"me"` can be used in lieu of a TIDAL ID for the current user. **Examples**: :code:"me"`, :code:`123456`, :code:`"654321"`, :code:`[123456, "654321"]`. country_code : str; keyword-only; optional ISO 3166-1 alpha-2 country code. **Example**: :code:`"US"`. expand : str or Collection[str]; keyword-only; optional Related resources to include metadata for in the response. **Valid values**: :code:`"albumStatistics"`, :code:`"artists"`, :code:`"coverArt"`, :code:`"genres"`, :code:`"items"`, :code:`"owners"`, :code:`"priceConfig"`, :code:`"providers"`, :code:`"replacement"`, :code:`"shares"`, :code:`"similarAlbums"`, :code:`"suggestedCoverArts"`, :code:`"usageRules"`. **Examples**: :code:`"coverArt"`, :code:`["artists", "items"]`. cursor : str; keyword-only; optional Cursor for fetching the next page of results when retrieving multiple albums. **Example**: :code:`"3nI1Esi"`. sort_by : str; keyword-only; optional Field to sort the albums by. **Valid values**: :code:`"createdAt"`, :code:`"title"`. share_code : str; keyword-only; optional Share code that grants access to unlisted resources. Returns ------- albums : dict[str, Any] TIDAL metadata for the albums. .. admonition:: Sample responses :class: response dropdown .. tab-set:: .. tab-item:: Single album .. code-block:: { "data": { "attributes": { "accessType": <str>, "availability": <list[str]>, "barcodeId": <str>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "mediaTags": <list[str]>, "numberOfItems": <int>, "numberOfVolumes": <int>, "popularity": <float>, "releaseDate": <str>, "title": <str>, "type": "ALBUM" }, "id": <str>, "relationships": { "artists": { "data": [ { "id": <str>, "type": "artists" } ], "links": { "self": <str> } }, "coverArt": { "data": [ { "id": <str>, "type": "artworks" } ], "links": { "self": <str> } }, "genres": { "links": { "self": <str> } }, "items": { "data": [ { "id": <str>, "meta": { "trackNumber": <int>, "volumeNumber": <int> }, "type": "tracks" }, { "id": <str>, "meta": { "trackNumber": <int>, "volumeNumber": <int> }, "type": "videos" } ], "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "providers": { "data": [ { "id": <str>, "type": "providers" } ], "links": { "self": <str> } }, "similarAlbums": { "data": [ { "id": <str>, "type": "albums" } ], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } }, "suggestedCoverArts" : { "links": { "self": <str> } } }, "type": "albums" }, "included": [ { "attributes": { "accessType": <str>, "availability": <list[str]>, "barcodeId": <str>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "mediaTags": <list[str]>, "numberOfItems": <int>, "numberOfVolumes": <int>, "popularity": <float>, "releaseDate": <str>, "title": <str>, "type": "ALBUM" }, "id": <str>, "relationships": { "artists": { "links": { "self": <str> } }, "coverArt": { "links": { "self": <str> } }, "genres": { "links": { "self": <str> } }, "items": { "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "providers": { "links": { "self": <str> } }, "similarAlbums": { "links": { "self": <str> } }, "suggestedCoverArts" : { "links": { "self": <str> } } }, "type": "albums" }, { "attributes": { "contributionsEnabled": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "name": <str>, "popularity": <float>, "spotlighted": <bool> }, "id": <str>, "relationships": { "albums": { "links": { "self": <str> } }, "biography": { "links": { "self": <str> } }, "followers": { "links": { "self": <str> } }, "following": { "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "profileArt": { "links": { "self": <str> } }, "radio": { "links": { "self": <str> } }, "roles": { "links": { "self": <str> } }, "similarArtists": { "links": { "self": <str> } }, "trackProviders": { "links": { "self": <str> } }, "tracks": { "links": { "self": <str> } }, "videos": { "links": { "self": <str> } } }, "type": "artists" }, { "attributes": { "files": [ { "href": <str>, "meta": { "height": <int>, "width": <int> } } ], "mediaType": "IMAGE" }, "id": <str>, "relationships": { "owners": { "links": { "self": <str> } } }, "type": "artworks" }, { "attributes": { "name": <str> }, "id": <str>, "type": "providers" }, { "attributes": { "accessType": <str>, "availability": <list[str]>, "bpm": <float>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "isrc": <str>, "key": <str>, "keyScale": <str>, "mediaTags": <list[str]>, "popularity": <float>, "spotlighted": <bool>, "title": <str>, "toneTags": <list[str]>, "version": <str> }, "id": <str>, "relationships": { "albums": { "links": { "self": <str> } }, "artists": { "links": { "self": <str> } }, "genres": { "links": { "self": <str> } }, "lyrics": { "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "providers": { "links": { "self": <str> } }, "radio": { "links": { "self": <str> } }, "shares": { "links": { "self": <str> } }, "similarTracks": { "links": { "self": <str> } }, "sourceFile": { "links": { "self": <str> } }, "trackStatistics": { "links": { "self": <str> } } }, "type": "tracks" }, { "attributes": { "availability": <list[str]>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "isrc": <str>, "popularity": <float>, "releaseDate": <str>, "title": <str> }, "id": <str>, "relationships": { "albums": { "links": { "self": <str> } }, "artists": { "links": { "self": <str> } }, "providers": { "links": { "self": <str> } }, "thumbnailArt": { "links": { "self": <str> } } }, "type": "videos" } ], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } } .. tab-item:: Multiple albums .. code-block:: { "data": [ { "attributes": { "accessType": <str>, "availability": <list[str]>, "barcodeId": <str>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "mediaTags": <list[str]>, "numberOfItems": <int>, "numberOfVolumes": <int>, "popularity": <float>, "releaseDate": <str>, "title": <str>, "type": "ALBUM" }, "id": <str>, "relationships": { "artists": { "data": [ { "id": <str>, "type": "artists" } ], "links": { "self": <str> } }, "coverArt": { "data": [ { "id": <str>, "type": "artworks" } ], "links": { "self": <str> } }, "genres": { "links": { "self": <str> } }, "items": { "data": [ { "id": <str>, "meta": { "trackNumber": <int>, "volumeNumber": <int> }, "type": "tracks" }, { "id": <str>, "meta": { "trackNumber": <int>, "volumeNumber": <int> }, "type": "videos" } ], "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "providers": { "data": [ { "id": <str>, "type": "providers" } ], "links": { "self": <str> } }, "similarAlbums": { "data": [ { "id": <str>, "type": "albums" } ], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } }, "suggestedCoverArts" : { "links": { "self": <str> } } }, "type": "albums" } ], "included": [ { "attributes": { "accessType": <str>, "availability": <list[str]>, "barcodeId": <str>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "mediaTags": <list[str]>, "numberOfItems": <int>, "numberOfVolumes": <int>, "popularity": <float>, "releaseDate": <str>, "title": <str>, "type": "ALBUM" }, "id": <str>, "relationships": { "artists": { "links": { "self": <str> } }, "coverArt": { "links": { "self": <str> } }, "genres": { "links": { "self": <str> } }, "items": { "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "providers": { "links": { "self": <str> } }, "similarAlbums": { "links": { "self": <str> } }, "suggestedCoverArts" : { "links": { "self": <str> } } }, "type": "albums" }, { "attributes": { "contributionsEnabled": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "name": <str>, "popularity": <float>, "spotlighted": <bool> }, "id": <str>, "relationships": { "albums": { "links": { "self": <str> } }, "biography": { "links": { "self": <str> } }, "followers": { "links": { "self": <str> } }, "following": { "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "profileArt": { "links": { "self": <str> } }, "radio": { "links": { "self": <str> } }, "roles": { "links": { "self": <str> } }, "similarArtists": { "links": { "self": <str> } }, "trackProviders": { "links": { "self": <str> } }, "tracks": { "links": { "self": <str> } }, "videos": { "links": { "self": <str> } } }, "type": "artists" }, { "attributes": { "files": [ { "href": <str>, "meta": { "height": <int>, "width": <int> } } ], "mediaType": "IMAGE" }, "id": <str>, "relationships": { "owners": { "links": { "self": <str> } } }, "type": "artworks" }, { "attributes": { "name": <str> }, "id": <str>, "type": "providers" }, { "attributes": { "accessType": <str>, "availability": <list[str]>, "bpm": <float>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "isrc": <str>, "key": <str>, "keyScale": <str>, "mediaTags": <list[str]>, "popularity": <float>, "spotlighted": <bool>, "title": <str>, "toneTags": <list[str]>, "version": <str> }, "id": <str>, "relationships": { "albums": { "links": { "self": <str> } }, "artists": { "links": { "self": <str> } }, "genres": { "links": { "self": <str> } }, "lyrics": { "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "providers": { "links": { "self": <str> } }, "radio": { "links": { "self": <str> } }, "shares": { "links": { "self": <str> } }, "similarTracks": { "links": { "self": <str> } }, "sourceFile": { "links": { "self": <str> } }, "trackStatistics": { "links": { "self": <str> } } }, "type": "tracks" }, { "attributes": { "availability": <list[str]>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "isrc": <str>, "popularity": <float>, "releaseDate": <str>, "title": <str> }, "id": <str>, "relationships": { "albums": { "links": { "self": <str> } }, "artists": { "links": { "self": <str> } }, "providers": { "links": { "self": <str> } }, "thumbnailArt": { "links": { "self": <str> } } }, "type": "videos" } ], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } } """ if ( sum(arg is not None for arg in (album_ids, barcodes, owner_ids)) != 1 ): raise ValueError( "Exactly one of `album_ids`, `barcodes`, or " "`owner_ids` must be provided." ) params = {} if barcodes is not None: if isinstance(barcodes, int | str): barcodes = self._prepare_barcode(barcodes) elif isinstance(barcodes, COLLECTION_TYPES): barcodes = [ self._prepare_barcode(barcode) for barcode in barcodes ] else: raise ValueError( "`barcodes` must be an integer, a string, or a " "collection of integers and/or strings." ) params["filter[barcodeId]"] = barcodes elif owner_ids is not None: self._validate_tidal_ids(owner_ids) params["filter[owners.id]"] = ( owner_ids if isinstance(owner_ids, ORDERED_COLLECTION_TYPES) else sorted(owner_ids) ) if sort_by is not None: self._process_sort( sort_by, prefix="", sort_fields=self._SORT_FIELDS, params=params, ) return self._get_resources( "albums", album_ids, country_code=country_code, expand=expand, cursor=cursor, share_code=share_code, params=params, )
[docs] @TTLCache.cached_method(ttl="popularity") def get_album_artists( self, album_id: int | str, /, country_code: str | None = None, *, include_metadata: bool = False, cursor: str | None = None, share_code: str | None = None, ) -> dict[str, Any]: """ `Albums > Get Artists Relationship <https://tidal-music.github.io/tidal-api-reference/#/albums /get_albums__id__relationships_artists>`_: Get TIDAL catalog information for the artists of an album. Parameters ---------- album_id : int or str; positional-only TIDAL ID of the album. **Examples**: :code:`46369321`, :code:`"251380836"`. country_code : str; optional ISO 3166-1 alpha-2 country code. **Example**: :code:`"US"`. include_metadata : bool; keyword-only; default: :code:`False` Whether to include metadata for the album artists. cursor : str; keyword-only; optional Cursor for fetching the next page of results. **Example**: :code:`"3nI1Esi"`. share_code : str; keyword-only; optional Share code that grants access to unlisted resources. Returns ------- artists : dict[str, Any] Page of TIDAL metadata for the album artists. .. admonition:: Sample response :class: response dropdown .. code-block:: { "data": [ { "id": <str>, "type": "artists" } ], "included": [ { "attributes": { "contributionsEnabled": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "name": <str>, "popularity": <float>, "spotlighted": <bool> }, "id": <str>, "relationships": { "albums": { "links": { "self": <str> } }, "biography": { "links": { "self": <str> } }, "followers": { "links": { "self": <str> } }, "following": { "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "profileArt": { "links": { "self": <str> } }, "radio": { "links": { "self": <str> } }, "roles": { "links": { "self": <str> } }, "similarArtists": { "links": { "self": <str> } }, "trackProviders": { "links": { "self": <str> } }, "tracks": { "links": { "self": <str> } }, "videos": { "links": { "self": <str> } } }, "type": "artists" } ], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } } """ return self._get_resource_relationship( "albums", album_id, "artists", country_code=country_code, include_metadata=include_metadata, cursor=cursor, share_code=share_code, )
[docs] @TTLCache.cached_method(ttl="static") def get_album_cover_art( self, album_id: int | str, /, country_code: str | None = None, *, include_metadata: bool = False, cursor: str | None = None, share_code: str | None = None, ) -> dict[str, Any]: """ `Albums > Get Cover Art Relationship <https://tidal-music.github.io/tidal-api-reference/#/albums /get_albums__id__relationships_coverArt>`_: Get TIDAL catalog information for the cover art of an album. Parameters ---------- album_id : int or str; positional-only TIDAL ID of the album. **Examples**: :code:`46369321`, :code:`"251380836"`. country_code : str; optional ISO 3166-1 alpha-2 country code. **Example**: :code:`"US"`. include_metadata : bool; keyword-only; default: :code:`False` Whether to include metadata for the album cover art. cursor : str; keyword-only; optional Cursor for fetching the next page of results. **Example**: :code:`"3nI1Esi"`. share_code : str; keyword-only; optional Share code that grants access to unlisted resources. Returns ------- cover_art : dict[str, Any] Page of TIDAL metadata for the album cover art. .. admonition:: Sample response :class: response dropdown .. code-block:: { "data": [ { "id": <str>, "type": "artworks" } ], "included": [ { "attributes": { "files": [ { "href": <str>, "meta": { "height": <int>, "width": <int> } } ], "mediaType": "IMAGE" }, "id": <str>, "relationships": { "owners": { "links": { "self": <str> } } }, "type": "artworks" } ], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } } """ return self._get_resource_relationship( "albums", album_id, "coverArt", country_code=country_code, include_metadata=include_metadata, cursor=cursor, share_code=share_code, )
[docs] @TTLCache.cached_method(ttl="popularity") def get_album_items( self, album_id: int | str, /, country_code: str | None = None, *, include_metadata: bool = False, cursor: str | None = None, share_code: str | None = None, ) -> dict[str, Any]: """ `Albums > Get Items Relationship <https://tidal-music.github.io/tidal-api-reference/#/albums /get_albums__id__relationships_items>`_: Get TIDAL catalog information for tracks and videos on an album. Parameters ---------- album_id : int or str; positional-only TIDAL ID of the album. **Examples**: :code:`46369321`, :code:`"251380836"`. country_code : str; optional ISO 3166-1 alpha-2 country code. **Example**: :code:`"US"`. include_metadata : bool; keyword-only; default: :code:`False` Whether to include metadata for the album's tracks and videos. cursor : str; keyword-only; optional Cursor for fetching the next page of results. **Example**: :code:`"3nI1Esi"`. share_code : str; keyword-only; optional Share code that grants access to unlisted resources. Returns ------- items : dict[str, Any] Page of TIDAL metadata for the album's tracks and videos. .. admonition:: Sample response :class: response dropdown .. code-block:: { "data": [ { "id": <str>, "meta": { "trackNumber": <int>, "volumeNumber": <int> }, "type": "tracks" }, { "id": <str>, "meta": { "trackNumber": <int>, "volumeNumber": <int> }, "type": "videos" } ], "included": [ { "attributes": { "accessType": <str>, "availability": <list[str]>, "bpm": <float>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "isrc": <str>, "key": <str>, "keyScale": <str>, "mediaTags": <list[str]>, "popularity": <float>, "spotlighted": <bool>, "title": <str>, "toneTags": <list[str]>, "version": <str> }, "id": <str>, "relationships": { "albums": { "links": { "self": <str> } }, "artists": { "links": { "self": <str> } }, "genres": { "links": { "self": <str> } }, "lyrics": { "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "providers": { "links": { "self": <str> } }, "radio": { "links": { "self": <str> } }, "shares": { "links": { "self": <str> } }, "similarTracks": { "links": { "self": <str> } }, "sourceFile": { "links": { "self": <str> } }, "trackStatistics": { "links": { "self": <str> } } }, "type": "tracks" }, { "attributes": { "availability": <list[str]>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "isrc": <str>, "popularity": <float>, "releaseDate": <str>, "title": <str> }, "id": <str>, "relationships": { "albums": { "links": { "self": <str> } }, "artists": { "links": { "self": <str> } }, "providers": { "links": { "self": <str> } }, "thumbnailArt": { "links": { "self": <str> } } }, "type": "videos" } ], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } } """ return self._get_resource_relationship( "albums", album_id, "items", country_code=country_code, include_metadata=include_metadata, cursor=cursor, share_code=share_code, )
[docs] @TTLCache.cached_method(ttl="static") def get_album_owners( self, album_id: int | str, /, *, include_metadata: bool = False, cursor: str | None = None, share_code: str | None = None, ) -> dict[str, Any]: """ `Albums > Get Owners Relationship <https://tidal-music.github.io/tidal-api-reference/#/albums /get_albums__id__relationships_owners>`_: Get TIDAL profile information for owners of an album resource. .. admonition:: User authentication :class: entitlement dropdown .. tab-set:: .. tab-item:: Optional User authentication Access information for a resource's owners. Parameters ---------- album_id : int or str; positional-only TIDAL ID of the album. **Examples**: :code:`46369321`, :code:`"251380836"`. include_metadata : bool; keyword-only; default: :code:`False` Whether to include metadata for the owners. cursor : str; keyword-only; optional Cursor for fetching the next page of results. **Example**: :code:`"3nI1Esi"`. share_code : str; keyword-only; optional Share code that grants access to unlisted resources. Returns ------- owners : dict[str, Any] Page of TIDAL profile information for the album resource's owners. .. admonition:: Sample response :class: response dropdown .. code-block:: { "data": [], "included": [], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } } """ return self._get_resource_relationship( "albums", album_id, "owners", include_metadata=include_metadata, cursor=cursor, share_code=share_code, )
[docs] @TTLCache.cached_method(ttl="static") def get_album_providers( self, album_id: int | str, /, country_code: str | None = None, *, include_metadata: bool = False, cursor: str | None = None, share_code: str | None = None, ) -> dict[str, Any]: """ `Albums > Get Providers Relationship <https://tidal-music.github.io/tidal-api-reference/#/albums /get_albums__id__relationships_providers>`_: Get TIDAL catalog information for the providers of an album. Parameters ---------- album_id : int or str; positional-only TIDAL ID of the album. **Examples**: :code:`46369321`, :code:`"251380836"`. country_code : str; optional ISO 3166-1 alpha-2 country code. **Example**: :code:`"US"`. include_metadata : bool; keyword-only; default: :code:`False` Whether to include metadata for the album's providers. cursor : str; keyword-only; optional Cursor for fetching the next page of results. **Example**: :code:`"3nI1Esi"`. share_code : str; keyword-only; optional Share code that grants access to unlisted resources. Returns ------- providers : dict[str, Any] Page of TIDAL metadata for the album's providers. .. admonition:: Sample response :class: response dropdown .. code-block:: { "data": [ { "id": <str>, "type": <str> } ], "included": [ { "attributes": { "name": <str> }, "id": <str>, "type": <str> } ], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } } """ return self._get_resource_relationship( "albums", album_id, "providers", country_code=country_code, include_metadata=include_metadata, cursor=cursor, share_code=share_code, )
[docs] @TTLCache.cached_method(ttl="recommendation") def get_similar_albums( self, album_id: int | str, /, country_code: str | None = None, *, include_metadata: bool = False, cursor: str | None = None, share_code: str | None = None, ) -> dict[str, Any]: """ `Albums > Get Similar Albums Relationship <https://tidal-music.github.io/tidal-api-reference/#/albums /get_albums__id__relationships_similarAlbums>`_: Get TIDAL catalog information for similar albums. Parameters ---------- album_id : int or str; positional-only TIDAL ID of the album. **Examples**: :code:`46369321`, :code:`"251380836"`. country_code : str; optional ISO 3166-1 alpha-2 country code. **Example**: :code:`"US"`. include_metadata : bool; keyword-only; default: :code:`False` Whether to include metadata for the similar albums. cursor : str; keyword-only; optional Cursor for fetching the next page of results. **Example**: :code:`"3nI1Esi"`. share_code : str; keyword-only; optional Share code that grants access to unlisted resources. Returns ------- albums : dict[str, Any] Page of TIDAL metadata for the similar albums. .. admonition:: Sample response :class: response dropdown .. code-block:: { "data": [ { "id": <str>, "type": "albums" } ], "included": [ { "attributes": { "accessType": <str>, "availability": <list[str]>, "barcodeId": <str>, "copyright": { "text": <str> }, "duration": <str>, "explicit": <bool>, "externalLinks": [ { "href": <str>, "meta": { "type": <str> } } ], "mediaTags": <list[str]>, "numberOfItems": <int>, "numberOfVolumes": <int>, "popularity": <float>, "releaseDate": <str>, "title": <str>, "type": "ALBUM" }, "id": <str>, "relationships": { "artists": { "links": { "self": <str> } }, "coverArt": { "links": { "self": <str> } }, "genres": { "links": { "self": <str> } }, "items": { "links": { "self": <str> } }, "owners": { "links": { "self": <str> } }, "providers": { "links": { "self": <str> } }, "similarAlbums": { "links": { "self": <str> } }, "suggestedCoverArts" : { "links": { "self": <str> } } }, "type": "albums" } ], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } } """ return self._get_resource_relationship( "albums", album_id, "similarAlbums", country_code=country_code, include_metadata=include_metadata, cursor=cursor, share_code=share_code, )
[docs] @TTLCache.cached_method(ttl="static") def get_album_usage_rules( self, album_id: int | str, /, country_code: str | None = None, *, include_metadata: bool = False, share_code: str | None = None, ) -> dict[str, Any]: """ `Albums > Get Usage Rules Relationship <https://tidal-music.github.io/tidal-api-reference/#/albums /get_albums__id__relationships_usageRules>`_: Get TIDAL catalog information for the usage rules for an album. Parameters ---------- album_id : int or str; positional-only TIDAL ID of the album. **Examples**: :code:`46369321`, :code:`"251380836"`. country_code : str; optional ISO 3166-1 alpha-2 country code. **Example**: :code:`"US"`. include_metadata : bool; keyword-only; default: :code:`False` Whether to include metadata for the album's usage rules. share_code : str; keyword-only; optional Share code that grants access to unlisted resources. Returns ------- cover_art : dict[str, Any] TIDAL metadata for the album's usage rules. .. admonition:: Sample response :class: response dropdown .. code-block:: { "data": [], "included": [], "links": { "meta": { "nextCursor": <str> }, "next": <str>, "self": <str> } } """ return self._get_resource_relationship( "albums", album_id, "usageRules", country_code=country_code, include_metadata=include_metadata, share_code=share_code, )
[docs] @_copy_docstring(SearchAPI.search_albums) def search_albums( self, query: str, /, country_code: str | None = None, *, include_explicit: bool | None = None, include_metadata: bool = False, cursor: str | None = None, ) -> dict[str, Any]: return self._client.search.search_albums( query, country_code=country_code, include_explicit=include_explicit, include_metadata=include_metadata, cursor=cursor, )
[docs] @_copy_docstring(UsersAPI.get_album_collection) def get_album_collection( self, collection_id: str | None = None, /, *, country_code: str | None = None, locale: str | None = None, expand: str | Collection[str] | None = None, ) -> dict[str, Any]: return self._client.users.get_album_collection( collection_id=collection_id, country_code=country_code, locale=locale, expand=expand, )
[docs] @_copy_docstring(UsersAPI.get_user_saved_albums) def get_user_saved_albums( self, *, collection_id: str | None = None, user_id: int | str | None = None, country_code: str | None = None, locale: str | None = None, include_metadata: bool = False, cursor: str | None = None, sort_by: str | None = None, descending: bool | None = None, ) -> dict[str, Any]: return self._client.users.get_user_saved_albums( collection_id=collection_id, user_id=user_id, country_code=country_code, locale=locale, include_metadata=include_metadata, cursor=cursor, sort_by=sort_by, descending=descending, )
[docs] @_copy_docstring(UsersAPI.save_albums) def save_albums( self, album_ids: int | str | dict[str, int | str] | Collection[int | str | dict[str, int | str]], /, *, collection_id: str | None = None, user_id: int | str | None = None, country_code: str | None = None, ) -> None: self._client.users.save_albums( album_ids, collection_id=collection_id, user_id=user_id, country_code=country_code, )
[docs] @_copy_docstring(UsersAPI.remove_saved_albums) def remove_saved_albums( self, album_ids: int | str | dict[str, int | str] | Collection[int | str | dict[str, int | str]], /, *, collection_id: str | None = None, user_id: int | str | None = None, country_code: str | None = None, ) -> None: self._client.users.remove_saved_albums( album_ids, collection_id=collection_id, user_id=user_id, country_code=country_code, )