From a32e6cea08d170e618d46eabc82d673074555c3d Mon Sep 17 00:00:00 2001 From: Harmon Date: Mon, 20 Sep 2021 13:32:54 -0500 Subject: [PATCH] Add Client methods for Likes and blocks lookup Add Client.get_liking_users, Client.get_liked_tweets, and Client.get_blocked --- ...st_block_and_get_blocked_and unblock.yaml} | 98 +++++++++--- cassettes/test_get_liked_tweets.yaml | 144 ++++++++++++++++++ cassettes/test_get_liking_users.yaml | 91 +++++++++++ docs/client.rst | 6 + tests/test_client.py | 14 +- tweepy/client.py | 138 +++++++++++++++++ 6 files changed, 469 insertions(+), 22 deletions(-) rename cassettes/{test_block_and_unblock.yaml => test_block_and_get_blocked_and unblock.yaml} (50%) create mode 100644 cassettes/test_get_liked_tweets.yaml create mode 100644 cassettes/test_get_liking_users.yaml diff --git a/cassettes/test_block_and_unblock.yaml b/cassettes/test_block_and_get_blocked_and unblock.yaml similarity index 50% rename from cassettes/test_block_and_unblock.yaml rename to cassettes/test_block_and_get_blocked_and unblock.yaml index cc27ac6..ea8d39f 100644 --- a/cassettes/test_block_and_unblock.yaml +++ b/cassettes/test_block_and_get_blocked_and unblock.yaml @@ -13,7 +13,7 @@ interactions: Content-Type: - application/json User-Agent: - - Python/3.9.4 Requests/2.25.1 Tweepy/3.10.0 + - Python/3.9.6 Requests/2.25.1 Tweepy/4.0.0-alpha method: POST uri: https://api.twitter.com/2/users/1072250532645998596/blocking response: @@ -21,6 +21,8 @@ interactions: string: !!binary | H4sIAAAAAAAAAKpWSkksSVSyqlZKyslPzs7MS1eyKikqTa2tBQAAAP//AwBcCHSuGgAAAA== headers: + api-version: + - '2.24' cache-control: - no-cache, no-store, max-age=0 content-disposition: @@ -32,20 +34,20 @@ interactions: content-type: - application/json; charset=utf-8 date: - - Tue, 27 Apr 2021 14:37:54 GMT + - Mon, 20 Sep 2021 18:12:41 UTC server: - tsa_b set-cookie: - - personalization_id="v1_wzSqJU5xmaPBwmsTkIQvCQ=="; Max-Age=63072000; Expires=Thu, - 27 Apr 2023 14:37:54 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None - - guest_id=v1%3A161953427486161259; Max-Age=63072000; Expires=Thu, 27 Apr 2023 - 14:37:54 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None + - personalization_id="v1_YP58GZ7KULovj9I0BZd+tA=="; Max-Age=63072000; Expires=Wed, + 20 Sep 2023 18:12:41 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None + - guest_id=v1%3A163216156123071343; Max-Age=63072000; Expires=Wed, 20 Sep 2023 + 18:12:41 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None strict-transport-security: - max-age=631138519 x-access-level: - read-write-directmessages x-connection-hash: - - 5c25c08c94e3e4166ae103e975e2c840 + - 74daf3f6996e83c2a3a1336df68a70c9ffe266db5ca7f75f44b223f3b021bc79 x-content-type-options: - nosniff x-frame-options: @@ -53,13 +55,67 @@ interactions: x-rate-limit-limit: - '50' x-rate-limit-remaining: - - '48' + - '49' x-rate-limit-reset: - - '1619534909' - x-response-time: - - '50' - x-tsa-request-body-time: - - '4' + - '1632162461' + x-xss-protection: + - '0' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - guest_id=v1%3A163216156123071343; personalization_id="v1_YP58GZ7KULovj9I0BZd+tA==" + User-Agent: + - Python/3.9.6 Requests/2.25.1 Tweepy/4.0.0-alpha + method: GET + uri: https://api.twitter.com/2/users/1072250532645998596/blocking + response: + body: + string: !!binary | + H4sIAAAAAAAAAKpWSkksSVSyiq5WykxRslIyNLcwNzE1MVHSUcpLzE0FioSUZ5aUpBYpBJcWFOQX + lQAlSotTi1AlYXK1sTpKuakg86qVilKLS3NK4pPzS/NKlKwMa2sBAAAA//8DAMW+VFVrAAAA + 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: + - '111' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 20 Sep 2021 18:12:41 UTC + server: + - tsa_b + strict-transport-security: + - max-age=631138519 + x-access-level: + - read-write-directmessages + x-connection-hash: + - 74daf3f6996e83c2a3a1336df68a70c9ffe266db5ca7f75f44b223f3b021bc79 + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-rate-limit-limit: + - '15' + x-rate-limit-remaining: + - '14' + x-rate-limit-reset: + - '1632162461' x-xss-protection: - '0' status: @@ -77,9 +133,9 @@ interactions: Content-Length: - '0' Cookie: - - guest_id=v1%3A161953427486161259; personalization_id="v1_wzSqJU5xmaPBwmsTkIQvCQ==" + - guest_id=v1%3A163216156123071343; personalization_id="v1_YP58GZ7KULovj9I0BZd+tA==" User-Agent: - - Python/3.9.4 Requests/2.25.1 Tweepy/3.10.0 + - Python/3.9.6 Requests/2.25.1 Tweepy/4.0.0-alpha method: DELETE uri: https://api.twitter.com/2/users/1072250532645998596/blocking/17874544 response: @@ -87,6 +143,8 @@ interactions: string: !!binary | H4sIAAAAAAAAAKpWSkksSVSyqlZKyslPzs7MS1eySkvMKU6trQUAAAD//wMAcXlx4RsAAAA= headers: + api-version: + - '2.24' cache-control: - no-cache, no-store, max-age=0 content-disposition: @@ -98,7 +156,7 @@ interactions: content-type: - application/json; charset=utf-8 date: - - Tue, 27 Apr 2021 14:37:55 GMT + - Mon, 20 Sep 2021 18:12:41 UTC server: - tsa_b strict-transport-security: @@ -106,7 +164,7 @@ interactions: x-access-level: - read-write-directmessages x-connection-hash: - - 5c25c08c94e3e4166ae103e975e2c840 + - 74daf3f6996e83c2a3a1336df68a70c9ffe266db5ca7f75f44b223f3b021bc79 x-content-type-options: - nosniff x-frame-options: @@ -114,11 +172,9 @@ interactions: x-rate-limit-limit: - '50' x-rate-limit-remaining: - - '48' + - '49' x-rate-limit-reset: - - '1619534920' - x-response-time: - - '401' + - '1632162461' x-xss-protection: - '0' status: diff --git a/cassettes/test_get_liked_tweets.yaml b/cassettes/test_get_liked_tweets.yaml new file mode 100644 index 0000000..e958220 --- /dev/null +++ b/cassettes/test_get_liked_tweets.yaml @@ -0,0 +1,144 @@ +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/users/783214/liked_tweets + response: + body: + string: !!binary | + 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 + 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: + - '4729' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 20 Sep 2021 18:12:42 UTC + server: + - tsa_b + set-cookie: + - personalization_id="v1_/+lN5pJJtHQB8sRzRQgrpg=="; Max-Age=63072000; Expires=Wed, + 20 Sep 2023 18:12:42 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None + - guest_id=v1%3A163216156189651841; Max-Age=63072000; Expires=Wed, 20 Sep 2023 + 18:12:42 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None + strict-transport-security: + - max-age=631138519 + x-access-level: + - read + x-connection-hash: + - b6adbe0b1bd07ad4f71300daf80f61b2fdd2ca053fa9823183eb6fff632c4660 + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-rate-limit-limit: + - '75' + x-rate-limit-remaining: + - '74' + x-rate-limit-reset: + - '1632162461' + x-xss-protection: + - '0' + status: + code: 200 + message: OK +version: 1 diff --git a/cassettes/test_get_liking_users.yaml b/cassettes/test_get_liking_users.yaml new file mode 100644 index 0000000..f8abb32 --- /dev/null +++ b/cassettes/test_get_liking_users.yaml @@ -0,0 +1,91 @@ +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/1293593516040269825/liking_users + response: + body: + string: !!binary | + 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 + /wMAeBlOl1sOAAA= + 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: + - '1664' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 20 Sep 2021 18:12:42 UTC + server: + - tsa_b + set-cookie: + - personalization_id="v1_USExOf66w3yoSBFTJPY6dQ=="; Max-Age=63072000; Expires=Wed, + 20 Sep 2023 18:12:42 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None + - guest_id=v1%3A163216156253094235; Max-Age=63072000; Expires=Wed, 20 Sep 2023 + 18:12:42 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None + strict-transport-security: + - max-age=631138519 + x-access-level: + - read + x-connection-hash: + - 64b98a6d638115a8ef50f8db4f42f1e14beb1d47b892827beb26c7879bfe0bd3 + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + x-rate-limit-limit: + - '75' + x-rate-limit-remaining: + - '74' + x-rate-limit-reset: + - '1632162462' + x-xss-protection: + - '0' + status: + code: 200 + message: OK +version: 1 diff --git a/docs/client.rst b/docs/client.rst index 00c1b63..a7fe350 100644 --- a/docs/client.rst +++ b/docs/client.rst @@ -23,6 +23,10 @@ Likes .. automethod:: Client.unlike +.. automethod:: Client.get_liking_users + +.. automethod:: Client.get_liked_tweets + .. automethod:: Client.like Search Tweets @@ -54,6 +58,8 @@ Blocks .. automethod:: Client.unblock +.. automethod:: Client.get_blocked + .. automethod:: Client.block Follows diff --git a/tests/test_client.py b/tests/test_client.py index 2b4c26e..a3ef340 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -26,6 +26,16 @@ class TweepyTestCase(unittest.TestCase): self.client.like(tweet_id) self.client.unlike(tweet_id) + @tape.use_cassette("test_get_liking_users.yaml", serializer="yaml") + def test_get_liking_users(self): + tweet_id = 1293593516040269825 # @TwitterDev Tweet announcing API v2 + self.client.get_liking_users(tweet_id) + + @tape.use_cassette("test_get_liked_tweets.yaml", serializer="yaml") + def test_get_liked_tweets(self): + user_id = 783214 # User ID for @Twitter + self.client.get_liked_tweets(user_id) + # TODO: test_search_all_tweets with access to Academic Research product track @tape.use_cassette("test_search_recent_tweets.yaml", serializer="yaml") @@ -53,10 +63,12 @@ class TweepyTestCase(unittest.TestCase): # @TwitterDev and @TwitterAPI Tweets announcing API v2 self.client.get_tweets(tweet_ids) - @tape.use_cassette("test_block_and_unblock.yaml", serializer="yaml") + @tape.use_cassette("test_block_and_get_blocked_and unblock.yaml", + serializer="yaml") def test_block_and_unblock(self): user_id = 17874544 # User ID for @TwitterSupport self.client.block(user_id) + self.client.get_blocked() self.client.unblock(user_id) @tape.use_cassette("test_follow_and_unfollow.yaml", serializer="yaml") diff --git a/tweepy/client.py b/tweepy/client.py index 6f36891..3426c30 100644 --- a/tweepy/client.py +++ b/tweepy/client.py @@ -261,6 +261,102 @@ class Client: return self._make_request("DELETE", route, user_auth=True) + def get_liking_users(self, id, *, user_auth=False, **params): + """get_liking_users(id, *, expansions, media_fields, place_fields, \ + poll_fields, tweet_fields, user_fields) + + Allows you to get information about a Tweet’s liking users. + + Parameters + ---------- + id : Union[int, str] + Tweet ID of the Tweet to request liking users of. + expansions : Union[List[str], str] + :ref:`expansions_parameter` + media_fields : Union[List[str], str] + :ref:`media_fields_parameter` + place_fields : Union[List[str], str] + :ref:`place_fields_parameter` + poll_fields : Union[List[str], str] + :ref:`poll_fields_parameter` + tweet_fields : Union[List[str], str] + :ref:`tweet_fields_parameter` + user_fields : Union[List[str], str] + :ref:`user_fields_parameter` + + Returns + ------- + Union[dict, requests.Response, Response] + + References + ---------- + https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/get-tweets-id-liking_users + """ + return self._make_request( + "GET", f"/2/tweets/{id}/liking_users", params=params, + endpoint_parameters=( + "expansions", "media.fields", "place.fields", "poll.fields", + "tweet.fields", "user.fields" + ), data_type=User, user_auth=user_auth + ) + + def get_liked_tweets(self, id, *, user_auth=False, **params): + """get_liked_tweets( \ + id, *, expansions, max_results, media_fields, pagination_token, \ + place_fields, poll_fields, tweet_fields, user_fields \ + ) + + Allows you to get information about a user’s liked Tweets. + + The Tweets returned by this endpoint count towards the Project-level + `Tweet cap`_. + + Parameters + ---------- + id : Union[int, str] + User ID of the user to request liked Tweets for. + expansions : Union[List[str], str] + :ref:`expansions_parameter` + max_results : int + The maximum number of results to be returned per page. This can be + a number between 5 and 100. By default, each page will return 100 + results. + media_fields : Union[List[str], str] + :ref:`media_fields_parameter` + pagination_token : str + Used to request the next page of results if all results weren't + returned with the latest request, or to go back to the previous + page of results. To return the next page, pass the ``next_token`` + returned in your previous response. To go back one page, pass the + ``previous_token`` returned in your previous response. + place_fields : Union[List[str], str] + :ref:`place_fields_parameter` + poll_fields : Union[List[str], str] + :ref:`poll_fields_parameter` + tweet_fields : Union[List[str], str] + :ref:`tweet_fields_parameter` + user_fields : Union[List[str], str] + :ref:`user_fields_parameter` + + Returns + ------- + Union[dict, requests.Response, Response] + + References + ---------- + https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/get-users-id-liked_tweets + + .. _Tweet cap: https://developer.twitter.com/en/docs/projects/overview#tweet-cap + """ + return self._make_request( + "GET", f"/2/users/{id}/liked_tweets", params=params, + endpoint_parameters=( + "expansions", "max_results", "media.fields", + "pagination_token", "place.fields", "poll.fields", + "tweet.fields", "user.fields" + ), data_type=Tweet, user_auth=user_auth + ) + def like(self, tweet_id): """Like a Tweet. @@ -793,6 +889,48 @@ class Client: "DELETE", route, user_auth=True ) + def get_blocked(self, **params): + """get_blocked(*, expansions, max_results, pagination_token, \ + tweet_fields, user_fields) + + Returns a list of users who are blocked by the authenticating user. + + Parameters + ---------- + expansions : Union[List[str], str] + :ref:`expansions_parameter` + max_results : int + The maximum number of results to be returned per page. This can be + a number between 1 and 1000. By default, each page will return 100 + results. + pagination_token : str + Used to request the next page of results if all results weren't + returned with the latest request, or to go back to the previous + page of results. + tweet_fields : Union[List[str], str] + :ref:`tweet_fields_parameter` + user_fields : Union[List[str], str] + :ref:`user_fields_parameter` + + Returns + ------- + Union[dict, requests.Response, Response] + + References + ---------- + https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/get-users-blocking + """ + id = self.access_token.partition('-')[0] + route = f"/2/users/{id}/blocking" + + return self._make_request( + "GET", route, params=params, + endpoint_parameters=( + "expansions", "max_results", "pagination_token", + "tweet.fields", "user.fields" + ), data_type=User, user_auth=True + ) + def block(self, target_user_id): """Block another user. -- 2.25.1