from __future__ import annotations from urllib.parse import urlencode from typing import TYPE_CHECKING, Iterator from .user import User from ..exceptions import InvalidResponseException if TYPE_CHECKING: from ..tiktok import TikTokApi class Search: """Contains static methods about searching TikTok for a phrase.""" parent: TikTokApi @staticmethod async def users(search_term, count=10, cursor=0, **kwargs) -> Iterator[User]: """ Searches for users. Note: Your ms_token needs to have done a search before for this to work. Args: search_term (str): The phrase you want to search for. count (int): The amount of users you want returned. Returns: async iterator/generator: Yields TikTokApi.user objects. Raises: InvalidResponseException: If TikTok returns an invalid response, or one we don't understand. Example Usage: .. code-block:: python async for user in api.search.users('david teather'): # do something """ async for user in Search.search_type( search_term, "user", count=count, cursor=cursor, **kwargs ): yield user @staticmethod async def search_type( search_term, obj_type, count=10, cursor=0, **kwargs ) -> Iterator: """ Searches for a specific type of object. But you shouldn't use this directly, use the other methods. Note: Your ms_token needs to have done a search before for this to work. Note: Currently only supports searching for users, other endpoints require auth. Args: search_term (str): The phrase you want to search for. obj_type (str): The type of object you want to search for (user) count (int): The amount of users you want returned. cursor (int): The the offset of users 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 user in api.search.search_type('david teather', 'user'): # do something """ found = 0 while found < count: params = { "keyword": search_term, "cursor": cursor, "from_page": "search", "web_search_code": """{"tiktok":{"client_params_x":{"search_engine":{"ies_mt_user_live_video_card_use_libra":1,"mt_search_general_user_live_card":1}},"search_server":{}}}""", } resp = await Search.parent.make_request( url=f"https://www.tiktok.com/api/search/{obj_type}/full/", params=params, headers=kwargs.get("headers"), session_index=kwargs.get("session_index"), ) if resp is None: raise InvalidResponseException( resp, "TikTok returned an invalid response." ) if obj_type == "user": for user in resp.get("user_list", []): sec_uid = user.get("user_info").get("sec_uid") uid = user.get("user_info").get("user_id") username = user.get("user_info").get("unique_id") yield Search.parent.user( sec_uid=sec_uid, user_id=uid, username=username ) found += 1 if not resp.get("has_more", False): return cursor = resp.get("cursor")