### Usage Example Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/EDClient.md Demonstrates how to initialize the client and use platform-specific endpoints. ```APIDOC ## Usage Example Initialize the client and interact with platform endpoints. ```python from ensembledata.api import EDClient # Initialize the client client = EDClient("your_api_token") # Search hashtags hashtag_result = client.tiktok.hashtag_search(hashtag="magic", cursor=0) print(f"Posts found: {len(hashtag_result.data['data'])}") # Get user information user_result = client.tiktok.user_info_from_username(username="zachking") user_info = user_result.data["user"] print(f"Followers: {user_info['follower_count']}") # Check API usage usage = client.customer.get_usage(date="2024-01-01") print(f"Units used: {usage.data['units_used']}") ``` ``` -------------------------------- ### Bash Output Example Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Example output showing the number of posts retrieved by the Full Keyword Search API. ```bash Number of posts: 1366 ``` -------------------------------- ### Keyword Search - Cursor Handling Example Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md An example demonstrating how to manually handle the cursor to fetch up to 200 posts for a keyword. ```APIDOC ## Keyword Search - Cursor Handling Example ### Description Illustrates a loop for manually fetching multiple batches of posts using the cursor until all available posts are retrieved or a limit is reached. ### Method client.tiktok.keyword_search ### Parameters #### Keyword Search Parameters - **keyword** (string) - Required - The keyword to search for. - **cursor** (string) - Optional - The cursor value for pagination. ### Request Example ```python posts = list() cursor = None for _ in range(10): result = client.tiktok.keyword_search(keyword="tesla", cursor=cursor) posts.extend(result.data["data"]) cursor = result.data.get("nextCursor") # If there is no next cursor, we've fetched all the available posts if cursor is None: break print("Number of posts:", len(posts)) ``` ### Output Example ```bash Number of posts: 200 ``` ``` -------------------------------- ### Setup Virtual Environment Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Optional steps to create and activate a virtual environment for Python projects. ```bash python3 -m venv .venv source .venv/bin/activate ``` -------------------------------- ### Concurrency Example Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/EDAsyncClient.md Demonstrates how to leverage asynchronous capabilities to make multiple API calls concurrently, improving efficiency. ```APIDOC ## Concurrency Example Leverage async to make multiple API calls concurrently: ```python import asyncio from ensembledata.api import EDAsyncClient async def scrape_multiple_users(): client = EDAsyncClient("your_api_token") usernames = ["zachking", "daviddobrik", "charlidamelio"] # Fetch user info for all users concurrently tasks = [ client.tiktok.user_info_from_username(username=name) for name in usernames ] results = await asyncio.gather(*tasks) for username, result in zip(usernames, results): user = result.data["user"] print(f"{username}: {user['follower_count']} followers") asyncio.run(scrape_multiple_users()) ``` ``` -------------------------------- ### EDClient Usage Example Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/EDClient.md Demonstrates common use cases such as searching hashtags, retrieving user information, and checking API usage. ```python from ensembledata.api import EDClient # Initialize the client client = EDClient("your_api_token") # Search hashtags hashtag_result = client.tiktok.hashtag_search(hashtag="magic", cursor=0) print(f"Posts found: {len(hashtag_result.data['data'])}") # Get user information user_result = client.tiktok.user_info_from_username(username="zachking") user_info = user_result.data["user"] print(f"Followers: {user_info['follower_count']}") # Check API usage usage = client.customer.get_usage(date="2024-01-01") print(f"Units used: {usage.data['units_used']}") ``` -------------------------------- ### Quick Start: Search TikTok Hashtags and Get User Info Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/README.md Demonstrates how to create an EDClient, search for TikTok posts by hashtag, and retrieve user information by username. Requires an API token for initialization. ```python from ensembledata.api import EDClient # Create client with your API token client = EDClient("your_api_token_here") # Search TikTok hashtags result = client.tiktok.hashtag_search(hashtag="magic") posts = result.data["data"] print(f"Found {len(posts)} posts") # Get user info user_result = client.tiktok.user_info_from_username(username="zachking") follower_count = user_result.data["user"]["follower_count"] print(f"Followers: {follower_count}") ``` -------------------------------- ### Install ensembledata Package Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/README.md Install the ensembledata Python package using pip. This command is used to add the library to your project. ```bash pip install ensembledata ``` -------------------------------- ### Quick Example: Search TikTok Hashtag Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/INDEX.md Demonstrates how to initialize the EDClient and perform a hashtag search on TikTok. Requires an API token. ```python from ensembledata.api import EDClient client = EDClient("your_api_token") # Search TikTok result = client.tiktok.hashtag_search(hashtag="magic") posts = result.data["data"] print(f"Found {len(posts)} posts") ``` -------------------------------- ### Usage Example Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/EDAsyncClient.md Demonstrates how to use the EDAsyncClient to fetch data from TikTok endpoints, including searching hashtags and retrieving user information. ```APIDOC ## Usage Example ```python import asyncio from ensembledata.api import EDAsyncClient, EDError async def fetch_tiktok_data(): client = EDAsyncClient("your_api_token") try: # Search hashtags hashtag_result = await client.tiktok.hashtag_search(hashtag="magic") posts = hashtag_result.data["data"] print(f"Found {len(posts)} posts") # Get user information user_result = await client.tiktok.user_info_from_username(username="zachking") user_data = user_result.data["user"] print(f"User: {user_data['nickname']}") # Batch fetch multiple users concurrently tasks = [ client.tiktok.user_info_from_username(username=username) for username in ["user1", "user2", "user3"] ] results = await asyncio.gather(*tasks) except EDError as e: print(f"API error: {e.detail}") # Run the async function asyncio.run(fetch_tiktok_data()) ``` ``` -------------------------------- ### Instantiate Asynchronous EDAsyncClient Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/configuration.md Instantiate the asynchronous EDAsyncClient with identical parameters to the synchronous client. This example also shows an API call using the client. ```python import asyncio from ensembledata.api import EDAsyncClient async def main(): client = EDAsyncClient( token="your_api_token", timeout=600, max_network_retries=3 ) result = await client.tiktok.hashtag_search(hashtag="magic") return result asyncio.run(main()) ``` -------------------------------- ### Example EDResponse Usage Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Demonstrates how to instantiate the EDClient and process a successful API response. Shows how to access status code, units charged, and the response data payload. ```python from ensembledata.api import EDClient client = EDClient("token") response = client.tiktok.hashtag_search(hashtag="magic") print(f"Status: {response.status_code}") # 200 print(f"Units charged: {response.units_charged}") # e.g., 1 print(f"Data type: {type(response.data)}") # dict # Access response data posts = response.data["data"] # For hashtag_search next_cursor = response.data.get("nextCursor") # Pagination cursor ``` -------------------------------- ### Get User Info by Username Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Retrieves user information using their username. Ensure the username is correct. ```python result = client.tiktok.user_info_from_username( username="zachking" ) ``` -------------------------------- ### Get User Liked Posts (Initial Request) Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Fetches posts liked by a user, requiring their secuid. Check for 'nextCursor' to paginate. ```python result = client.tiktok.user_liked_posts( sec_uid="MS4wLjAB...", ) posts = result.data["liked_posts"] next_cursor = result.data.get("nextCursor") ``` -------------------------------- ### Get User Posts by Secuid Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Fetches posts for a given user secuid. Accepts depth parameter. ```python result = client.tiktok_user_posts_from_secuid( sec_uid="MS4wLjAB...", depth=1, ) ``` -------------------------------- ### Fetch Multiple Chunks of Posts Combining Depth and Cursor Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md This example demonstrates fetching an initial set of posts and then fetching subsequent posts using both `depth` and `cursor` parameters. It's useful for retrieving a specific range of posts efficiently. ```python posts = list() result = client.tiktok_user_posts_from_username( username="zachking", depth=1, ) posts.extend(result.data["data"]) next_cursor = result.get("nextCursor") if next_cursor is not None: result = client.tiktok_user_posts_from_username( username="zachking", depth=5, cursor=next_cursor, ) posts.extend(result.data["data"]) print("Posts:", len(posts)) ``` -------------------------------- ### Example of Omitting Optional Parameters Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Demonstrates how to use USE_DEFAULT to omit optional parameters, making it equivalent to not passing the parameter at all. This contrasts with explicitly passing a value like 0. ```python # These are equivalent - both omit the `cursor` parameter result1 = client.tiktok.hashtag_search(hashtag="magic") result2 = client.tiktok.hashtag_search(hashtag="magic", cursor=USE_DEFAULT) # This explicitly passes cursor=0 result3 = client.tiktok.hashtag_search(hashtag="magic", cursor=0) ``` -------------------------------- ### Get User Liked Posts (Pagination) Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Fetches subsequent pages of liked posts using the 'next_cursor' obtained from a previous request. ```python result = client.tiktok.user_liked_posts( sec_uid="MS4wLjAB...", cursor=next_cursor ) more_posts = result.data["liked_posts"] next_cursor = result.data.get("nextCursor") ``` -------------------------------- ### Get User Info by Secuid Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Retrieves user information using their secuid. The optional alternative_method parameter can provide additional data like account category. ```python result = client.tiktok.user_info_from_secuid( sec_uid="MS4wLjAB..." ) user = result.data["user"] print("Username:", user["unique_id"]) print("Nickname:", user["nickname"]) print("Followers:", user["follower_count"]) print("Posts:", user["aweme_count"]) print("Likes:", user["total_favorited"]) ``` -------------------------------- ### Get User Info by SecUID Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/TiktokEndpoints.md Retrieve a user's profile information using their secondary user ID (sec_uid). ```python def user_info_from_secuid( self, *, sec_uid: str, alternative_method: bool | UseDefault = USE_DEFAULT, extra_params: Mapping[str, Any] | None = None, timeout: float | None = None, ) -> EDResponse ``` -------------------------------- ### Fetch YouTube Channel Subscriber Count Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/YoutubeEndpoints.md Use this to get the subscriber count for a YouTube channel. Requires the channel ID. ```python def channel_subscribers( self, *, channel_id: str, extra_params: Mapping[str, Any] | None = None, timeout: float | None = None, ) -> EDResponse ``` -------------------------------- ### Get Post Info by URL Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/TiktokEndpoints.md Retrieve detailed information for a single TikTok post using its URL. Optionally download the video. ```python def post_info( self, *, url: str, new_version: bool | UseDefault = USE_DEFAULT, download_video: bool | UseDefault = USE_DEFAULT, extra_params: Mapping[str, Any] | None = None, timeout: float | None = None, ) -> EDResponse ``` ```python result = client.tiktok.post_info(url="https://www.tiktok.com/@daviddobrik/video/7165262254722534698") post = result.data[0] print(f"Likes: {post['statistics']['digg_count']}") print(f"Views: {post['statistics']['play_count']}") ``` -------------------------------- ### Cursor-Based Pagination Example Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/README.md Handle paginated results from TikTok API endpoints using the 'nextCursor' value. Fetch subsequent pages by passing the cursor in the next request. ```python result = client.tiktok.hashtag_search(hashtag="magic") posts = result.data["data"] next_cursor = result.data.get("nextCursor") if next_cursor: result = client.tiktok.hashtag_search(hashtag="magic", cursor=next_cursor) more_posts = result.data["data"] ``` -------------------------------- ### Get YouTube Video Details Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/README.md Fetches details for a YouTube video using its unique ID. Returns statistics and other relevant information about the video. ```python result = client.youtube.video_details(id="dQw4w9WgXcQ") stats = result.data ``` -------------------------------- ### Example EDError Handling Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Illustrates how to handle potential API errors using a try-except block. Catches EDError and prints details like status code, message, and units charged, with a specific check for invalid tokens. ```python from ensembledata.api import EDClient, EDError, STATUS_491_INVALID_TOKEN client = EDClient("invalid_token") try: result = client.tiktok.hashtag_search(hashtag="test") except EDError as e: print(f"Error code: {e.status_code}") print(f"Message: {e.detail}") print(f"Units charged: {e.units_charged}") if e.status_code == STATUS_491_INVALID_TOKEN: print("Invalid API token") ``` -------------------------------- ### Implement Retry Logic for Rate Limiting Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/errors.md Use exponential backoff to retry requests when encountering a 429 Rate Limit Exceeded error. This example shows a custom fetch function with retry capabilities. ```python import time from ensembledata.api import EDClient, EDError, STATUS_429_RATE_LIMIT_EXCEEDED def fetch_with_retry(client, max_retries=3): for attempt in range(max_retries): try: return client.tiktok.hashtag_search(hashtag="test") except EDError as e: if e.status_code == STATUS_429_RATE_LIMIT_EXCEEDED: wait_time = 2 ** attempt # Exponential backoff: 1, 2, 4 seconds print(f"Rate limited. Waiting {wait_time}s before retry...") time.sleep(wait_time) else: raise raise Exception("Max retries exceeded") client = EDClient("token") result = fetch_with_retry(client) ``` -------------------------------- ### Get TikTok User Followings (Initial) Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Fetch the first 100 users that a TikTok user is following. Requires user ID and secondary user ID. Subsequent requests require 'cursor' and 'nextPageToken' for pagination. ```python result = client.tiktok.user_followings( id="6784819479778378757", sec_uid="MS4wLjABAAAAQ45...", ) followers = result.data["followings"] follower_count = result.data["total"] next_cursor = result.data.get("nextCursor") next_page_token = result.data.get("nextPageToken") ``` -------------------------------- ### Catching Errors Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/errors.md Example of how to catch and handle EDError exceptions when interacting with the EnsembleData API. ```APIDOC ## Catching Errors ```python from ensembledata.api import EDClient, EDError client = EDClient("token") try: result = client.tiktok.hashtag_search(hashtag="test") except EDError as e: print(f"Status: {e.status_code}") print(f"Detail: {e.detail}") print(f"Units charged: {e.units_charged}") ``` ``` -------------------------------- ### Get YouTube Video Details Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/README.md Retrieve details for a YouTube video using its unique video ID. ```APIDOC ## Get YouTube Video Details ### Description Fetches detailed information about a YouTube video using its unique video ID. ### Method `client.youtube.video_details(id: str)` ### Parameters - **id** (str) - Required - The unique identifier of the YouTube video. ### Response Example ```json { "data": { // Video details and statistics } } ``` ``` -------------------------------- ### Initialize EDClient Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/EDClient.md Instantiate the EDClient with your API token. Optional parameters include request timeout and network retry attempts. ```python class EDClient: def __init__(self, token: str, *, timeout: float = 600, max_network_retries: int = 3) ``` -------------------------------- ### Initialize EDAsyncClient Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/EDAsyncClient.md Instantiate the asynchronous client with your API token. Optional parameters include request timeout and maximum network retries. ```python class EDAsyncClient: def __init__(self, token: str, *, timeout: float = 600, max_network_retries: int = 3) ``` -------------------------------- ### API Pagination with Cursor - Initial Request Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Demonstrates the initial API call to fetch a chunk of items from a list. The response includes the data and a `nextCursor` if more items are available. ```python result = api.get_books() print(result.data) ``` -------------------------------- ### Async Customer Endpoint Usage Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/CustomerEndpoints.md Demonstrates how to use customer endpoint methods asynchronously with `EDAsyncClient`. Requires awaiting the method calls. ```python import asyncio from ensembledata.api import EDAsyncClient async def check_usage(): client = EDAsyncClient("token") # Check usage for specific date result = await client.customer.get_usage(date="2024-01-15") print(f"Units used: {result.data['units_used']}") # Check usage history history = await client.customer.get_usage_history(days=30) print(f"Usage records: {len(history.data)}") asyncio.run(check_usage()) ``` -------------------------------- ### EDClient Constructor Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/EDClient.md Initializes the EDClient with an API token and optional network settings. ```APIDOC ## EDClient Constructor Initializes the synchronous EnsembleData API client. ### Parameters - **token** (str) - Required - API authentication token. Obtain from https://dashboard.ensembledata.com - **timeout** (float) - Optional - Request timeout in seconds. Defaults to 600. - **max_network_retries** (int) - Optional - Number of retry attempts for network errors. Defaults to 3. ``` -------------------------------- ### Instantiate Synchronous EDClient Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/configuration.md Instantiate the synchronous EDClient with authentication token, timeout, and network retries. The client logs a warning if an empty string or non-string value is provided for the token. ```python from ensembledata.api import EDClient client = EDClient( token="your_api_token", timeout=600, max_network_retries=3 ) ``` -------------------------------- ### EDClient Constructor Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/REFERENCE-INDEX.md Instantiate the synchronous API client. Requires an API token and allows optional configuration for timeout and network retries. ```python EDClient(token: str, *, timeout: float = 600, max_network_retries: int = 3) ``` -------------------------------- ### video_details Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/YoutubeEndpoints.md Gets detailed statistics for a specific YouTube video, with options to use alternative scraping methods and include subscriber counts. ```APIDOC ## video_details ### Description Retrieve detailed statistics for a YouTube video. ### Method Signature ```python def video_details( self, *, id: str, alternative_method: bool | UseDefault = USE_DEFAULT, get_subscribers_count: bool | UseDefault = USE_DEFAULT, extra_params: Mapping[str, Any] | None = None, timeout: float | None = None, ) -> EDResponse ``` ### Parameters #### Path Parameters - `id` (str) - Required - YouTube video ID #### Optional Parameters - `alternative_method` (bool | UseDefault) - Optional - Use alternative scraping method - `get_subscribers_count` (bool | UseDefault) - Optional - Include channel subscriber count - `extra_params` (Mapping[str, Any] | None) - Optional - Additional query parameters - `timeout` (float | None) - Optional - Request timeout override in seconds ### Returns `EDResponse` with video statistics ``` -------------------------------- ### Get Multiple Post Info by IDs Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/TiktokEndpoints.md Retrieve information for multiple TikTok posts simultaneously using their IDs. Supports downloading videos. ```python def multi_post_info( self, *, aweme_ids: Sequence[str], new_version: bool | UseDefault = USE_DEFAULT, download_video: bool | UseDefault = USE_DEFAULT, extra_params: Mapping[str, Any] | None = None, timeout: float | None = None, ) -> EDResponse ``` ```python result = client.tiktok.multi_post_info(aweme_ids=["123456", "789012"]) posts = result.data for post in posts: print(f"Post {post['id']}: {post['desc']}") ``` -------------------------------- ### Async Context Manager Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/EDAsyncClient.md Illustrates how to use the EDAsyncClient as an asynchronous context manager for proper resource cleanup. ```APIDOC ## Async Context Manager For proper resource cleanup, use the client as an async context manager: ```python import asyncio from ensembledata.api import EDAsyncClient async def main(): async with EDAsyncClient("your_api_token") as client: result = await client.tiktok.hashtag_search(hashtag="test") print(result.data) asyncio.run(main()) ``` ``` -------------------------------- ### Initialize EnsembleData Client Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Initializes the EDClient with your API token to interact with EnsembleData APIs. ```python from ensembledata.api import EDClient client = EDClient("INSERT API TOKEN") ``` -------------------------------- ### Get User Information Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/README.md Fetch detailed information about a TikTok user, including follower count, post count, and total likes, using their username. ```APIDOC ## Get User Information ### Description Fetches detailed information about a TikTok user, identified by their username. The response includes metrics such as follower count, post count, and total likes. ### Method `client.tiktok.user_info_from_username(username: str)` ### Parameters - **username** (str) - Required - The username of the TikTok user. ### Response Example ```json { "data": { "user": { "follower_count": 1000000, "aweme_count": 500, "total_favorited": 10000000 // ... other user details } } } ``` ``` -------------------------------- ### Fetch All Posts for a Keyword Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/TiktokEndpoints.md Fetches all posts associated with a given keyword, automatically handling pagination. This endpoint may take a considerable amount of time for popular keywords, so it's recommended to set a high timeout value. ```python def full_keyword_search( self, *, keyword: str, period: Literal["0", "1", "7", "30", "90", "180"], sorting: Literal["0", "1"] | UseDefault = USE_DEFAULT, country: str | UseDefault = USE_DEFAULT, match_exactly: bool | UseDefault = USE_DEFAULT, extra_params: Mapping[str, Any] | None = None, timeout: float | None = None, ) -> EDResponse ``` ```python result = client.tiktok.full_keyword_search(keyword="tesla", period="180") all_posts = result.data["data"] print(f"Total posts found: {len(all_posts)}") ``` -------------------------------- ### Load Token from Environment Variable Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/configuration.md Instantiate the client using an API token read from the 'ENSEMBLEDATA_TOKEN' environment variable. Ensure the variable is set before running the code. ```python import os from ensembledata.api import EDClient # Read token from environment api_token = os.getenv("ENSEMBLEDATA_TOKEN") if not api_token: raise ValueError("ENSEMBLEDATA_TOKEN environment variable not set") client = EDClient(api_token) ``` -------------------------------- ### EDClient Default Configuration Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/configuration.md Use the default configuration for the EDClient by providing only the API token. ```python # Default configuration client = EDClient("token") ``` -------------------------------- ### Literal Type for Twitch Search Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations enforce specific string values for enumerated parameters. This example shows literals for Twitch search types. ```python Literal["videos", "channels", "games"] ``` -------------------------------- ### Use EDAsyncClient as an Async Context Manager Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/EDAsyncClient.md Properly initialize and clean up the EDAsyncClient by using it within an `async with` statement. Ensures resources are released. ```python import asyncio from ensembledata.api import EDAsyncClient async def main(): async with EDAsyncClient("your_api_token") as client: result = await client.tiktok.hashtag_search(hashtag="test") print(result.data) asyncio.run(main()) ``` -------------------------------- ### Literal Type for YouTube Sorting Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations enforce specific string values for enumerated parameters. This example shows literals for YouTube sorting options. ```python Literal["relevance", "time", "views", "rating"] ``` -------------------------------- ### Manually Handle Cursor for Multiple Pages Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Iteratively fetches posts for a keyword by managing the cursor manually. The loop continues until no `nextCursor` is returned, indicating all available posts have been retrieved. ```python posts = list() cursor = None for _ in range(10): result = client.tiktok.keyword_search(keyword="tesla", cursor=cursor) posts.extend(result.data["data"]) cursor = result.data.get("nextCursor") # If there is no next cursor, we've fetched all the available posts if cursor is None: break print("Number of posts:", len(posts)) ``` -------------------------------- ### Load Token from .env File Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/configuration.md Load the API token from a .env file using the python-dotenv library. This pattern is convenient for local development. ```bash # .env file ENSEMBLEDATA_TOKEN=your_token_here ``` ```python # Python code import os from dotenv import load_dotenv from ensembledata.api import EDClient load_dotenv() client = EDClient(os.getenv("ENSEMBLEDATA_TOKEN")) ``` -------------------------------- ### Fetch User Tagged Posts Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/InstagramEndpoints.md Get posts where a user has been tagged. This method supports pagination using a cursor and allows control over the number of posts per batch. ```python def user_tagged_posts( self, *, user_id: int, cursor: str | UseDefault = USE_DEFAULT, chunk_size: int | UseDefault = USE_DEFAULT, extra_params: Mapping[str, Any] | None = None, timeout: float | None = None, ) -> EDResponse ``` -------------------------------- ### full_keyword_search Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/TiktokEndpoints.md Fetches all posts for a given keyword, automatically handling pagination. This operation may take a significant amount of time for popular keywords, so setting a high timeout is recommended. ```APIDOC ## full_keyword_search ### Description Fetch all posts for a keyword automatically handling pagination. ### Method POST ### Endpoint /tiktok/full_keyword_search ### Parameters #### Query Parameters - **keyword** (str) - Required - Keyword to search - **period** (Literal["0", "1", "7", "30", "90", "180"]) - Required - Time period filter - **sorting** (Literal["0", "1"] | UseDefault) - Optional - `USE_DEFAULT` - Sort order - **country** (str | UseDefault) - Optional - `USE_DEFAULT` - Country code - **match_exactly** (bool | UseDefault) - Optional - `USE_DEFAULT` - Exact match - **extra_params** (Mapping[str, Any] | None) - Optional - `None` - Additional query parameters - **timeout** (float | None) - Optional - `None` - Request timeout override in seconds ### Response #### Success Response (200) - **data** (dict) - Contains posts and pagination information ### Response Example ```json { "data": { "data": [ { "id": "post_id_1", "text": "Example post text..." } ], "nextCursor": "some_cursor" } } ``` ### Warning This endpoint may take 10+ minutes for popular keywords. Set a high timeout. ``` -------------------------------- ### API Pagination with Cursor - Subsequent Request Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Shows how to use the `nextCursor` from a previous response to fetch the next chunk of items from an API list. This is essential for iterating over large datasets. ```python result = api.get_books(cursor=20) print(result.data) ``` -------------------------------- ### TikTok API Error Handling Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/README.md Implement robust error handling for TikTok API requests using EDError. This example checks for invalid tokens and rate limiting errors. ```python from ensembledata.api import EDClient, EDError, STATUS_491_INVALID_TOKEN client = EDClient("token") try: result = client.tiktok.hashtag_search(hashtag="test") except EDError as e: if e.status_code == STATUS_491_INVALID_TOKEN: print("Invalid API token") elif e.status_code == 429: print("Rate limited") else: print(f"API error: {e.detail}") ``` -------------------------------- ### Literal Type for Threads Post Sorting Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations enforce specific string values for enumerated parameters. This example shows literals for Threads post sorting. ```python Literal["0", "1"] ``` -------------------------------- ### Literal Type for Instagram Comment Sorting Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations enforce specific string values for enumerated parameters. This example shows literals for Instagram comment sorting. ```python Literal["popular", "recent"] ``` -------------------------------- ### EDAsyncClient Constructor Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/EDAsyncClient.md Initializes the asynchronous client for the EnsembleData API. Requires an API token and allows configuration of timeout and network retries. ```APIDOC ## EDAsyncClient Constructor ```python class EDAsyncClient: def __init__(self, token: str, *, timeout: float = 600, max_network_retries: int = 3) ``` ### Parameters - **token** (str) - Required - API authentication token. Obtain from https://dashboard.ensembledata.com - **timeout** (float) - Optional - Request timeout in seconds. Defaults to 600. - **max_network_retries** (int) - Optional - Number of retry attempts for network errors. Defaults to 3. ``` -------------------------------- ### Literal Type for Reddit Time Period Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations enforce specific string values for enumerated parameters. This example shows literals for Reddit time periods. ```python Literal["hour", "day", "week", "month", "year", "all"] ``` -------------------------------- ### Instantiate EDClient and Access Endpoint Groups Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/configuration.md Instantiate the EDClient with your API token and access various endpoint groups as client attributes. ```python from ensembledata.api import EDClient client = EDClient("token") # Endpoint group attributes client.customer # CustomerEndpoints client.tiktok # TiktokEndpoints client.youtube # YoutubeEndpoints client.instagram # InstagramEndpoints client.twitch # TwitchEndpoints client.reddit # RedditEndpoints client.twitter # TwitterEndpoints client.threads # ThreadsEndpoints client.snapchat # SnapchatEndpoints ``` -------------------------------- ### Full Keyword Search Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Fetches all posts for a specified keyword by automatically handling the cursor. This method can take a significant amount of time to complete. ```APIDOC ## Full Keyword Search ### Description Fetches all posts for a specified keyword by automatically handling the cursor. This method can take a significant amount of time to complete. ### Method POST (Assumed based on typical API patterns for search with parameters) ### Endpoint /tiktok/full_keyword_search ### Parameters #### Query Parameters - **keyword** (string) - Required - The keyword to search for. - **period** (string) - Required - The time period for the search (e.g., "180" for 180 days). ### Request Example ```python result = client.tiktok.full_keyword_search( keyword="tesla", period="180" ) ``` ### Response #### Success Response (200) - **data** (object) - Contains the list of posts. #### Response Example ```json { "data": [ // ... list of posts ... ] } ``` #### Warning This API can take a long time to respond. Ensure a high timeout is set for direct HTTP requests. ``` -------------------------------- ### Literal Type for Reddit Sort Options Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations enforce specific string values for enumerated parameters. This example shows literals for Reddit sort options. ```python Literal["hot", "new", "top", "rising"] ``` -------------------------------- ### Customize Network Configuration with Requester Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/configuration.md Customize network behavior by creating a custom Requester with specific httpx transports or proxy configurations. Note: This requires direct use of internal APIs. ```python import httpx from ensembledata.api._requester import Requester # Use custom httpx transport custom_transport = httpx.HTTPTransport( limits=httpx.Limits(max_connections=10) ) # Or proxy configuration proxies = { "https://ensembledata.com": "https://proxy.example.com:8080" } # Create requester and use in client # Note: This requires direct use of internal APIs ``` -------------------------------- ### Literal Type for YouTube Period Filter Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations enforce specific string values for enumerated parameters. This example shows literals for YouTube period filtering. ```python Literal["overall", "hour", "today", "week", "month", "year"] ``` -------------------------------- ### Keyword Search - Fetching More Posts (Cursor) Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Retrieves the next batch of posts using the cursor obtained from a previous search. ```APIDOC ## Keyword Search - Fetching More Posts (Cursor) ### Description Fetches subsequent batches of posts by providing the `nextCursor` value from a previous request. ### Method client.tiktok.keyword_search ### Parameters #### Keyword Search Parameters - **keyword** (string) - Required - The keyword to search for. - **cursor** (string) - Optional - The cursor value obtained from the previous response to fetch the next set of results. ### Request Example ```python # Assuming 'next_cursor' was obtained from a previous call result = client.tiktok.keyword_search(keyword="tesla", cursor=next_cursor) posts = result.data["data"] next_cursor = result.data.get("nextCursor") ``` ### Note Continue this process until `nextCursor` is no longer present in the response, indicating all available posts have been fetched. ``` -------------------------------- ### Get TikTok User Information Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/README.md Fetches detailed information about a TikTok user, including follower count, post count, and total likes. Requires the user's username. ```python result = client.tiktok.user_info_from_username(username="zachking") user = result.data["user"] print(user["follower_count"]) # Followers print(user["aweme_count"]) # Post count print(user["total_favorited"]) # Total likes ``` -------------------------------- ### Fetch User Posts with Alternative Method Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Fetches user posts using an alternative scraping method. The response payload will differ from the default method. ```python result = client.tiktok_user_posts_from_username( username="zachking", depth=1, alternative_method=True, ) ``` -------------------------------- ### Get Next Chunk of TikTok User Followings Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Retrieve the next chunk of followings for a TikTok user by passing the 'cursor' and 'nextPageToken' obtained from a previous request. This is used for paginating through results. ```python result = client.tiktok.user_followings( id="6784819479778378757", sec_uid="MS4wLjABAAAAQ45...", cursor=next_cursor, page_token=next_page_token, ) next_cursor = result.data.get("nextCursor") next_page_token = result.data.get("nextPageToken") ``` -------------------------------- ### Keyword Search - Basic Usage Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Fetches the first 20 posts for the keyword 'tesla' within the last 180 days. ```APIDOC ## Keyword Search - Basic Usage ### Description Fetches posts for a given keyword within a specified period. ### Method client.tiktok.keyword_search ### Parameters #### Keyword Search Parameters - **keyword** (string) - Required - The keyword to search for. - **period** (string) - Optional - The period in days to search within (e.g., "0", "1", "7", "30", "90", "180"). Defaults to "180" if not specified. ### Request Example ```python from ensembledata.api import EDClient client = EDClient("API_TOKEN") result = client.tiktok.keyword_search( keyword="tesla", period="180" ) posts = result.data["data"] print("Number of posts:", len(posts)) ``` ### Response #### Success Response - **data** (list) - A list of posts matching the keyword. - **nextCursor** (string) - A cursor for fetching the next batch of posts. ``` -------------------------------- ### Retrieve YouTube Video Details Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/api-reference/YoutubeEndpoints.md Use this to get detailed statistics for a YouTube video. Requires the video ID. Optionally, you can use an alternative scraping method or include subscriber counts. ```python def video_details( self, *, id: str, alternative_method: bool | UseDefault = USE_DEFAULT, get_subscribers_count: bool | UseDefault = USE_DEFAULT, extra_params: Mapping[str, Any] | None = None, timeout: float | None = None, ) -> EDResponse ``` -------------------------------- ### Literal Type for TikTok Music Search Filters Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations enforce specific string values for enumerated parameters. This example shows literals for filtering TikTok music searches. ```python Literal["0", "1", "2"] ``` -------------------------------- ### Literal Type for Music-Specific Sorting Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations enforce specific string values for enumerated parameters. This example shows literals for music-specific sorting options in TikTok music searches. ```python Literal["0", "1", "2", "3", "4"] # TikTok music search ``` -------------------------------- ### Fetch Next Chunk of Posts using Cursor Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md To retrieve the next set of posts after an initial fetch, use the `next_cursor` value obtained from the previous response. This allows for paginated fetching of content. ```python result = client.tiktok_user_posts_from_username( username="zachking", depth=1, cursor=next_cursor, ) next_posts = result.data["data"] next_cursor = result.data.get("nextCursor") ``` -------------------------------- ### Literal Type for TikTok Sorting Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations are used to enforce specific string values for enumerated parameters. This example shows literals for TikTok keyword/music search sorting options. ```python Literal["0", "1"] # TikTok keyword/music search ``` -------------------------------- ### Get Commenter User IDs Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Extracts the commenter's `sec_uid` and `uid` from the user object within a comment. These IDs are valuable for calling other Ensembledata API endpoints related to user information. ```python print("sec_uid:", user["sec_uid"]) print("user_id:", user["uid"]) ``` -------------------------------- ### Get TikTok User Followers Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Retrieve the most recent 100 followers for a given TikTok user. Requires user ID and secondary user ID. Subsequent requests can use the 'nextCursor' for pagination. ```python result = client.tiktok.user_followers( id="6784819479778378757", sec_uid="MS4wLjABAAAAQ45...", ) followers = result.data["followers"] follower_count = result.data["total"] next_cursor = result.data["nextCursor"] ``` -------------------------------- ### Full Keyword Search API in Python Source: https://github.com/ensembledata/tiktok-scraper/blob/main/README.md Fetches all posts for a given keyword automatically handling pagination. Ensure a timeout greater than 10 minutes for long-running requests when not using the EnsembleData API packages. ```python result = client.tiktok.full_keyword_search( keyword="tesla", period="180" ) posts = result.data["data"] print("Number of posts:", len(posts)) ``` -------------------------------- ### Literal Type for Period Filtering Source: https://github.com/ensembledata/tiktok-scraper/blob/main/_autodocs/types.md Literal type annotations enforce specific string values for enumerated parameters. This example shows literals used for time period filtering in keyword search endpoints. ```python Literal["0", "1", "7", "30", "90", "180"] ```