Skip to content

Commit

Permalink
add missing string id representation to models #116
Browse files Browse the repository at this point in the history
  • Loading branch information
vladkens committed Feb 10, 2024
1 parent 748ceae commit 277ebd1
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 8 deletions.
Binary file added .github/example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
Twitter GraphQL API implementation with [SNScrape](https://github.com/JustAnotherArchivist/snscrape) data models.

<div align="center">
<img src="https://miro.medium.com/v2/resize:fit:1400/format:webp/1*0erkeMBhl_qqRofIeU5jMQ.png" alt="example of cli usage" width="560px">
<img src=".github/example.png" alt="example of cli usage" width="560px">
</div>

## Install
Expand Down
39 changes: 33 additions & 6 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from twscrape import API, gather
from twscrape.logger import set_log_level
from twscrape.models import Tweet, User, parse_tweet
from twscrape.models import Tweet, User, UserRef, parse_tweet

BASE_DIR = os.path.dirname(__file__)
DATA_DIR = os.path.join(BASE_DIR, "mocked-data")
Expand Down Expand Up @@ -49,18 +49,33 @@ async def cb_gen(*args, **kwargs):

def check_tweet(doc: Tweet | None):
assert doc is not None
assert doc.id is not None
assert doc.id_str is not None
assert isinstance(doc.id, int)
assert isinstance(doc.id_str, str)
assert doc.id == int(doc.id_str)
assert str(doc.id) == doc.id_str

assert doc.url is not None
assert doc.id_str in doc.url
assert doc.user is not None

assert isinstance(doc.conversationId, int)
assert isinstance(doc.conversationIdStr, str)
assert str(doc.conversationId) == doc.conversationIdStr

if doc.inReplyToTweetId is not None:
assert isinstance(doc.inReplyToTweetId, int)
assert isinstance(doc.inReplyToTweetIdStr, str)
assert str(doc.inReplyToTweetId) == doc.inReplyToTweetIdStr

if doc.inReplyToUser:
check_user_ref(doc.inReplyToUser)

if doc.mentionedUsers:
for x in doc.mentionedUsers:
check_user_ref(x)

obj = doc.dict()
assert doc.id == obj["id"]
assert doc.id_str == obj["id_str"]
assert doc.user.id == obj["user"]["id"]

assert "url" in obj
Expand Down Expand Up @@ -104,10 +119,9 @@ def check_tweet(doc: Tweet | None):

def check_user(doc: User):
assert doc.id is not None
assert doc.id_str is not None
assert isinstance(doc.id, int)
assert isinstance(doc.id_str, str)
assert doc.id == int(doc.id_str)
assert str(doc.id) == doc.id_str

assert doc.username is not None
assert doc.descriptionLinks is not None
Expand All @@ -127,6 +141,19 @@ def check_user(doc: User):
assert str(doc.id) in txt


def check_user_ref(doc: UserRef):
assert isinstance(doc.id, int)
assert isinstance(doc.id_str, str)
assert str(doc.id) == doc.id_str

assert doc.username is not None
assert doc.displayname is not None

obj = doc.dict()
assert doc.id == obj["id"]
assert doc.id_str == obj["id_str"]


async def test_search():
api = API()
mock_rep(api.search_raw, "raw_search", as_generator=True)
Expand Down
12 changes: 11 additions & 1 deletion twscrape/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,19 @@ def parse(obj: dict):
@dataclass
class UserRef(JSONTrait):
id: int
id_str: str
username: str
displayname: str
_type: str = "snscrape.modules.twitter.UserRef"

@staticmethod
def parse(obj: dict):
return UserRef(id=int(obj["id_str"]), username=obj["screen_name"], displayname=obj["name"])
return UserRef(
id=int(obj["id_str"]),
id_str=obj["id_str"],
username=obj["screen_name"],
displayname=obj["name"],
)


@dataclass
Expand Down Expand Up @@ -163,6 +169,7 @@ class Tweet(JSONTrait):
likeCount: int
quoteCount: int
conversationId: int
conversationIdStr: str
hashtags: list[str]
cashtags: list[str]
mentionedUsers: list[UserRef]
Expand All @@ -173,6 +180,7 @@ class Tweet(JSONTrait):
place: Optional[Place] = None
coordinates: Optional[Coordinates] = None
inReplyToTweetId: int | None = None
inReplyToTweetIdStr: str | None = None
inReplyToUser: UserRef | None = None
source: str | None = None
sourceUrl: str | None = None
Expand Down Expand Up @@ -217,6 +225,7 @@ def parse(obj: dict, res: dict):
likeCount=obj["favorite_count"],
quoteCount=obj["quote_count"],
conversationId=int(obj["conversation_id_str"]),
conversationIdStr=obj["conversation_id_str"],
hashtags=[x["text"] for x in get_or(obj, "entities.hashtags", [])],
cashtags=[x["text"] for x in get_or(obj, "entities.symbols", [])],
mentionedUsers=[UserRef.parse(x) for x in get_or(obj, "entities.user_mentions", [])],
Expand All @@ -229,6 +238,7 @@ def parse(obj: dict, res: dict):
place=Place.parse(obj["place"]) if obj.get("place") else None,
coordinates=Coordinates.parse(obj),
inReplyToTweetId=int_or(obj, "in_reply_to_status_id_str"),
inReplyToTweetIdStr=get_or(obj, "in_reply_to_status_id_str"),
inReplyToUser=_get_reply_user(obj, res),
source=obj.get("source", None),
sourceUrl=_get_source_url(obj),
Expand Down

0 comments on commit 277ebd1

Please sign in to comment.