Source code for TikTokApi.api.sound

from __future__ import annotations
from ..exceptions import *
from typing import TYPE_CHECKING, ClassVar, Iterator, Optional

if TYPE_CHECKING:
    from ..tiktok import TikTokApi
    from .user import User
    from .video import Video


[docs] class Sound: """ A TikTok Sound/Music/Song. Example Usage .. code-block:: python song = api.song(id='7016547803243022337') """ parent: ClassVar[TikTokApi] id: str """TikTok's ID for the sound""" title: Optional[str] """The title of the song.""" author: Optional[User] """The author of the song (if it exists)""" duration: Optional[int] """The duration of the song in seconds.""" original: Optional[bool] """Whether the song is original or not.""" def __init__(self, id: Optional[str] = None, data: Optional[str] = None): """ You must provide the id of the sound or it will not work. """ if data is not None: self.as_dict = data self.__extract_from_data() elif id is None: raise TypeError("You must provide id parameter.") else: self.id = id
[docs] async def info(self, **kwargs) -> dict: """ Returns all information sent by TikTok related to this sound. Returns: dict: The raw data returned by TikTok. Raises: InvalidResponseException: If TikTok returns an invalid response, or one we don't understand. Example Usage: .. code-block:: python sound_info = await api.sound(id='7016547803243022337').info() """ id = getattr(self, "id", None) if not id: raise TypeError( "You must provide the id when creating this class to use this method." ) url_params = { "msToken": kwargs.get("ms_token"), "musicId": id, } resp = await self.parent.make_request( url="https://www.tiktok.com/api/music/detail/", params=url_params, headers=kwargs.get("headers"), session_index=kwargs.get("session_index"), ) if resp is None: raise InvalidResponseException(resp, "TikTok returned an invalid response.") self.as_dict = resp self.__extract_from_data() return resp
[docs] async def videos(self, count=30, cursor=0, **kwargs) -> Iterator[Video]: """ Returns Video objects of videos created with this sound. Args: count (int): The amount of videos you want returned. cursor (int): The the offset of videos from 0 you want to get. Returns: async iterator/generator: Yields TikTokApi.video objects. Raises: InvalidResponseException: If TikTok returns an invalid response, or one we don't understand. Example Usage: .. code-block:: python async for video in api.sound(id='7016547803243022337').videos(): # do something """ id = getattr(self, "id", None) if id is None: raise TypeError( "You must provide the id when creating this class to use this method." ) found = 0 while found < count: params = { "musicID": id, "count": 30, "cursor": cursor, } resp = await self.parent.make_request( url="https://www.tiktok.com/api/music/item_list/", params=params, headers=kwargs.get("headers"), session_index=kwargs.get("session_index"), ) if resp is None: raise InvalidResponseException( resp, "TikTok returned an invalid response." ) for video in resp.get("itemList", []): yield self.parent.video(data=video) found += 1 if not resp.get("hasMore", False): return cursor = resp.get("cursor")
def __extract_from_data(self): data = self.as_dict keys = data.keys() if "musicInfo" in keys: author = data.get("musicInfo").get("author") if isinstance(author, dict): self.author = self.parent.user(data=author) elif isinstance(author, str): self.author = self.parent.user(username=author) if data.get("musicInfo").get("music"): self.title = data.get("musicInfo").get("music").get("title") self.id = data.get("musicInfo").get("music").get("id") self.original = data.get("musicInfo").get("music").get("original") self.play_url = data.get("musicInfo").get("music").get("playUrl") self.cover_large = data.get("musicInfo").get("music").get("coverLarge") self.duration = data.get("musicInfo").get("music").get("duration") if "music" in keys: self.title = data.get("music").get("title") self.id = data.get("music").get("id") self.original = data.get("music").get("original") self.play_url = data.get("music").get("playUrl") self.cover_large = data.get("music").get("coverLarge") self.duration = data.get("music").get("duration") if "stats" in keys: self.stats = data.get("stats") if getattr(self, "id", None) is None: Sound.parent.logger.error(f"Failed to create Sound with data: {data}\n") def __repr__(self): return self.__str__() def __str__(self): return f"TikTokApi.sound(id='{getattr(self, 'id', None)}')"