Replace APIMethod.payload_list and APIMethod.payload_type
authorHarmon <Harmon758@gmail.com>
Tue, 2 Feb 2021 16:54:38 +0000 (10:54 -0600)
committerHarmon <Harmon758@gmail.com>
Tue, 2 Feb 2021 16:54:38 +0000 (10:54 -0600)
Replace APIMethod.payload_list and APIMethod.payload_type with payload decorator and APIMethod.execute payload_list and payload_type keyword-only arguments
Add payload_list and payload_type keyword-only arguments to ModelParser.parse
Allow passing keyword arguments to bind_api and APIMethod through API.send_direct_message, API.lookup_friendships, API.update_profile_image, API.add_list_members, API.remove_list_members

tweepy/api.py
tweepy/binder.py
tweepy/cursor.py
tweepy/parsers.py

index 1649d41519a4a835d176952f6d2b3ad99e702abf..bf3beab97a84d03ddf8e07f8589de1ca1300dc10 100644 (file)
@@ -6,7 +6,7 @@ import imghdr
 import mimetypes
 import os
 
-from tweepy.binder import bind_api, pagination
+from tweepy.binder import bind_api, pagination, payload
 from tweepy.error import TweepError
 from tweepy.parsers import ModelParser, Parser
 from tweepy.utils import list_to_csv
@@ -75,6 +75,7 @@ class API:
             )
 
     @pagination(mode='id')
+    @payload('status', list=True)
     def home_timeline(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-home_timeline
             :allowed_param: 'count', 'since_id', 'max_id', 'trim_user',
@@ -83,12 +84,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/statuses/home_timeline.json',
-            payload_type='status', payload_list=True,
             allowed_param=['count', 'since_id', 'max_id', 'trim_user',
                            'exclude_replies', 'include_entities'],
             require_auth=True, **kwargs
         )
 
+    @payload('status', list=True)
     def statuses_lookup(self, id_, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-lookup
             :allowed_param: 'id', 'include_entities', 'trim_user', 'map',
@@ -100,13 +101,13 @@ class API:
         return bind_api(
             list_to_csv(id_), *args, api=self,
             path='/statuses/lookup.json',
-            payload_type='status', payload_list=True,
             allowed_param=['id', 'include_entities', 'trim_user', 'map',
                            'include_ext_alt_text', 'include_card_uri'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='id')
+    @payload('status', list=True)
     def user_timeline(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-user_timeline
             :allowed_param: 'user_id', 'screen_name', 'since_id', 'count',
@@ -116,13 +117,13 @@ class API:
         return bind_api(
             *args, api=self,
             path='/statuses/user_timeline.json',
-            payload_type='status', payload_list=True,
             allowed_param=['user_id', 'screen_name', 'since_id', 'count',
                            'max_id', 'trim_user', 'exclude_replies',
                            'include_rts'], **kwargs
         )
 
     @pagination(mode='id')
+    @payload('status', list=True)
     def mentions_timeline(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-mentions_timeline
             :allowed_param: 'since_id', 'max_id', 'count'
@@ -130,12 +131,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/statuses/mentions_timeline.json',
-            payload_type='status', payload_list=True,
             allowed_param=['since_id', 'max_id', 'count'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='id')
+    @payload('status', list=True)
     def retweets_of_me(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-retweets_of_me
             :allowed_param: 'since_id', 'max_id', 'count'
@@ -143,11 +144,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/statuses/retweets_of_me.json',
-            payload_type='status', payload_list=True,
             allowed_param=['since_id', 'max_id', 'count'],
             require_auth=True, **kwargs
         )
 
+    @payload('status')
     def get_status(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-show-id
             :allowed_param: 'id', 'trim_user', 'include_my_retweet',
@@ -157,12 +158,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/statuses/show.json',
-            payload_type='status',
             allowed_param=['id', 'trim_user', 'include_my_retweet',
                            'include_entities', 'include_ext_alt_text',
                            'include_card_uri'], **kwargs
         )
 
+    @payload('status')
     def update_status(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update
             :allowed_param: 'status', 'in_reply_to_status_id',
@@ -179,7 +180,6 @@ class API:
             *args, api=self,
             path='/statuses/update.json',
             method='POST',
-            payload_type='status',
             allowed_param=['status', 'in_reply_to_status_id',
                            'auto_populate_reply_metadata',
                            'exclude_reply_user_ids', 'attachment_url',
@@ -190,6 +190,7 @@ class API:
             require_auth=True, **kwargs
         )
 
+    @payload('media')
     def media_upload(self, filename, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/media/upload-media/api-reference/post-media-upload
             :allowed_param:
@@ -216,7 +217,6 @@ class API:
             *args, api=self,
             path='/media/upload.json',
             method='POST',
-            payload_type='media',
             allowed_param=[],
             require_auth=True,
             upload_api=True, **kwargs
@@ -240,6 +240,7 @@ class API:
             upload_api=True, **kwargs
         )
 
+    @payload('status')
     def update_with_media(self, filename, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update_with_media
             :allowed_param: 'status', 'possibly_sensitive',
@@ -257,7 +258,6 @@ class API:
             *args, api=self,
             path='/statuses/update_with_media.json',
             method='POST',
-            payload_type='status',
             allowed_param=['status', 'possibly_sensitive',
                            'in_reply_to_status_id',
                            'in_reply_to_status_id_str',
@@ -266,6 +266,7 @@ class API:
             require_auth=True, **kwargs
         )
 
+    @payload('status')
     def destroy_status(self, status_id, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-destroy-id
             :allowed_param:
@@ -274,10 +275,10 @@ class API:
             *args, api=self,
             path=f'/statuses/destroy/{status_id}.json',
             method='POST',
-            payload_type='status',
             require_auth=True, **kwargs
         )
 
+    @payload('status')
     def retweet(self, status_id, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-retweet-id
             :allowed_param:
@@ -286,10 +287,10 @@ class API:
             *args, api=self,
             path=f'/statuses/retweet/{status_id}.json',
             method='POST',
-            payload_type='status',
             require_auth=True, **kwargs
         )
 
+    @payload('status')
     def unretweet(self, status_id, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-unretweet-id
             :allowed_param:
@@ -298,10 +299,10 @@ class API:
             *args, api=self,
             path=f'/statuses/unretweet/{status_id}.json',
             method='POST',
-            payload_type='status',
             require_auth=True, **kwargs
         )
 
+    @payload('status', list=True)
     def retweets(self, status_id, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-retweets-id
             :allowed_param: 'count'
@@ -309,12 +310,12 @@ class API:
         return bind_api(
             *args, api=self,
             path=f'/statuses/retweets/{status_id}.json',
-            payload_type='status', payload_list=True,
             allowed_param=['count'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('ids')
     def retweeters(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-retweeters-ids
             :allowed_param: 'id', 'cursor', 'stringify_ids
@@ -322,10 +323,10 @@ class API:
         return bind_api(
             *args, api=self,
             path='/statuses/retweeters/ids.json',
-            payload_type='ids',
             allowed_param=['id', 'cursor', 'stringify_ids'], **kwargs
         )
 
+    @payload('user')
     def get_user(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-show
             :allowed_param: 'id', 'user_id', 'screen_name'
@@ -333,10 +334,10 @@ class API:
         return bind_api(
             *args, api=self,
             path='/users/show.json',
-            payload_type='user',
             allowed_param=['id', 'user_id', 'screen_name'], **kwargs
         )
 
+    @payload('json')
     def get_oembed(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-oembed
             :allowed_param: 'url', 'maxwidth', 'hide_media', 'hide_thread',
@@ -346,12 +347,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/statuses/oembed.json',
-            payload_type='json',
             allowed_param=['url', 'maxwidth', 'hide_media', 'hide_thread',
                            'omit_script', 'align', 'related', 'lang', 'theme',
                            'link_color', 'widget_type', 'dnt'], **kwargs
         )
 
+    @payload('user', list=True)
     def lookup_users(self, user_ids=None, screen_names=None, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup
             :allowed_param: 'user_id', 'screen_name', 'include_entities',
@@ -360,7 +361,6 @@ class API:
         return bind_api(
             list_to_csv(user_ids), list_to_csv(screen_names), *args, api=self,
             path='/users/lookup.json',
-            payload_type='user', payload_list=True,
             method='POST',
             allowed_param=['user_id', 'screen_name', 'include_entities',
                            'tweet_mode'], **kwargs
@@ -371,6 +371,7 @@ class API:
         return self.get_user(screen_name=self.auth.get_username())
 
     @pagination(mode='page')
+    @payload('user', list=True)
     def search_users(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-search
             :allowed_param: 'q', 'count', 'page'
@@ -378,11 +379,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/users/search.json',
-            payload_type='user', payload_list=True,
             require_auth=True,
             allowed_param=['q', 'count', 'page'], **kwargs
         )
 
+    @payload('direct_message')
     def get_direct_message(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-event
             :allowed_param: 'id'
@@ -390,12 +391,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/direct_messages/events/show.json',
-            payload_type='direct_message',
             allowed_param=['id'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='dm_cursor')
+    @payload('direct_message', list=True)
     def list_direct_messages(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/list-events
             :allowed_param: 'count', 'cursor'
@@ -403,14 +404,14 @@ class API:
         return bind_api(
             *args, api=self,
             path='/direct_messages/events/list.json',
-            payload_type='direct_message', payload_list=True,
             allowed_param=['count', 'cursor'],
             require_auth=True, **kwargs
         )
 
+    @payload('direct_message')
     def send_direct_message(self, recipient_id, text, quick_reply_options=None,
                             attachment_type=None, attachment_media_id=None,
-                            ctas=None):
+                            ctas=None, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event
             :allowed_param: 'recipient_id', 'text', 'quick_reply_type',
                             'attachment_type', attachment_media_id'
@@ -440,9 +441,8 @@ class API:
             api=self,
             path='/direct_messages/events/new.json',
             method='POST',
-            payload_type='direct_message',
             require_auth=True, 
-            json_payload=json_payload
+            json_payload=json_payload, **kwargs
         )
 
     def destroy_direct_message(self, *args, **kwargs):
@@ -457,6 +457,7 @@ class API:
             require_auth=True, **kwargs
         )
 
+    @payload('user')
     def create_friendship(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create
             :allowed_param: 'id', 'user_id', 'screen_name', 'follow'
@@ -465,11 +466,11 @@ class API:
             *args, api=self,
             path='/friendships/create.json',
             method='POST',
-            payload_type='user',
             allowed_param=['id', 'user_id', 'screen_name', 'follow'],
             require_auth=True, **kwargs
         )
 
+    @payload('user')
     def destroy_friendship(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy
             :allowed_param: 'id', 'user_id', 'screen_name'
@@ -478,11 +479,11 @@ class API:
             *args, api=self,
             path='/friendships/destroy.json',
             method='POST',
-            payload_type='user',
             allowed_param=['id', 'user_id', 'screen_name'],
             require_auth=True, **kwargs
         )
 
+    @payload('friendship')
     def show_friendship(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-show
             :allowed_param: 'source_id', 'source_screen_name', 'target_id',
@@ -491,24 +492,24 @@ class API:
         return bind_api(
             *args, api=self,
             path='/friendships/show.json',
-            payload_type='friendship',
             allowed_param=['source_id', 'source_screen_name',
                            'target_id', 'target_screen_name'], **kwargs
         )
 
-    def lookup_friendships(self, user_ids=None, screen_names=None):
+    @payload('relationship', list=True)
+    def lookup_friendships(self, user_ids=None, screen_names=None, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-lookup
             :allowed_param: 'user_id', 'screen_name'
         """
         return bind_api(
             list_to_csv(user_ids), list_to_csv(screen_names), api=self,
             path='/friendships/lookup.json',
-            payload_type='relationship', payload_list=True,
             allowed_param=['user_id', 'screen_name'],
-            require_auth=True
+            require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('ids')
     def friends_ids(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids
             :allowed_param: 'id', 'user_id', 'screen_name', 'cursor'
@@ -516,11 +517,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/friends/ids.json',
-            payload_type='ids',
             allowed_param=['id', 'user_id', 'screen_name', 'cursor'], **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('user', list=True)
     def friends(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-list
             :allowed_param: 'id', 'user_id', 'screen_name', 'cursor', 'count',
@@ -529,12 +530,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/friends/list.json',
-            payload_type='user', payload_list=True,
             allowed_param=['id', 'user_id', 'screen_name', 'cursor', 'count',
                            'skip_status', 'include_user_entities'], **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('ids')
     def friendships_incoming(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming
             :allowed_param: 'cursor'
@@ -542,11 +543,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/friendships/incoming.json',
-            payload_type='ids',
             allowed_param=['cursor'], **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('ids')
     def friendships_outgoing(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-outgoing
             :allowed_param: 'cursor'
@@ -554,11 +555,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/friendships/outgoing.json',
-            payload_type='ids',
             allowed_param=['cursor'], **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('ids')
     def followers_ids(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids
             :allowed_param: 'id', 'user_id', 'screen_name', 'cursor', 'count'
@@ -566,12 +567,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/followers/ids.json',
-            payload_type='ids',
             allowed_param=['id', 'user_id', 'screen_name', 'cursor', 'count'],
             **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('user', list=True)
     def followers(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list
             :allowed_param: 'id', 'user_id', 'screen_name', 'cursor', 'count',
@@ -580,20 +581,20 @@ class API:
         return bind_api(
             *args, api=self,
             path='/followers/list.json',
-            payload_type='user', payload_list=True,
             allowed_param=['id', 'user_id', 'screen_name', 'cursor', 'count',
                            'skip_status', 'include_user_entities'], **kwargs
         )
 
+    @payload('json')
     def get_settings(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-account-settings """
         return bind_api(
             *args, api=self,
             path='/account/settings.json',
-            payload_type='json',
             use_cache=False, **kwargs
         )
 
+    @payload('json')
     def set_settings(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-settings
             :allowed_param: 'sleep_time_enabled', 'start_sleep_time',
@@ -605,7 +606,6 @@ class API:
             *args, api=self,
             path='/account/settings.json',
             method='POST',
-            payload_type='json',
             allowed_param=['sleep_time_enabled', 'start_sleep_time',
                            'end_sleep_time', 'time_zone',
                            'trend_location_woeid',
@@ -613,6 +613,7 @@ class API:
             use_cache=False, **kwargs
         )
 
+    @payload('user')
     def verify_credentials(self, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-account-verify_credentials
             :allowed_param: 'include_entities', 'skip_status', 'include_email'
@@ -623,7 +624,6 @@ class API:
             return bind_api(
                 api=self,
                 path='/account/verify_credentials.json',
-                payload_type='user',
                 require_auth=True,
                 allowed_param=['include_entities', 'skip_status',
                                'include_email'], **kwargs
@@ -633,6 +633,7 @@ class API:
                 return False
             raise
 
+    @payload('json')
     def rate_limit_status(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/developer-utilities/rate-limit-status/api-reference/get-application-rate_limit_status
             :allowed_param: 'resources'
@@ -640,12 +641,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/application/rate_limit_status.json',
-            payload_type='json',
             allowed_param=['resources'],
             use_cache=False, **kwargs
         )
 
-    def update_profile_image(self, filename, file_=None):
+    @payload('user')
+    def update_profile_image(self, filename, file_=None, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_image
             :allowed_param: 'include_entities', 'skip_status'
         """
@@ -654,10 +655,9 @@ class API:
             self, api=self,
             path='/account/update_profile_image.json',
             method='POST',
-            payload_type='user',
             allowed_param=['include_entities', 'skip_status'],
             require_auth=True,
-            post_data=post_data, headers=headers
+            post_data=post_data, headers=headers, **kwargs
         )
 
     def update_profile_banner(self, filename, **kwargs):
@@ -676,6 +676,7 @@ class API:
             post_data=post_data, headers=headers
         )
 
+    @payload('user')
     def update_profile(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile
             :allowed_param: 'name', 'url', 'location', 'description',
@@ -685,13 +686,13 @@ class API:
             *args, api=self,
             path='/account/update_profile.json',
             method='POST',
-            payload_type='user',
             allowed_param=['name', 'url', 'location', 'description',
                            'profile_link_color'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='id')
+    @payload('status', list=True)
     def favorites(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-favorites-list
             :allowed_param: 'screen_name', 'user_id', 'max_id', 'count',
@@ -700,11 +701,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/favorites/list.json',
-            payload_type='status', payload_list=True,
             allowed_param=['screen_name', 'user_id', 'max_id', 'count',
                            'since_id'], **kwargs
         )
 
+    @payload('status')
     def create_favorite(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-favorites-create
             :allowed_param: 'id'
@@ -713,11 +714,11 @@ class API:
             *args, api=self,
             path='/favorites/create.json',
             method='POST',
-            payload_type='status',
             allowed_param=['id'],
             require_auth=True, **kwargs
         )
 
+    @payload('status')
     def destroy_favorite(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-favorites-destroy
             :allowed_param: 'id'
@@ -726,11 +727,11 @@ class API:
             *args, api=self,
             path='/favorites/destroy.json',
             method='POST',
-            payload_type='status',
             allowed_param=['id'],
             require_auth=True, **kwargs
         )
 
+    @payload('user')
     def create_block(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-blocks-create
             :allowed_param: 'id', 'user_id', 'screen_name'
@@ -739,11 +740,11 @@ class API:
             *args, api=self,
             path='/blocks/create.json',
             method='POST',
-            payload_type='user',
             allowed_param=['id', 'user_id', 'screen_name'],
             require_auth=True, **kwargs
         )
 
+    @payload('user')
     def destroy_block(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-blocks-destroy
             :allowed_param: 'id', 'user_id', 'screen_name'
@@ -752,12 +753,12 @@ class API:
             *args, api=self,
             path='/blocks/destroy.json',
             method='POST',
-            payload_type='user',
             allowed_param=['id', 'user_id', 'screen_name'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('ids')
     def mutes_ids(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-ids
             :allowed_param: 'cursor'
@@ -765,12 +766,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/mutes/users/ids.json',
-            payload_type='ids',
             allowed_param=['cursor'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('user', list=True)
     def mutes(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-list
             :allowed_param: 'cursor', 'include_entities', 'skip_status'
@@ -778,11 +779,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/mutes/users/list.json',
-            payload_type='user', payload_list=True,
             allowed_param=['cursor', 'include_entities', 'skip_status'],
             required_auth=True, **kwargs
         )
 
+    @payload('user')
     def create_mute(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-mutes-users-create
             :allowed_param: 'id', 'user_id', 'screen_name'
@@ -791,11 +792,11 @@ class API:
             *args, api=self,
             path='/mutes/users/create.json',
             method='POST',
-            payload_type='user',
             allowed_param=['id', 'user_id', 'screen_name'],
             require_auth=True, **kwargs
         )
 
+    @payload('user')
     def destroy_mute(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-mutes-users-destroy
             :allowed_param: 'id', 'user_id', 'screen_name'
@@ -804,12 +805,12 @@ class API:
             *args, api=self,
             path='/mutes/users/destroy.json',
             method='POST',
-            payload_type='user',
             allowed_param=['id', 'user_id', 'screen_name'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('user', list=True)
     def blocks(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/get-blocks-list
             :allowed_param: 'cursor'
@@ -817,12 +818,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/blocks/list.json',
-            payload_type='user', payload_list=True,
             allowed_param=['cursor'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('ids')
     def blocks_ids(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/get-blocks-ids
             :allowed_param: 'cursor'
@@ -830,11 +831,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/blocks/ids.json',
-            payload_type='ids',
             allowed_param=['cursor'],
             require_auth=True, **kwargs
         )
 
+    @payload('user')
     def report_spam(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-users-report_spam
             :allowed_param: 'user_id', 'screen_name', 'perform_block'
@@ -843,20 +844,20 @@ class API:
             *args, api=self,
             path='/users/report_spam.json',
             method='POST',
-            payload_type='user',
             allowed_param=['user_id', 'screen_name', 'perform_block'],
             require_auth=True, **kwargs
         )
 
+    @payload('saved_search', list=True)
     def saved_searches(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-saved_searches-list """
         return bind_api(
             *args, api=self,
             path='/saved_searches/list.json',
-            payload_type='saved_search', payload_list=True,
             require_auth=True, **kwargs
         )
 
+    @payload('saved_search')
     def get_saved_search(self, saved_search_id, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-saved_searches-show-id
             :allowed_param:
@@ -864,10 +865,10 @@ class API:
         return bind_api(
             *args, api=self,
             path=f'/saved_searches/show/{saved_search_id}.json',
-            payload_type='saved_search',
             require_auth=True, **kwargs
         )
 
+    @payload('saved_search')
     def create_saved_search(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-saved_searches-create
             :allowed_param: 'query'
@@ -876,11 +877,11 @@ class API:
             *args, api=self,
             path='/saved_searches/create.json',
             method='POST',
-            payload_type='saved_search',
             allowed_param=['query'],
             require_auth=True, **kwargs
         )
 
+    @payload('saved_search')
     def destroy_saved_search(self, saved_search_id, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-saved_searches-destroy-id
             :allowed_param:
@@ -889,10 +890,10 @@ class API:
             *args, api=self,
             path=f'/saved_searches/destroy/{saved_search_id}.json',
             method='POST',
-            payload_type='saved_search',
             require_auth=True, **kwargs
         )
 
+    @payload('list')
     def create_list(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-create
             :allowed_param: 'name', 'mode', 'description'
@@ -901,11 +902,11 @@ class API:
             *args, api=self,
             path='/lists/create.json',
             method='POST',
-            payload_type='list',
             allowed_param=['name', 'mode', 'description'],
             require_auth=True, **kwargs
         )
 
+    @payload('list')
     def destroy_list(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-destroy
             :allowed_param: 'owner_screen_name', 'owner_id', 'list_id', 'slug'
@@ -914,11 +915,11 @@ class API:
             *args, api=self,
             path='/lists/destroy.json',
             method='POST',
-            payload_type='list',
             allowed_param=['owner_screen_name', 'owner_id', 'list_id', 'slug'],
             require_auth=True, **kwargs
         )
 
+    @payload('list')
     def update_list(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-update
             :allowed_param: 'list_id', 'slug', 'name', 'mode', 'description',
@@ -928,12 +929,12 @@ class API:
             *args, api=self,
             path='/lists/update.json',
             method='POST',
-            payload_type='list',
             allowed_param=['list_id', 'slug', 'name', 'mode', 'description',
                            'owner_screen_name', 'owner_id'],
             require_auth=True, **kwargs
         )
 
+    @payload('list', list=True)
     def lists_all(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-list
             :allowed_param: 'screen_name', 'user_id', 'reverse'
@@ -941,12 +942,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/lists/list.json',
-            payload_type='list', payload_list=True,
             allowed_param=['screen_name', 'user_id', 'reverse'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('list', list=True)
     def lists_memberships(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-memberships
             :allowed_param: 'screen_name', 'user_id', 'filter_to_owned_lists',
@@ -955,13 +956,13 @@ class API:
         return bind_api(
             *args, api=self,
             path='/lists/memberships.json',
-            payload_type='list', payload_list=True,
             allowed_param=['screen_name', 'user_id', 'filter_to_owned_lists',
                            'cursor', 'count'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('list', list=True)
     def lists_ownerships(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-ownerships
             :allowed_param: 'user_id', 'screen_name', 'count', 'cursor'
@@ -969,12 +970,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/lists/ownerships.json',
-            payload_type='list', payload_list=True,
             allowed_param=['user_id', 'screen_name', 'count', 'cursor'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('list', list=True)
     def lists_subscriptions(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-subscriptions
             :allowed_param: 'screen_name', 'user_id', 'cursor', 'count'
@@ -982,12 +983,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/lists/subscriptions.json',
-            payload_type='list', payload_list=True,
             allowed_param=['screen_name', 'user_id', 'cursor', 'count'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='id')
+    @payload('status', list=True)
     def list_timeline(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-statuses
             :allowed_param: 'owner_screen_name', 'slug', 'owner_id', 'list_id',
@@ -997,12 +998,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/lists/statuses.json',
-            payload_type='status', payload_list=True,
             allowed_param=['owner_screen_name', 'slug', 'owner_id', 'list_id',
                            'since_id', 'max_id', 'count', 'include_entities',
                            'include_rts'], **kwargs
         )
 
+    @payload('list')
     def get_list(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-show
             :allowed_param: 'owner_screen_name', 'owner_id', 'slug', 'list_id'
@@ -1010,11 +1011,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/lists/show.json',
-            payload_type='list',
             allowed_param=['owner_screen_name', 'owner_id', 'slug', 'list_id'],
             **kwargs
         )
 
+    @payload('list')
     def add_list_member(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-members-create
             :allowed_param: 'screen_name', 'user_id', 'owner_screen_name',
@@ -1024,12 +1025,12 @@ class API:
             *args, api=self,
             path='/lists/members/create.json',
             method='POST',
-            payload_type='list',
             allowed_param=['screen_name', 'user_id', 'owner_screen_name',
                            'owner_id', 'slug', 'list_id'],
             require_auth=True, **kwargs
         )
 
+    @payload('list')
     def remove_list_member(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-members-destroy
             :allowed_param: 'screen_name', 'user_id', 'owner_screen_name',
@@ -1039,14 +1040,15 @@ class API:
             *args, api=self,
             path='/lists/members/destroy.json',
             method='POST',
-            payload_type='list',
             allowed_param=['screen_name', 'user_id', 'owner_screen_name',
                            'owner_id', 'slug', 'list_id'],
             require_auth=True, **kwargs
         )
 
+    @payload('list')
     def add_list_members(self, screen_name=None, user_id=None, slug=None,
-                         list_id=None, owner_id=None, owner_screen_name=None):
+                         list_id=None, owner_id=None, owner_screen_name=None,
+                         **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-members-create_all
             :allowed_param: 'screen_name', 'user_id', 'slug', 'list_id',
                             'owner_id', 'owner_screen_name'
@@ -1057,15 +1059,15 @@ class API:
             api=self,
             path='/lists/members/create_all.json',
             method='POST',
-            payload_type='list',
             allowed_param=['screen_name', 'user_id', 'slug', 'list_id',
                            'owner_id', 'owner_screen_name'],
-            require_auth=True
+            require_auth=True, **kwargs
         )
 
+    @payload('list')
     def remove_list_members(self, screen_name=None, user_id=None, slug=None,
                             list_id=None, owner_id=None,
-                            owner_screen_name=None):
+                            owner_screen_name=None, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-members-destroy_all
             :allowed_param: 'screen_name', 'user_id', 'slug', 'list_id',
                             'owner_id', 'owner_screen_name'
@@ -1076,13 +1078,13 @@ class API:
             api=self,
             path='/lists/members/destroy_all.json',
             method='POST',
-            payload_type='list',
             allowed_param=['screen_name', 'user_id', 'slug', 'list_id',
                            'owner_id', 'owner_screen_name'],
-            require_auth=True
+            require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('user', list=True)
     def list_members(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-members
             :allowed_param: 'owner_screen_name', 'slug', 'list_id', 'owner_id',
@@ -1091,11 +1093,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/lists/members.json',
-            payload_type='user', payload_list=True,
             allowed_param=['owner_screen_name', 'slug', 'list_id', 'owner_id',
                            'cursor'], **kwargs
         )
 
+    @payload('user')
     def show_list_member(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-members-show
             :allowed_param: 'list_id', 'slug', 'user_id', 'screen_name',
@@ -1104,11 +1106,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/lists/members/show.json',
-            payload_type='user',
             allowed_param=['list_id', 'slug', 'user_id', 'screen_name',
                            'owner_screen_name', 'owner_id'], **kwargs
         )
 
+    @payload('list')
     def subscribe_list(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-create
             :allowed_param: 'owner_screen_name', 'slug', 'owner_id', 'list_id'
@@ -1117,11 +1119,11 @@ class API:
             *args, api=self,
             path='/lists/subscribers/create.json',
             method='POST',
-            payload_type='list',
             allowed_param=['owner_screen_name', 'slug', 'owner_id', 'list_id'],
             require_auth=True, **kwargs
         )
 
+    @payload('list')
     def unsubscribe_list(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-destroy
             :allowed_param: 'owner_screen_name', 'slug', 'owner_id', 'list_id'
@@ -1130,12 +1132,12 @@ class API:
             *args, api=self,
             path='/lists/subscribers/destroy.json',
             method='POST',
-            payload_type='list',
             allowed_param=['owner_screen_name', 'slug', 'owner_id', 'list_id'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='cursor')
+    @payload('user', list=True)
     def list_subscribers(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers
             :allowed_param: 'owner_screen_name', 'slug', 'owner_id', 'list_id',
@@ -1145,12 +1147,12 @@ class API:
         return bind_api(
             *args, api=self,
             path='/lists/subscribers.json',
-            payload_type='user', payload_list=True,
             allowed_param=['owner_screen_name', 'slug', 'owner_id', 'list_id',
                            'cursor', 'count', 'include_entities',
                            'skip_status'], **kwargs
         )
 
+    @payload('user')
     def show_list_subscriber(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers-show
             :allowed_param: 'owner_screen_name', 'slug', 'screen_name',
@@ -1159,19 +1161,20 @@ class API:
         return bind_api(
             *args, api=self,
             path='/lists/subscribers/show.json',
-            payload_type='user',
             allowed_param=['owner_screen_name', 'slug', 'screen_name',
                            'owner_id', 'list_id', 'user_id'], **kwargs
         )
 
+    @payload('json')
     def trends_available(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/trends/locations-with-trending-topics/api-reference/get-trends-available """
         return bind_api(
             *args, api=self,
             path='/trends/available.json',
-            payload_type='json', **kwargs
+            **kwargs
         )
 
+    @payload('json')
     def trends_place(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/trends/trends-for-location/api-reference/get-trends-place
             :allowed_param: 'id', 'exclude'
@@ -1179,10 +1182,10 @@ class API:
         return bind_api(
             *args, api=self,
             path='/trends/place.json',
-            payload_type='json',
             allowed_param=['id', 'exclude'], **kwargs
         )
 
+    @payload('json')
     def trends_closest(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/trends/locations-with-trending-topics/api-reference/get-trends-closest
             :allowed_param: 'lat', 'long'
@@ -1190,11 +1193,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/trends/closest.json',
-            payload_type='json',
             allowed_param=['lat', 'long'], **kwargs
         )
 
     @pagination(mode='id')
+    @payload('search_results')
     def search(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets
             :allowed_param: 'q', 'lang', 'locale', 'since_id', 'geocode',
@@ -1204,13 +1207,13 @@ class API:
         return bind_api(
             *args, api=self,
             path='/search/tweets.json',
-            payload_type='search_results',
             allowed_param=['q', 'lang', 'locale', 'since_id', 'geocode',
                            'max_id', 'until', 'result_type', 'count',
                            'include_entities'], **kwargs
         )
 
     @pagination(mode='next')
+    @payload('status', list=True)
     def search_30_day(self, environment_name, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/search/api-reference/premium-search
             :allowed_param: 'query', 'tag', 'fromDate', 'toDate', 'maxResults',
@@ -1219,13 +1222,13 @@ class API:
         return bind_api(
             *args, api=self,
             path=f'/tweets/search/30day/{environment_name}.json',
-            payload_type='status', payload_list=True,
             allowed_param=['query', 'tag', 'fromDate', 'toDate', 'maxResults',
                            'next'],
             require_auth=True, **kwargs
         )
 
     @pagination(mode='next')
+    @payload('status', list=True)
     def search_full_archive(self, environment_name, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/tweets/search/api-reference/premium-search
             :allowed_param: 'query', 'tag', 'fromDate', 'toDate', 'maxResults',
@@ -1234,12 +1237,12 @@ class API:
         return bind_api(
             *args, api=self,
             path=f'/tweets/search/fullarchive/{environment_name}.json',
-            payload_type='status', payload_list=True,
             allowed_param=['query', 'tag', 'fromDate', 'toDate', 'maxResults',
                            'next'],
             require_auth=True, **kwargs
         )
 
+    @payload('place', list=True)
     def reverse_geocode(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/geo/places-near-location/api-reference/get-geo-reverse_geocode
             :allowed_param: 'lat', 'long', 'accuracy', 'granularity',
@@ -1248,11 +1251,11 @@ class API:
         return bind_api(
             *args, api=self,
             path='/geo/reverse_geocode.json',
-            payload_type='place', payload_list=True,
             allowed_param=['lat', 'long', 'accuracy', 'granularity',
                            'max_results'], **kwargs
         )
 
+    @payload('place')
     def geo_id(self, place_id, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/geo/place-information/api-reference/get-geo-id-place_id
             :allowed_param:
@@ -1260,9 +1263,10 @@ class API:
         return bind_api(
             *args, api=self,
             path=f'/geo/id/{place_id}.json',
-            payload_type='place', **kwargs
+            **kwargs
         )
 
+    @payload('place', list=True)
     def geo_search(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/geo/places-near-location/api-reference/get-geo-search
             :allowed_param: 'lat', 'long', 'query', 'ip', 'granularity',
@@ -1272,27 +1276,26 @@ class API:
         return bind_api(
             *args, api=self,
             path='/geo/search.json',
-            payload_type='place', payload_list=True,
             allowed_param=['lat', 'long', 'query', 'ip', 'granularity',
                            'accuracy', 'max_results', 'contained_within'],
             **kwargs
         )
 
+    @payload('json')
     def supported_languages(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/developer-utilities/supported-languages/api-reference/get-help-languages """
         return bind_api(
             *args, api=self,
             path='/help/languages.json',
-            payload_type='json',
             require_auth=True, **kwargs
         )
 
+    @payload('json')
     def configuration(self, *args, **kwargs):
         """ :reference: https://developer.twitter.com/en/docs/developer-utilities/configuration/api-reference/get-help-configuration """
         return bind_api(
             *args, api=self,
             path='/help/configuration.json',
-            payload_type='json',
             require_auth=True, **kwargs
         )
 
index 2f64c68c43691f0a39b23e880c8cd7aaf0ca0419..7e2a8a71417e4593ad54023c2bfcf61bdbc3ff5a 100644 (file)
@@ -19,8 +19,6 @@ class APIMethod:
 
     def __init__(self, *args, **kwargs):
         self.api = api = kwargs.pop('api')
-        self.payload_type = kwargs.pop('payload_type', None)
-        self.payload_list = kwargs.pop('payload_list', False)
         self.allowed_param = kwargs.pop('allowed_param', [])
         self.session = requests.Session()
 
@@ -52,8 +50,9 @@ class APIMethod:
         log.debug("PARAMS: %r", self.session.params)
 
     def execute(self, method, path, *, headers=None, json_payload=None,
-                post_data=None, require_auth=False, return_cursors=False,
-                upload_api=False, use_cache=True):
+                payload_list=False, payload_type=None, post_data=None,
+                require_auth=False, return_cursors=False, upload_api=False,
+                use_cache=True):
         # If authentication is required and no credentials
         # are provided, throw an error.
         if require_auth and not self.api.auth:
@@ -170,7 +169,9 @@ class APIMethod:
         # Parse the response payload
         return_cursors = (return_cursors or
                           'cursor' in self.session.params or 'next' in self.session.params)
-        result = self.parser.parse(self, resp.text, return_cursors=return_cursors)
+        result = self.parser.parse(self, resp.text, payload_list=payload_list,
+                                   payload_type=payload_type,
+                                   return_cursors=return_cursors)
 
         # Store result into cache if one is available.
         if use_cache and self.api.cache and method == 'GET' and result:
@@ -184,6 +185,8 @@ def bind_api(*args, **kwargs):
     path = kwargs.pop('path')
     headers = kwargs.pop('headers', {})
     json_payload = kwargs.pop('json_payload', None)
+    payload_list = kwargs.pop('payload_list', False)
+    payload_type = kwargs.pop('payload_type', None)
     post_data = kwargs.pop('post_data', None)
     require_auth = kwargs.pop('require_auth', False)
     return_cursors = kwargs.pop('return_cursors', False)
@@ -197,6 +200,7 @@ def bind_api(*args, **kwargs):
         else:
             return method.execute(
                 http_method, path, headers=headers, json_payload=json_payload,
+                payload_list=payload_list, payload_type=payload_type,
                 post_data=post_data, require_auth=require_auth,
                 return_cursors=return_cursors, upload_api=upload_api,
                 use_cache=use_cache
@@ -210,3 +214,16 @@ def pagination(mode):
         method.pagination_mode = mode
         return method
     return decorator
+
+
+def payload(payload_type, **payload_kwargs):
+    payload_list = payload_kwargs.get('list', False)
+    def decorator(method):
+        def wrapper(*args, **kwargs):
+            kwargs['payload_list'] = payload_list
+            kwargs['payload_type'] = payload_type
+            return method(*args, **kwargs)
+        wrapper.payload_list = payload_list
+        wrapper.payload_type = payload_type
+        return wrapper
+    return decorator
index 2031812126037ef9197043683fd8ee0c77ae057f..fbc8ae8138c811387b71d4c81c2e35cbbd927615 100644 (file)
@@ -133,8 +133,14 @@ class IdIterator(BaseIterator):
 
             # This is a special invocation that returns the underlying
             # APIMethod class
-            model = ModelParser().parse(self.method(create=True), data)
-            result = self.method.__self__.parser.parse(self.method(create=True), data)
+            model = ModelParser().parse(self.method(create=True), data,
+                                        payload_list=self.method.payload_list,
+                                        payload_type=self.method.payload_type)
+            result = self.method.__self__.parser.parse(
+                self.method(create=True), data,
+                payload_list=self.method.payload_list,
+                payload_type=self.method.payload_type
+            )
 
             if len(self.results) != 0:
                 self.index += 1
index fb5efde158c96a64a727afa96f7d3e216b034c70..2eea766f05227c3dddcd7cedaf913f494cb964f0 100644 (file)
@@ -43,7 +43,7 @@ class JSONParser(Parser):
 
     payload_format = 'json'
 
-    def parse(self, method, payload, *, return_cursors=False):
+    def parse(self, method, payload, *, return_cursors=False, **kwargs):
         try:
             json = json_lib.loads(payload)
         except Exception as e:
@@ -81,13 +81,14 @@ class ModelParser(JSONParser):
         JSONParser.__init__(self)
         self.model_factory = model_factory or ModelFactory
 
-    def parse(self, method, payload, *, return_cursors=False):
+    def parse(self, method, payload, *, payload_list=False, payload_type=None,
+              return_cursors=False):
         try:
-            if method.payload_type is None:
+            if payload_type is None:
                 return
-            model = getattr(self.model_factory, method.payload_type)
+            model = getattr(self.model_factory, payload_type)
         except AttributeError:
-            raise TweepError(f'No model for this payload type: {method.payload_type}')
+            raise TweepError(f'No model for this payload type: {payload_type}')
 
         json = JSONParser.parse(self, method, payload, return_cursors=return_cursors)
         if isinstance(json, tuple):
@@ -95,7 +96,7 @@ class ModelParser(JSONParser):
         else:
             cursors = None
 
-        if method.payload_list:
+        if payload_list:
             result = model.parse_list(method.api, json)
         else:
             result = model.parse(method.api, json)