Huanzhi (Hans) Mao
init
4d1746c
raw
history blame
12.5 kB
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,
}