Skip to content

Commit

Permalink
Added get_place_trends, get_available_locations, TweetEngagementEvent…
Browse files Browse the repository at this point in the history
….reply_count
  • Loading branch information
d60 committed May 4, 2024
1 parent 9de6674 commit f23423a
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 9 deletions.
2 changes: 1 addition & 1 deletion twikit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
A Python library for interacting with the Twitter API.
"""

__version__ = '1.6.0'
__version__ = '1.6.1'

from .bookmark import BookmarkFolder
from .client import Client
Expand Down
32 changes: 31 additions & 1 deletion twikit/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from .list import List
from .message import Message
from .notification import Notification
from .trend import Trend
from .trend import PlaceTrend, PlaceTrends, Location, Trend
from .streaming import Payload, StreamingSession, _payload_from_data
from .tweet import CommunityNote, Poll, ScheduledTweet, Tweet, tweet_from_data
from .user import User
Expand Down Expand Up @@ -2739,6 +2739,36 @@ def get_trends(

return results

def get_available_locations(self) -> list[Location]:
"""
Retrieves locations where trends can be retrieved.
Returns
-------
list[:class:`.Location`]
"""
response = self.http.get(
Endpoint.AVAILABLE_LOCATIONS,
headers=self._base_headers
).json()
return [Location(self, data) for data in response]

def get_place_trends(self, woeid: int) -> PlaceTrends:
"""
Retrieves the top 50 trending topics for a specific id.
You can get available woeid using
:attr:`.Client.get_available_locations`.
"""
response = self.http.get(
Endpoint.PLACE_TRENDS,
params={'id': woeid},
headers=self._base_headers
).json()
trend_data = response[0]
trends = [PlaceTrend(self, data) for data in trend_data['trends']]
trend_data['trends'] = trends
return trend_data

def _get_user_friendship(
self,
user_id: str,
Expand Down
6 changes: 4 additions & 2 deletions twikit/streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,15 @@ def _event_from_data(name: str, data: dict) -> StreamEventType:
like_count = data.get('like_count')
retweet_count = data.get('retweet_count')
quote_count = data.get('quote_count')
reply_count = data.get('reply_count')
view_count = None
view_count_state = None
if 'view_count_info' in data:
view_count = data['view_count_info']['count']
view_count_state = data['view_count_info']['state']
return TweetEngagementEvent(
like_count, retweet_count,
view_count, view_count_state, quote_count
like_count, retweet_count, view_count,
view_count_state, quote_count, reply_count
)

if name == 'dm_update':
Expand Down Expand Up @@ -181,6 +182,7 @@ class TweetEngagementEvent(NamedTuple):
view_count: str | None #: The number of views of the tweet.
view_count_state: str | None #: The state of view count.
quote_count: int | None #: The number of quotes of the tweet.
reply_count: int | None # The number of Replies of the tweet.


class DMUpdateEvent(NamedTuple):
Expand Down
60 changes: 59 additions & 1 deletion twikit/trend.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import TYPE_CHECKING
from typing import TypedDict, TYPE_CHECKING

if TYPE_CHECKING:
from .client import Client
Expand Down Expand Up @@ -33,3 +33,61 @@ def __init__(self, client: Client, data: dict) -> None:

def __repr__(self) -> str:
return f'<Trend name="{self.name}">'


class PlaceTrends(TypedDict):
trends: list[PlaceTrend]
as_of: str
created_at: str
locations: dict


class PlaceTrend:
"""
Attributes
----------
name : :class:`str`
The name of the trend.
url : :class:`str`
The URL to view the trend.
query : :class:`str`
The search query corresponding to the trend.
tweet_volume : :class:`int`
The volume of tweets associated with the trend.
"""
def __init__(self, client: Client, data: dict) -> None:
self._client = client

self.name: str = data['name']
self.url: str = data['url']
self.promoted_content: None = data['promoted_content']
self.query: str = data['query']
self.tweet_volume: int = data['tweet_volume']

def __repr__(self) -> str:
return f'<PlaceTrend name="{self.name}">'


class Location:
def __init__(self, client: Client, data: dict) -> None:
self._client = client

self.woeid: int = data['woeid']
self.country: str = data['country']
self.country_code: str = data['countryCode']
self.name: str = data['name']
self.parentid: int = data['parentid']
self.placeType: dict = data['placeType']
self.url: str = data['url']

def get_trends(self) -> PlaceTrends:
return self._client.get_place_trends(self.woeid)

def __repr__(self) -> str:
return f'<Location name="{self.name}" woeid={self.woeid}>'

def __eq__(self, __value: object) -> bool:
return isinstance(__value, Location) and self.woeid == __value.woeid

def __ne__(self, __value: object) -> bool:
return not self == __value
32 changes: 31 additions & 1 deletion twikit/twikit_async/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
from .list import List
from .message import Message
from .notification import Notification
from .trend import Trend
from .trend import Location, PlaceTrend, PlaceTrends, Trend
from .streaming import Payload, StreamingSession, _payload_from_data
from .tweet import CommunityNote, Poll, ScheduledTweet, Tweet, tweet_from_data
from .user import User
Expand Down Expand Up @@ -2759,6 +2759,36 @@ async def get_trends(

return results

async def get_available_locations(self) -> list[Location]:
"""
Retrieves locations where trends can be retrieved.
Returns
-------
list[:class:`.Location`]
"""
response = (await self.http.get(
Endpoint.AVAILABLE_LOCATIONS,
headers=self._base_headers
)).json()
return [Location(self, data) for data in response]

async def get_place_trends(self, woeid: int) -> PlaceTrends:
"""
Retrieves the top 50 trending topics for a specific id.
You can get available woeid using
:attr:`.Client.get_available_locations`.
"""
response = (await self.http.get(
Endpoint.PLACE_TRENDS,
params={'id': woeid},
headers=self._base_headers
)).json()
trend_data = response[0]
trends = [PlaceTrend(self, data) for data in trend_data['trends']]
trend_data['trends'] = trends
return trend_data

async def _get_user_friendship(
self,
user_id: str,
Expand Down
6 changes: 4 additions & 2 deletions twikit/twikit_async/streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,15 @@ def _event_from_data(name: str, data: dict) -> StreamEventType:
like_count = data.get('like_count')
retweet_count = data.get('retweet_count')
quote_count = data.get('quote_count')
reply_count = data.get('reply_count')
view_count = None
view_count_state = None
if 'view_count_info' in data:
view_count = data['view_count_info']['count']
view_count_state = data['view_count_info']['state']
return TweetEngagementEvent(
like_count, retweet_count,
view_count, view_count_state, quote_count
like_count, retweet_count, view_count,
view_count_state, quote_count, reply_count
)

if name == 'dm_update':
Expand Down Expand Up @@ -185,6 +186,7 @@ class TweetEngagementEvent(NamedTuple):
view_count: str | None #: The number of views of the tweet.
view_count_state: str | None #: The state of view count.
quote_count: int | None #: The number of quotes of the tweet.
reply_count: int | None # The number of Replies of the tweet.


class DMUpdateEvent(NamedTuple):
Expand Down
60 changes: 59 additions & 1 deletion twikit/twikit_async/trend.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import TYPE_CHECKING
from typing import TypedDict, TYPE_CHECKING

if TYPE_CHECKING:
from .client import Client
Expand Down Expand Up @@ -33,3 +33,61 @@ def __init__(self, client: Client, data: dict) -> None:

def __repr__(self) -> str:
return f'<Trend name="{self.name}">'


class PlaceTrends(TypedDict):
trends: list[PlaceTrend]
as_of: str
created_at: str
locations: dict


class PlaceTrend:
"""
Attributes
----------
name : :class:`str`
The name of the trend.
url : :class:`str`
The URL to view the trend.
query : :class:`str`
The search query corresponding to the trend.
tweet_volume : :class:`int`
The volume of tweets associated with the trend.
"""
def __init__(self, client: Client, data: dict) -> None:
self._client = client

self.name: str = data['name']
self.url: str = data['url']
self.promoted_content: None = data['promoted_content']
self.query: str = data['query']
self.tweet_volume: int = data['tweet_volume']

def __repr__(self) -> str:
return f'<PlaceTrend name="{self.name}">'


class Location:
def __init__(self, client: Client, data: dict) -> None:
self._client = client

self.woeid: int = data['woeid']
self.country: str = data['country']
self.country_code: str = data['countryCode']
self.name: str = data['name']
self.parentid: int = data['parentid']
self.placeType: dict = data['placeType']
self.url: str = data['url']

async def get_trends(self) -> PlaceTrends:
return await self._client.get_place_trends(self.woeid)

def __repr__(self) -> str:
return f'<Location name="{self.name}" woeid={self.woeid}>'

def __eq__(self, __value: object) -> bool:
return isinstance(__value, Location) and self.woeid == __value.woeid

def __ne__(self, __value: object) -> bool:
return not self == __value
1 change: 1 addition & 0 deletions twikit/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ class Endpoint:
BOOKMARK_FOLDER_TIMELINE = 'https://twitter.com/i/api/graphql/8HoabOvl7jl9IC1Aixj-vg/BookmarkFolderTimeline'
BOOKMARK_TO_FOLDER = 'https://twitter.com/i/api/graphql/4KHZvvNbHNf07bsgnL9gWA/bookmarkTweetToFolder'
PLACE_TRENDS = 'https://api.twitter.com/1.1/trends/place.json'
AVAILABLE_LOCATIONS = 'https://api.twitter.com/1.1/trends/available.json'
EVENTS = 'https://api.twitter.com/live_pipeline/events'
UPDATE_SUBSCRIPTIONS = 'https://api.twitter.com/1.1/live_pipeline/update_subscriptions'

Expand Down

0 comments on commit f23423a

Please sign in to comment.