Spaces:
Sleeping
Sleeping
from copy import deepcopy | |
from typing import Dict, List, Optional, Union | |
DEFAULT_STATE = { | |
"username": "john", | |
"password": "john123", | |
"authenticated": False, | |
"tweets": {}, | |
"comments": {}, | |
"retweets": {}, | |
"following_list": ["alice", "bob"], | |
"tweet_counter": 0, | |
} | |
class TwitterAPI: | |
def __init__(self): | |
self.username: str | |
self.password: str | |
self.authenticated: bool | |
self.tweets: Dict[int, Dict[str, Union[int, str, List[str]]]] | |
self.comments: Dict[int, List[Dict[str, str]]] | |
self.retweets: Dict[str, List[int]] | |
self.following_list: List[str] | |
# tweet_counter is used to assign unique IDs to tweets, it might not be the same as the length of the tweets list for different scenarios | |
self.tweet_counter: int | |
self._api_description = "This tool belongs to the TwitterAPI, which provides core functionality for posting tweets, retweeting, commenting, and following users on Twitter." | |
def _load_scenario(self, scenario: dict, long_context=False) -> None: | |
""" | |
Load a scenario into the TwitterAPI instance. | |
Args: | |
scenario (dict): A dictionary containing Twitter data. | |
""" | |
DEFAULT_STATE_COPY = deepcopy(DEFAULT_STATE) | |
self.username = scenario.get("username", DEFAULT_STATE_COPY["username"]) | |
self.password = scenario.get("password", DEFAULT_STATE_COPY["password"]) | |
self.authenticated = scenario.get( | |
"authenticated", DEFAULT_STATE_COPY["authenticated"] | |
) | |
self.tweets = scenario.get("tweets", DEFAULT_STATE_COPY["tweets"]) | |
self.tweets = {int(k): v for k, v in self.tweets.items()} # Convert tweet keys from string to int from loaded scenario | |
self.comments = scenario.get("comments", DEFAULT_STATE_COPY["comments"]) | |
self.retweets = scenario.get("retweets", DEFAULT_STATE_COPY["retweets"]) | |
self.following_list = scenario.get( | |
"following_list", DEFAULT_STATE_COPY["following_list"] | |
) | |
self.tweet_counter = scenario.get( | |
"tweet_counter", DEFAULT_STATE_COPY["tweet_counter"] | |
) | |
def authenticate_twitter(self, username: str, password: str) -> Dict[str, bool]: | |
""" | |
Authenticate a user with username and password. | |
Args: | |
username (str): Username of the user. | |
password (str): Password of the user. | |
Returns: | |
authentication_status (bool): True if authenticated, False otherwise. | |
""" | |
if username == self.username and password == self.password: | |
self.authenticated = True | |
return {"authentication_status": True} | |
return {"authentication_status": False} | |
def posting_get_login_status(self) -> Dict[str, Union[bool, str]]: | |
""" | |
Get the login status of the current user. | |
Returns: | |
login_status (bool): True if the current user is logged in, False otherwise. | |
""" | |
return {"login_status": bool(self.authenticated)} | |
def post_tweet( | |
self, content: str, tags: List[str] = [], mentions: List[str] = [] | |
) -> Dict[str, Union[int, str, List[str]]]: | |
""" | |
Post a tweet for the authenticated user. | |
Args: | |
content (str): Content of the tweet. | |
tags (List[str]): [Optional] List of tags for the tweet. Tag name should start with #. This is only relevant if the user wants to add tags to the tweet. | |
mentions (List[str]): [Optional] List of users mentioned in the tweet. Mention name should start with @. This is only relevant if the user wants to add mentions to the tweet. | |
Returns: | |
id (int): ID of the posted tweet. | |
username (str): Username of the poster. | |
content (str): Content of the tweet. | |
tags (List[str]): List of tags associated with the tweet. | |
mentions (List[str]): List of users mentioned in the tweet. | |
""" | |
if not self.authenticated: | |
return {"error": "User not authenticated. Please authenticate before posting."} | |
tweet = { | |
"id": self.tweet_counter, | |
"username": self.username, | |
"content": content, | |
"tags": tags, | |
"mentions": mentions, | |
} | |
self.tweets[self.tweet_counter] = tweet | |
self.tweet_counter += 1 | |
return tweet | |
def retweet(self, tweet_id: int) -> Dict[str, str]: | |
""" | |
Retweet a tweet for the authenticated user. | |
Args: | |
tweet_id (int): ID of the tweet to retweet. | |
Returns: | |
retweet_status (str): Status of the retweet action. | |
""" | |
if not self.authenticated: | |
return {"error": "User not authenticated. Please authenticate before retweeting."} | |
if tweet_id not in self.tweets: | |
return {"error": f"Tweet with ID {tweet_id} not found."} | |
if self.username not in self.retweets: | |
self.retweets[self.username] = [] | |
if tweet_id in self.retweets[self.username]: | |
return {"retweet_status": "Already retweeted"} | |
self.retweets[self.username].append(tweet_id) | |
return {"retweet_status": "Successfully retweeted"} | |
def comment(self, tweet_id: int, comment_content: str) -> Dict[str, str]: | |
""" | |
Comment on a tweet for the authenticated user. | |
Args: | |
tweet_id (int): ID of the tweet to comment on. | |
comment_content (str): Content of the comment. | |
Returns: | |
comment_status (str): Status of the comment action. | |
""" | |
if not self.authenticated: | |
raise {"error": "User not authenticated. Please authenticate before commenting."} | |
if tweet_id not in self.tweets: | |
return {"error": f"Tweet with ID {tweet_id} not found."} | |
if tweet_id not in self.comments: | |
self.comments[tweet_id] = [] | |
self.comments[tweet_id].append( | |
{"username": self.username, "content": comment_content} | |
) | |
return {"comment_status": "Comment added successfully"} | |
def mention(self, tweet_id: int, mentioned_usernames: List[str]) -> Dict[str, str]: | |
""" | |
Mention specified users in a tweet. | |
Args: | |
tweet_id (int): ID of the tweet where users are mentioned. | |
mentioned_usernames (List[str]): List of usernames to be mentioned. | |
Returns: | |
mention_status (str): Status of the mention action. | |
""" | |
if tweet_id not in self.tweets: | |
return {"error": f"Tweet with ID {tweet_id} not found."} | |
tweet = self.tweets[tweet_id] | |
tweet["mentions"].extend(mentioned_usernames) | |
return {"mention_status": "Users mentioned successfully"} | |
def follow_user(self, username_to_follow: str) -> Dict[str, bool]: | |
""" | |
Follow a user for the authenticated user. | |
Args: | |
username_to_follow (str): Username of the user to follow. | |
Returns: | |
follow_status (bool): True if followed, False if already following. | |
""" | |
if not self.authenticated: | |
return {"error": "User not authenticated. Please authenticate before following."} | |
if username_to_follow in self.following_list: | |
return {"follow_status": False} | |
self.following_list.append(username_to_follow) | |
return {"follow_status": True} | |
def list_all_following(self) -> List[str]: | |
""" | |
List all users that the authenticated user is following. | |
Returns: | |
following_list (List[str]): List of all users that the authenticated user is following. | |
""" | |
if not self.authenticated: | |
return {"error": "User not authenticated. Please authenticate before listing following."} | |
return self.following_list | |
def unfollow_user(self, username_to_unfollow: str) -> Dict[str, bool]: | |
""" | |
Unfollow a user for the authenticated user. | |
Args: | |
username_to_unfollow (str): Username of the user to unfollow. | |
Returns: | |
unfollow_status (bool): True if unfollowed, False if not following. | |
""" | |
if not self.authenticated: | |
return {"error": "User not authenticated. Please authenticate before unfollowing."} | |
if username_to_unfollow not in self.following_list: | |
return {"unfollow_status": False} | |
self.following_list.remove(username_to_unfollow) | |
return {"unfollow_status": True} | |
def get_tweet(self, tweet_id: int) -> Dict[str, Union[int, str, List[str]]]: | |
""" | |
Retrieve a specific tweet. | |
Args: | |
tweet_id (int): ID of the tweet to retrieve. | |
Returns: | |
id (int): ID of the retrieved tweet. | |
username (str): Username of the tweet's author. | |
content (str): Content of the tweet. | |
tags (List[str]): List of tags associated with the tweet. | |
mentions (List[str]): List of users mentioned in the tweet. | |
""" | |
if tweet_id not in self.tweets: | |
return {"error": f"Tweet with ID {tweet_id} not found."} | |
return self.tweets[tweet_id] | |
def get_user_tweets(self, username: str) -> List[Dict[str, Union[int, str, List[str]]]]: | |
""" | |
Retrieve all tweets from a specific user. | |
Args: | |
username (str): Username of the user whose tweets to retrieve. | |
Returns: | |
user_tweets (List[Dict]): List of dictionaries, each containing tweet information. | |
- id (int): ID of the retrieved tweet. | |
- username (str): Username of the tweet's author. | |
- content (str): Content of the tweet. | |
- tags (List[str]): List of tags associated with the tweet. | |
- mentions (List[str]): List of users mentioned in the tweet. | |
""" | |
return [tweet for tweet in self.tweets.values() if tweet["username"] == username] | |
def search_tweets(self, keyword: str) -> List[Dict[str, Union[int, str, List[str]]]]: | |
""" | |
Search for tweets containing a specific keyword. | |
Args: | |
keyword (str): Keyword to search for in the content of the tweets. | |
Returns: | |
matching_tweets (List[Dict]): List of dictionaries, each containing tweet information. | |
- id (int): ID of the retrieved tweet. | |
- username (str): Username of the tweet's author. | |
- content (str): Content of the tweet. | |
- tags (List[str]): List of tags associated with the tweet. | |
- mentions (List[str]): List of users mentioned in the tweet. | |
""" | |
return [ | |
tweet | |
for tweet in self.tweets.values() | |
if keyword.lower() in tweet["content"].lower() | |
or keyword.lower() in [tag.lower() for tag in tweet["tags"]] | |
] | |
def get_tweet_comments(self, tweet_id: int) -> List[Dict[str, str]]: | |
""" | |
Retrieve all comments for a specific tweet. | |
Args: | |
tweet_id (int): ID of the tweet to retrieve comments for. | |
Returns: | |
comments (List[Dict]): List of dictionaries, each containing comment information. | |
- username (str): Username of the commenter. | |
- content (str): Content of the comment. | |
""" | |
if tweet_id not in self.tweets: | |
return {"error": f"Tweet with ID {tweet_id} not found."} | |
return self.comments.get(tweet_id, []) | |
def get_user_stats(self, username: str) -> Dict[str, int]: | |
""" | |
Get statistics for a specific user. | |
Args: | |
username (str): Username of the user to get statistics for. | |
Returns: | |
tweet_count (int): Number of tweets posted by the user. | |
following_count (int): Number of users the specified user is following. | |
retweet_count (int): Number of retweets made by the user. | |
""" | |
tweet_count = len( | |
[tweet for tweet in self.tweets.values() if tweet["username"] == username] | |
) | |
following_count = len(self.following_list) if username == self.username else 0 | |
retweet_count = len(self.retweets.get(username, [])) | |
return { | |
"tweet_count": tweet_count, | |
"following_count": following_count, | |
"retweet_count": retweet_count, | |
} | |