From 49156cb9f1d74d709480b8d746b01e755f5c312b Mon Sep 17 00:00:00 2001 From: Harmon Date: Mon, 20 Sep 2021 14:24:29 -0500 Subject: [PATCH] Add Client.get_all_tweets_count and Client.get_recent_tweets_count --- cassettes/test_get_recent_tweets_count.yaml | 82 ++++++++++++ docs/client.rst | 7 + tests/test_client.py | 6 + tweepy/client.py | 137 ++++++++++++++++++++ 4 files changed, 232 insertions(+) create mode 100644 cassettes/test_get_recent_tweets_count.yaml diff --git a/cassettes/test_get_recent_tweets_count.yaml b/cassettes/test_get_recent_tweets_count.yaml new file mode 100644 index 0000000..aa51691 --- /dev/null +++ b/cassettes/test_get_recent_tweets_count.yaml @@ -0,0 +1,82 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - Python/3.9.6 Requests/2.25.1 Tweepy/4.0.0-alpha + method: GET + uri: https://api.twitter.com/2/tweets/counts/recent?query=Tweepy + response: + body: + string: !!binary | + H4sIAAAAAAAAAJybwW7bMBBE/0XnpJBkiyL9HTm1KAKj8a1NgFZBD4b/vRGKHqRZ8w0L5GjNW4w5 + mwFtX7uX83LuTl+u3eX1pTt1Yz8Oj315HA5PY3/q179Pfd9/7h66X8v557J9yVBOQz6Nx38vWX5f + Lsvzt7f3148XDreHSHVA1T3YUR1ZdaiojrHqgVXHxlmPTz37ugfjrB+q5KuCHVXyVcGOA+Srgp1Z + j6z6H75OrHqsqKZYNbHq1O7rzKqpXTWz6lxRPcSqhVVz86wDZUvBxqwDZ2sP3qgeY1XO1h7sOMDZ + 2oMdVc7WHuyocrb2YEeVs7UHO2eAs7UHO7NytvZgR5WztQcbmxD7gIKNWbEPKNh4t7APKNiZlbPV + 3Acm7gMK3qhOsSr5quCNao5VyVcFO7OSrwrG8zpxH1Cwo0o7S8HOGaCdpWBMwcR9QMHOrLSzFOyc + AdpZCjbeLewDCjYcwD6gYOyEE/cBBWPLmLgPKNhxgLPV3Acm7gMK3qjOsSpnq9oH7pwszlZzH5i4 + DyjYyBb2AQUbJwv7gIINB7APKNjYhNgHFGycAewDCkbVxH1AwbhdEvcBBTuzkq8KxjOQuA8o2FGl + naVgR5V2loLxvCbuAwp2ZqWdpWDnDNDOUrAzK+0sBRu+Yh9QsJEt7AMKxv2auA8oGP8XJO4DCjbO + APYBBTuqnK3m+4HEfUDBjipnq9oH7pxXzla1D9xR5Ww13w8k7gMKNlKAfUDBzqycreY+kLgPKBhP + 1sx9QMF4BmbuAwp2ZiVfFYy+ztwHFOw4QDtLwXheZ+4DCnZ8pZ2lYMcB2lkKdmalnaVgZ1baWQo2 + VLEPKNhR5WxV+0D0n3vmPqBgI1vYBxTsOMDZar4fmLkPKNhR5Ww13w/M3AcU7PjK2ar2gTuzcraq + fSD2FfuAgo1ZsQ8o2FHlbDV/XjBzH1AwqmbuAwrG7ZK5DygYfc3cBxTsOEC+KhizlbkPKBj7QOY+ + oGBnVtpZCnZmpZ2lYOfdop2lYOdk0c5SsKGKfUDBjipnq7kPZO4DCjZOFvYBBeMdfOY+oGDHV85W + tQ/EKcA+oGBHlbNV7QN3HOBsNd8PZO4DCjb2APYBBRuzYh9QsOEr9gEFOw5wtqp9INoDhfuAgtHX + wn1AwehA4T6gYHy3CvcBBWNiC/cBBTuz0s5SsOMr7SwFO6q0sxTsOEA7S8HOrLSzFGzMin1AwUa2 + sA8o2FHlbDXfDxTuAwp2VDlbzfcDhfuAgh1Vzlbz9wkL9wEFO75ytpr7QOE+oGBjv2IfULAxK/YB + BRu+Yh9QsKPK2ar2gcCBsec+oGD6jHNVBV8DMGVrfQR8DcDk6/oI+BqAHVXYWQHYUYWdFYAdVdhZ + AZgSuz4COysAO+cVdlYAdhyAnRWAjVmpDwRgY1bqAwHYUeVstd4PrI9wtlq/T7g+wtmq9oH4vFIf + CMCOr5yt1s8L1kc4W9U+cMcBzlbr5wXrI5yt1vuBv6qbHxNGqvXvE3596H5c1p8zXrvlbTl/f946 + NAy32x8AAAD//wMATBzFdvE4AAA= + headers: + api-version: + - '2.24' + cache-control: + - no-cache, no-store, max-age=0 + content-disposition: + - attachment; filename=json.json + content-encoding: + - gzip + content-length: + - '1160' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 20 Sep 2021 19:18:34 UTC + server: + - tsa_b + set-cookie: + - personalization_id="v1_XZy+PKoPtmUjvUSrkmW5ew=="; Max-Age=63072000; Expires=Wed, + 20 Sep 2023 19:18:34 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None + - guest_id=v1%3A163216551384042673; Max-Age=63072000; Expires=Wed, 20 Sep 2023 + 19:18:34 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None + strict-transport-security: + - max-age=631138519 + x-access-level: + - read + x-connection-hash: + - 7abe3709a90e6eb88d43cbfce1d5085b3e00a2388bfb4fb5daaad3b1af8b720a + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-rate-limit-limit: + - '300' + x-rate-limit-remaining: + - '299' + x-rate-limit-reset: + - '1632166413' + x-xss-protection: + - '0' + status: + code: 200 + message: OK +version: 1 diff --git a/docs/client.rst b/docs/client.rst index a7fe350..5b7fa50 100644 --- a/docs/client.rst +++ b/docs/client.rst @@ -43,6 +43,13 @@ Timelines .. automethod:: Client.get_users_tweets +Tweet Counts +------------ + +.. automethod:: Client.get_all_tweets_count + +.. automethod:: Client.get_recent_tweets_count + Tweet lookup ------------ diff --git a/tests/test_client.py b/tests/test_client.py index a3ef340..619195b 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -52,6 +52,12 @@ class TweepyTestCase(unittest.TestCase): user_id = 783214 # User ID for @Twitter self.client.get_users_tweets(user_id) + # TODO: test_get_all_tweets_count with access to Academic Research product track + + @tape.use_cassette("test_get_recent_tweets_count.yaml", serializer="yaml") + def test_get_recent_tweets_count(self): + self.client.get_recent_tweets_count("Tweepy") + @tape.use_cassette("test_get_tweet.yaml", serializer="yaml") def test_get_tweet(self): tweet_id = 1293593516040269825 # @TwitterDev Tweet announcing API v2 diff --git a/tweepy/client.py b/tweepy/client.py index 3426c30..60b8429 100644 --- a/tweepy/client.py +++ b/tweepy/client.py @@ -772,6 +772,143 @@ class Client: ), data_type=Tweet, user_auth=user_auth ) + # Tweet counts + + def get_all_tweets_count(self, query, **params): + """get_all_tweets_count(query, *, end_time, granularity, next_token, \ + since_id, start_time, until_id) + + This endpoint is only available to those users who have been approved + for the `Academic Research product track`_. + + The full-archive search endpoint returns the complete history of public + Tweets matching a search query; since the first Tweet was created March + 26, 2006. + + Parameters + ---------- + query : str + One query for matching Tweets. Up to 1024 characters. + end_time : Union[datetime.datetime, str] + YYYY-MM-DDTHH:mm:ssZ (ISO 8601/RFC 3339). Used with ``start_time``. + The newest, most recent UTC timestamp to which the Tweets will be + provided. Timestamp is in second granularity and is exclusive (for + example, 12:00:01 excludes the first second of the minute). If used + without ``start_time``, Tweets from 30 days before ``end_time`` + will be returned by default. If not specified, ``end_time`` will + default to [now - 30 seconds]. + granularity : str + This is the granularity that you want the timeseries count data to + be grouped by. You can requeset ``minute``, ``hour``, or ``day`` + granularity. The default granularity, if not specified is ``hour``. + next_token : str + This parameter is used to get the next 'page' of results. The value + used with the parameter is pulled directly from the response + provided by the API, and should not be modified. You can learn more + by visiting our page on `pagination`_. + since_id : Union[int, str] + Returns results with a Tweet ID greater than (for example, more + recent than) the specified ID. The ID specified is exclusive and + responses will not include it. If included with the same request as + a ``start_time`` parameter, only ``since_id`` will be used. + start_time : Union[datetime.datetime, str] + YYYY-MM-DDTHH:mm:ssZ (ISO 8601/RFC 3339). The oldest UTC timestamp + from which the Tweets will be provided. Timestamp is in second + granularity and is inclusive (for example, 12:00:01 includes the + first second of the minute). By default, a request will return + Tweets from up to 30 days ago if you do not include this parameter. + until_id : Union[int, str] + Returns results with a Tweet ID less than (that is, older than) the + specified ID. Used with ``since_id``. The ID specified is exclusive + and responses will not include it. + + Returns + ------- + Union[dict, requests.Response, Response] + + References + ---------- + https://developer.twitter.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-all + + .. _Academic Research product track: https://developer.twitter.com/en/docs/projects/overview#product-track + .. _pagination: https://developer.twitter.com/en/docs/twitter-api/tweets/search/integrate/paginate + """ + params["query"] = query + return self._make_request( + "GET", "/2/tweets/counts/all", params=params, + endpoint_parameters=( + "end_time", "granularity", "next_token", "query", "since_id", + "start_time", "until_id" + ) + ) + + def get_recent_tweets_count(self, query, **params): + """get_recent_tweets_count(query, *, end_time, granularity, since_id, \ + start_time, until_id) + + The recent Tweet counts endpoint returns count of Tweets from the last + seven days that match a search query. + + Parameters + ---------- + query : str + One rule for matching Tweets. If you are using a + `Standard Project`_ at the Basic `access level`_, you can use the + basic set of `operators`_ and can make queries up to 512 characters + long. If you are using an `Academic Research Project`_ at the Basic + access level, you can use all available operators and can make + queries up to 1,024 characters long. + end_time : Union[datetime.datetime, str] + YYYY-MM-DDTHH:mm:ssZ (ISO 8601/RFC 3339). The newest, most recent + UTC timestamp to which the Tweets will be provided. Timestamp is in + second granularity and is exclusive (for example, 12:00:01 excludes + the first second of the minute). By default, a request will return + Tweets from as recent as 30 seconds ago if you do not include this + parameter. + granularity : str + This is the granularity that you want the timeseries count data to + be grouped by. You can requeset ``minute``, ``hour``, or ``day`` + granularity. The default granularity, if not specified is ``hour``. + since_id : Union[int, str] + Returns results with a Tweet ID greater than (that is, more recent + than) the specified ID. The ID specified is exclusive and responses + will not include it. If included with the same request as a + ``start_time`` parameter, only ``since_id`` will be used. + start_time : Union[datetime.datetime, str] + YYYY-MM-DDTHH:mm:ssZ (ISO 8601/RFC 3339). The oldest UTC timestamp + (from most recent seven days) from which the Tweets will be + provided. Timestamp is in second granularity and is inclusive (for + example, 12:00:01 includes the first second of the minute). If + included with the same request as a ``since_id`` parameter, only + ``since_id`` will be used. By default, a request will return Tweets + from up to seven days ago if you do not include this parameter. + until_id : Union[int, str] + Returns results with a Tweet ID less than (that is, older than) the + specified ID. The ID specified is exclusive and responses will not + include it. + + Returns + ------- + Union[dict, requests.Response, Response] + + References + ---------- + https://developer.twitter.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-recent + + .. _Standard Project: https://developer.twitter.com/en/docs/projects + .. _access level: https://developer.twitter.com/en/products/twitter-api/early-access/guide.html#na_1 + .. _operators: https://developer.twitter.com/en/docs/twitter-api/tweets/search/integrate/build-a-query + .. _Academic Research Project: https://developer.twitter.com/en/docs/projects + """ + params["query"] = query + return self._make_request( + "GET", "/2/tweets/counts/recent", params=params, + endpoint_parameters=( + "end_time", "granularity", "query", "since_id", "start_time", + "until_id" + ) + ) + # Tweet lookup def get_tweet(self, id, *, user_auth=False, **params): -- 2.25.1