-
-
Notifications
You must be signed in to change notification settings - Fork 423
Added functionality for fetching user_mentions
#367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Reviewer's GuideIntroduces a new get_user_mentions method in the client to fetch tweets mentioning a given handle by leveraging the existing search_tweet function, filtering the results for the target handle, sorting them by ID, and returning a list of Tweet objects. Sequence diagram for get_user_mentions methodsequenceDiagram
actor User
participant Client as Client
participant TwitterAPI as Twitter API
participant Tweet as Tweet Objects
User->>Client: get_user_mentions(handle, search_count)
Client->>Client: search_tweet(f"@{handle}", "Latest", count=search_count)
Client->>TwitterAPI: Send search request
TwitterAPI-->>Client: Return tweets
loop For each tweet in result
Client->>Tweet: Check if tweet mentions handle
alt Tweet contains @handle
Client->>Client: Add tweet to mentions
end
end
Client->>Client: Sort mentions by tweet id
Client-->>User: Return list of mentions
Class diagram for Client with new get_user_mentions methodclassDiagram
class Client {
+async get_user_mentions(handle: str, search_count: int = 20) List[Tweet]
+async search_tweet(...)
...
}
class Tweet {
+id: int
+full_text: str
+text: str
...
}
Client --> Tweet : returns List[Tweet]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
WalkthroughA new asynchronous method Changes
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @Madhav-MKNC - I've reviewed your changes - here's some feedback:
- The function signature claims to return List[Tweet] but you’re actually returning List[Tuple[str, Tweet]]—either update the type hint or unpack the tuples to return only the Tweet objects.
- Sorting by int-casted tweet_id strings works but could be more straightforward and reliable by sorting on the tweet.id or tweet.created_at attribute directly.
- The substring-based mention check (f"@{handle.lower()}" in text) may yield false positives in URLs or longer words—consider using a regex with word boundaries to match standalone mentions.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The function signature claims to return List[Tweet] but you’re actually returning List[Tuple[str, Tweet]]—either update the type hint or unpack the tuples to return only the Tweet objects.
- Sorting by int-casted tweet_id strings works but could be more straightforward and reliable by sorting on the tweet.id or tweet.created_at attribute directly.
- The substring-based mention check (f"@{handle.lower()}" in text) may yield false positives in URLs or longer words—consider using a regex with word boundaries to match standalone mentions.
## Individual Comments
### Comment 1
<location> `twikit/client/client.py:788` </location>
<code_context>
previous_cursor
)
+ async def get_user_mentions(
+ self,
+ handle: str,
</code_context>
<issue_to_address>
The method returns a list of (tweet_id, tweet) tuples, not Tweet objects as the docstring and type hint suggest.
Please update the docstring and type hint to match the actual return type, or modify the method to return a List[Tweet] as documented.
</issue_to_address>
### Comment 2
<location> `twikit/client/client.py:821` </location>
<code_context>
+ """
+ result = await self.search_tweet(f"@{handle}", "Latest", count=search_count)
+ mentions = []
+ for tweet in result:
+ tweet_id = str(tweet.id)
+ if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower():
+ mentions.append((tweet_id, tweet))
+ mentions.sort(key=lambda x: int(x[0]))
</code_context>
<issue_to_address>
The mention detection logic may produce false positives for substrings and does not account for word boundaries.
Using a substring search can incorrectly match partial usernames (e.g., '@elon' in '@elona'). Use a regular expression with word boundaries or stricter logic to ensure only exact mentions are detected.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
result = await self.search_tweet(f"@{handle}", "Latest", count=search_count)
mentions = []
for tweet in result:
tweet_id = str(tweet.id)
if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower():
mentions.append((tweet_id, tweet))
mentions.sort(key=lambda x: int(x[0]))
=======
import re
result = await self.search_tweet(f"@{handle}", "Latest", count=search_count)
mentions = []
mention_pattern = re.compile(rf"@{re.escape(handle)}\b", re.IGNORECASE)
for tweet in result:
tweet_id = str(tweet.id)
text = (tweet.full_text or tweet.text or "").strip()
if mention_pattern.search(text):
mentions.append((tweet_id, tweet))
mentions.sort(key=lambda x: int(x[0]))
>>>>>>> REPLACE
</suggested_fix>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
previous_cursor | ||
) | ||
|
||
async def get_user_mentions( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: The method returns a list of (tweet_id, tweet) tuples, not Tweet objects as the docstring and type hint suggest.
Please update the docstring and type hint to match the actual return type, or modify the method to return a List[Tweet] as documented.
twikit/client/client.py
Outdated
result = await self.search_tweet(f"@{handle}", "Latest", count=search_count) | ||
mentions = [] | ||
for tweet in result: | ||
tweet_id = str(tweet.id) | ||
if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower(): | ||
mentions.append((tweet_id, tweet)) | ||
mentions.sort(key=lambda x: int(x[0])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): The mention detection logic may produce false positives for substrings and does not account for word boundaries.
Using a substring search can incorrectly match partial usernames (e.g., '@elon' in '@elona'). Use a regular expression with word boundaries or stricter logic to ensure only exact mentions are detected.
result = await self.search_tweet(f"@{handle}", "Latest", count=search_count) | |
mentions = [] | |
for tweet in result: | |
tweet_id = str(tweet.id) | |
if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower(): | |
mentions.append((tweet_id, tweet)) | |
mentions.sort(key=lambda x: int(x[0])) | |
import re | |
result = await self.search_tweet(f"@{handle}", "Latest", count=search_count) | |
mentions = [] | |
mention_pattern = re.compile(rf"@{re.escape(handle)}\b", re.IGNORECASE) | |
for tweet in result: | |
tweet_id = str(tweet.id) | |
text = (tweet.full_text or tweet.text or "").strip() | |
if mention_pattern.search(text): | |
mentions.append((tweet_id, tweet)) | |
mentions.sort(key=lambda x: int(x[0])) |
twikit/client/client.py
Outdated
mentions = [] | ||
for tweet in result: | ||
tweet_id = str(tweet.id) | ||
if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower(): | ||
mentions.append((tweet_id, tweet)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): We've found these issues:
- Convert for loop into list comprehension (
list-comprehension
) - Move assignments closer to their usage (
move-assign
) - Inline variable that is only used once (
inline-variable
)
mentions = [] | |
for tweet in result: | |
tweet_id = str(tweet.id) | |
if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower(): | |
mentions.append((tweet_id, tweet)) | |
mentions = [ | |
(str(tweet.id), tweet) | |
for tweet in result | |
if f"@{handle.lower()}" | |
in (tweet.full_text or tweet.text or "").strip().lower() | |
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
twikit/client/client.py (1)
10-10
: Add missingList
import for type annotations.The
get_user_mentions
method usesList[Tweet]
in its return type annotation, butList
is not imported from thetyping
module.-from typing import Any, AsyncGenerator, Literal +from typing import Any, AsyncGenerator, List, Literal
🧹 Nitpick comments (1)
twikit/client/client.py (1)
819-826
: Consider improving search accuracy and efficiency.The current implementation searches for "@handle" and then manually filters results, which may include false positives and could be inefficient.
Consider these improvements:
- The search might return tweets containing "@handle" in contexts other than actual mentions
- Manual filtering after fetching could be wasteful if most results don't match
- The return format (tuples) seems unnecessary - users likely just want the Tweet objects
Alternative implementation that returns
List[Tweet]
directly:- result = await self.search_tweet(f"@{handle}", "Latest", count=search_count) - mentions = [] - for tweet in result: - tweet_id = str(tweet.id) - if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower(): - mentions.append((tweet_id, tweet)) - mentions.sort(key=lambda x: int(x[0])) - return mentions + result = await self.search_tweet(f"@{handle}", "Latest", count=search_count) + mentions = [] + for tweet in result: + if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower(): + mentions.append(tweet) + mentions.sort(key=lambda x: int(x.id)) + return mentions
>>> mentions = await client.get_user_mentions('5mknc5', search_count=30) | ||
>>> for mention in mentions: | ||
... print(mention) | ||
<Tweet id="..."> | ||
<Tweet id="..."> | ||
... | ||
... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Update documentation examples to match actual return format.
The examples show the result as <Tweet id="...">
but the method actually returns tuples of (tweet_id, tweet)
.
- >>> mentions = await client.get_user_mentions('5mknc5', search_count=30)
- >>> for mention in mentions:
- ... print(mention)
- <Tweet id="...">
- <Tweet id="...">
+ >>> mentions = await client.get_user_mentions('5mknc5', search_count=30)
+ >>> for tweet_id, tweet in mentions:
+ ... print(f"Tweet ID: {tweet_id}, Tweet: {tweet}")
+ Tweet ID: 123456789, Tweet: <Tweet id="123456789">
+ Tweet ID: 123456790, Tweet: <Tweet id="123456790">
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
>>> mentions = await client.get_user_mentions('5mknc5', search_count=30) | |
>>> for mention in mentions: | |
... print(mention) | |
<Tweet id="..."> | |
<Tweet id="..."> | |
... | |
... | |
>>> mentions = await client.get_user_mentions('5mknc5', search_count=30) | |
>>> for tweet_id, tweet in mentions: | |
... print(f"Tweet ID: {tweet_id}, Tweet: {tweet}") | |
Tweet ID: 123456789, Tweet: <Tweet id="123456789"> | |
Tweet ID: 123456790, Tweet: <Tweet id="123456790"> |
🤖 Prompt for AI Agents
In twikit/client/client.py around lines 810 to 816, the documentation example
incorrectly shows the method returning <Tweet id="..."> objects, but it actually
returns tuples of (tweet_id, tweet). Update the example to reflect this by
showing the iteration over mentions unpacking or accessing the tuple elements,
demonstrating the correct return format.
self, | ||
handle: str, | ||
search_count: int = 20 | ||
) -> List[Tweet]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix return type annotation to match actual implementation.
The method declares it returns List[Tweet]
but actually returns List[Tuple[str, Tweet]]
(tuples of tweet ID and tweet object).
-) -> List[Tweet]:
+) -> List[Tuple[str, Tweet]]:
You'll also need to import Tuple
:
-from typing import Any, AsyncGenerator, List, Literal
+from typing import Any, AsyncGenerator, List, Literal, Tuple
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
) -> List[Tweet]: | |
# at the top of twikit/client/client.py | |
-from typing import Any, AsyncGenerator, List, Literal | |
+from typing import Any, AsyncGenerator, List, Literal, Tuple | |
# … later in the file, around line 792 … | |
- ) -> List[Tweet]: | |
+ ) -> List[Tuple[str, Tweet]]: |
🤖 Prompt for AI Agents
In twikit/client/client.py at line 792, the return type annotation is
incorrectly specified as List[Tweet] while the method actually returns
List[Tuple[str, Tweet]]. Update the return type annotation to List[Tuple[str,
Tweet]] to accurately reflect the returned data structure. Additionally, add an
import statement for Tuple from the typing module at the top of the file if it
is not already imported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
twikit/client/client.py (1)
10-10
: Add missing import for List type annotation.The method uses
List[Tweet]
as return type annotation butList
is not imported from typing.Add the import:
-from typing import Any, AsyncGenerator, Literal +from typing import Any, AsyncGenerator, List, Literal
♻️ Duplicate comments (1)
twikit/client/client.py (1)
823-823
: Improve mention detection to avoid false positives.The current substring search can incorrectly match partial usernames (e.g., '@elon' would match '@ElonMusk'). Consider using word boundaries for more accurate detection.
Use regex with word boundaries for precise matching:
+import re + async def get_user_mentions( self, handle: str, search_count: int = 20 ) -> List[Tweet]: # ... existing docstring ... result = await self.search_tweet(f"@{handle}", "Latest", count=search_count) + mention_pattern = re.compile(rf"\b@{re.escape(handle)}\b", re.IGNORECASE) mentions = [] for tweet in result: - if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower(): + text = (tweet.full_text or tweet.text or "").strip() + if mention_pattern.search(text): mentions.append(tweet)
🧹 Nitpick comments (1)
twikit/client/client.py (1)
819-826
: Consider using list comprehension for cleaner code.The filtering and sorting logic can be made more concise and readable.
- result = await self.search_tweet(f"@{handle}", "Latest", count=search_count) - mentions = [] - for tweet in result: - if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower(): - mentions.append(tweet) - mentions.sort(key=lambda x: int(x.id)) - return mentions + result = await self.search_tweet(f"@{handle}", "Latest", count=search_count) + mentions = [ + tweet for tweet in result + if f"@{handle.lower()}" in (tweet.full_text or tweet.text or "").strip().lower() + ] + return sorted(mentions, key=lambda x: int(x.id))
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
twikit/client/client.py
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
twikit/client/client.py (2)
twikit/tweet.py (4)
Tweet
(19-560)id
(112-113)full_text
(225-229)text
(120-121)twikit/community.py (1)
search_tweet
(244-269)
🪛 Ruff (0.11.9)
twikit/client/client.py
822-822: Local variable tweet_id
is assigned to but never used
Remove assignment to unused variable tweet_id
(F841)
🪛 Flake8 (7.2.0)
twikit/client/client.py
[error] 822-822: local variable 'tweet_id' is assigned to but never used
(F841)
Added get_user_mentions functionality (X API v2).
Example usage:
Output:
Summary by Sourcery
Introduce get_user_mentions method to fetch and filter tweets mentioning a specified user handle and return them as sorted Tweet objects.
New Features:
Summary by CodeRabbit