2 # Copyright 2009-2010 Joshua Roesslein
3 # See LICENSE for details.
5 from __future__ import print_function
12 from tweepy.binder import bind_api
13 from tweepy.error import TweepError
14 from tweepy.parsers import ModelParser, Parser
15 from tweepy.utils import list_to_csv
21 def __init__(self, auth_handler=None,
22 host='api.twitter.com', search_host='search.twitter.com',
23 upload_host='upload.twitter.com', cache=None, api_root='/1.1',
24 search_root='', upload_root='/1.1', retry_count=0,
25 retry_delay=0, retry_errors=None, timeout=60, parser=None,
26 compression=False, wait_on_rate_limit=False,
27 wait_on_rate_limit_notify=False, proxy=''):
28 """ Api instance Constructor
31 :param host: url of the server of the rest api, default:'api.twitter.com'
32 :param search_host: url of the search server, default:'search.twitter.com'
33 :param upload_host: url of the upload server, default:'upload.twitter.com'
34 :param cache: Cache to query if a GET method is used, default:None
35 :param api_root: suffix of the api version, default:'/1.1'
36 :param search_root: suffix of the search version, default:''
37 :param upload_root: suffix of the upload version, default:'/1.1'
38 :param retry_count: number of allowed retries, default:0
39 :param retry_delay: delay in second between retries, default:0
40 :param retry_errors: default:None
41 :param timeout: delay before to consider the request as timed out in seconds, default:60
42 :param parser: ModelParser instance to parse the responses, default:None
43 :param compression: If the response is compressed, default:False
44 :param wait_on_rate_limit: If the api wait when it hits the rate limit, default:False
45 :param wait_on_rate_limit_notify: If the api print a notification when the rate limit is hit, default:False
46 :param proxy: Url to use as proxy during the HTTP request, default:''
48 :raise TypeError: If the given parser is not a ModelParser instance.
50 self.auth = auth_handler
52 self.search_host = search_host
53 self.upload_host = upload_host
54 self.api_root = api_root
55 self.search_root = search_root
56 self.upload_root = upload_root
58 self.compression = compression
59 self.retry_count = retry_count
60 self.retry_delay = retry_delay
61 self.retry_errors = retry_errors
62 self.timeout = timeout
63 self.wait_on_rate_limit = wait_on_rate_limit
64 self.wait_on_rate_limit_notify = wait_on_rate_limit_notify
65 self.parser = parser or ModelParser()
68 self.proxy['https'] = proxy
70 # Attempt to explain more clearly the parser argument requirements
71 # https://github.com/tweepy/tweepy/issues/421
74 if not isinstance(self.parser, parser_type):
76 '"parser" argument has to be an instance of "{required}".'
77 ' It is currently a {actual}.'.format(
78 required=parser_type.__name__,
79 actual=type(self.parser)
84 def home_timeline(self):
85 """ :reference: https://dev.twitter.com/rest/reference/get/statuses/home_timeline
86 :allowed_param:'since_id', 'max_id', 'count'
90 path='/statuses/home_timeline.json',
91 payload_type='status', payload_list=True,
92 allowed_param=['since_id', 'max_id', 'count'],
96 def statuses_lookup(self, id_, include_entities=None,
97 trim_user=None, map_=None):
98 return self._statuses_lookup(list_to_csv(id_), include_entities,
102 def _statuses_lookup(self):
103 """ :reference: https://dev.twitter.com/rest/reference/get/statuses/lookup
104 :allowed_param:'id', 'include_entities', 'trim_user', 'map'
108 path='/statuses/lookup.json',
109 payload_type='status', payload_list=True,
110 allowed_param=['id', 'include_entities', 'trim_user', 'map'],
115 def user_timeline(self):
116 """ :reference: https://dev.twitter.com/rest/reference/get/statuses/user_timeline
117 :allowed_param:'id', 'user_id', 'screen_name', 'since_id'
121 path='/statuses/user_timeline.json',
122 payload_type='status', payload_list=True,
123 allowed_param=['id', 'user_id', 'screen_name', 'since_id',
124 'max_id', 'count', 'include_rts']
128 def mentions_timeline(self):
129 """ :reference: https://dev.twitter.com/rest/reference/get/statuses/mentions_timeline
130 :allowed_param:'since_id', 'max_id', 'count'
134 path='/statuses/mentions_timeline.json',
135 payload_type='status', payload_list=True,
136 allowed_param=['since_id', 'max_id', 'count'],
141 def related_results(self):
142 """ :reference: https://dev.twitter.com/docs/api/1.1/get/related_results/show/%3id.format
147 path='/related_results/show/{id}.json',
148 payload_type='relation', payload_list=True,
149 allowed_param=['id'],
154 def retweets_of_me(self):
155 """ :reference: https://dev.twitter.com/rest/reference/get/statuses/retweets_of_me
156 :allowed_param:'since_id', 'max_id', 'count'
160 path='/statuses/retweets_of_me.json',
161 payload_type='status', payload_list=True,
162 allowed_param=['since_id', 'max_id', 'count'],
167 def get_status(self):
168 """ :reference: https://dev.twitter.com/rest/reference/get/statuses/show/%3Aid
173 path='/statuses/show.json',
174 payload_type='status',
178 def update_status(self, media_ids=None, *args, **kwargs):
179 """ :reference: https://dev.twitter.com/rest/reference/post/statuses/update
180 :allowed_param:'status', 'in_reply_to_status_id', 'lat', 'long', 'source', 'place_id', 'display_coordinates', 'media_ids'
183 if media_ids is not None:
184 post_data["media_ids"] = list_to_csv(media_ids)
188 path='/statuses/update.json',
190 payload_type='status',
191 allowed_param=['status', 'in_reply_to_status_id', 'lat', 'long', 'source', 'place_id', 'display_coordinates'],
193 )(post_data=post_data, *args, **kwargs)
195 def media_upload(self, filename, *args, **kwargs):
196 """ :reference: https://dev.twitter.com/rest/reference/post/media/upload
199 f = kwargs.pop('file', None)
200 headers, post_data = API._pack_image(filename, 3072, form_field='media', f=f)
201 kwargs.update({'headers': headers, 'post_data': post_data})
205 path='/media/upload.json',
207 payload_type='media',
213 def update_with_media(self, filename, *args, **kwargs):
214 """ :reference: https://dev.twitter.com/rest/reference/post/statuses/update_with_media
215 :allowed_param:'status', 'possibly_sensitive', 'in_reply_to_status_id', 'lat', 'long', 'place_id', 'display_coordinates'
217 f = kwargs.pop('file', None)
218 headers, post_data = API._pack_image(filename, 3072, form_field='media[]', f=f)
219 kwargs.update({'headers': headers, 'post_data': post_data})
223 path='/statuses/update_with_media.json',
225 payload_type='status',
227 'status', 'possibly_sensitive', 'in_reply_to_status_id', 'lat', 'long',
228 'place_id', 'display_coordinates'
234 def destroy_status(self):
235 """ :reference: https://dev.twitter.com/rest/reference/post/statuses/destroy/%3Aid
240 path='/statuses/destroy/{id}.json',
242 payload_type='status',
243 allowed_param=['id'],
249 """ :reference: https://dev.twitter.com/rest/reference/post/statuses/retweet/%3Aid
254 path='/statuses/retweet/{id}.json',
256 payload_type='status',
257 allowed_param=['id'],
263 """ :reference: https://dev.twitter.com/rest/reference/get/statuses/retweets/%3Aid
264 :allowed_param:'id', 'count'
268 path='/statuses/retweets/{id}.json',
269 payload_type='status', payload_list=True,
270 allowed_param=['id', 'count'],
275 def retweeters(self):
276 """ :reference: https://dev.twitter.com/rest/reference/get/statuses/retweeters/ids
277 :allowed_param:'id', 'cursor', 'stringify_ids
281 path='/statuses/retweeters/ids.json',
283 allowed_param=['id', 'cursor', 'stringify_ids']
288 """ :reference: https://dev.twitter.com/rest/reference/get/users/show
289 :allowed_param:'id', 'user_id', 'screen_name'
293 path='/users/show.json',
295 allowed_param=['id', 'user_id', 'screen_name']
299 def get_oembed(self):
300 """ :reference: https://dev.twitter.com/rest/reference/get/statuses/oembed
301 :allowed_param:'id', 'url', 'maxwidth', 'hide_media', 'omit_script', 'align', 'related', 'lang'
305 path='/statuses/oembed.json',
307 allowed_param=['id', 'url', 'maxwidth', 'hide_media', 'omit_script', 'align', 'related', 'lang']
310 def lookup_users(self, user_ids=None, screen_names=None, include_entities=None):
311 """ Perform bulk look up of users from user ID or screenname """
313 if include_entities is not None:
314 include_entities = 'true' if include_entities else 'false'
315 post_data['include_entities'] = include_entities
317 post_data['user_id'] = list_to_csv(user_ids)
319 post_data['screen_name'] = list_to_csv(screen_names)
321 return self._lookup_users(post_data=post_data)
324 def _lookup_users(self):
325 """ :reference: https://dev.twitter.com/rest/reference/get/users/lookup
326 allowed_param='user_id', 'screen_name', 'include_entities'
330 path='/users/lookup.json',
331 payload_type='user', payload_list=True,
336 """ Get the authenticated user """
337 return self.get_user(screen_name=self.auth.get_username())
340 def search_users(self):
341 """ :reference: https://dev.twitter.com/rest/reference/get/users/search
342 :allowed_param:'q', 'count', 'page'
346 path='/users/search.json',
347 payload_type='user', payload_list=True,
349 allowed_param=['q', 'count', 'page']
353 def suggested_users(self):
354 """ :reference: https://dev.twitter.com/rest/reference/get/users/suggestions/%3Aslug
355 :allowed_param:'slug', 'lang'
359 path='/users/suggestions/{slug}.json',
360 payload_type='user', payload_list=True,
362 allowed_param=['slug', 'lang']
366 def suggested_categories(self):
367 """ :reference: https://dev.twitter.com/rest/reference/get/users/suggestions
368 :allowed_param:'lang'
372 path='/users/suggestions.json',
373 payload_type='category', payload_list=True,
374 allowed_param=['lang'],
379 def suggested_users_tweets(self):
380 """ :reference: https://dev.twitter.com/rest/reference/get/users/suggestions/%3Aslug/members
381 :allowed_param:'slug'
385 path='/users/suggestions/{slug}/members.json',
386 payload_type='status', payload_list=True,
387 allowed_param=['slug'],
392 def direct_messages(self):
393 """ :reference: https://dev.twitter.com/rest/reference/get/direct_messages
394 :allowed_param:'since_id', 'max_id', 'count'
398 path='/direct_messages.json',
399 payload_type='direct_message', payload_list=True,
400 allowed_param=['since_id', 'max_id', 'count'],
405 def get_direct_message(self):
406 """ :reference: https://dev.twitter.com/rest/reference/get/direct_messages/show
411 path='/direct_messages/show/{id}.json',
412 payload_type='direct_message',
413 allowed_param=['id'],
418 def sent_direct_messages(self):
419 """ :reference: https://dev.twitter.com/rest/reference/get/direct_messages/sent
420 :allowed_param:'since_id', 'max_id', 'count', 'page'
424 path='/direct_messages/sent.json',
425 payload_type='direct_message', payload_list=True,
426 allowed_param=['since_id', 'max_id', 'count', 'page'],
431 def send_direct_message(self):
432 """ :reference: https://dev.twitter.com/rest/reference/post/direct_messages/new
433 :allowed_param:'user', 'screen_name', 'user_id', 'text'
437 path='/direct_messages/new.json',
439 payload_type='direct_message',
440 allowed_param=['user', 'screen_name', 'user_id', 'text'],
445 def destroy_direct_message(self):
446 """ :reference: https://dev.twitter.com/rest/reference/post/direct_messages/destroy
451 path='/direct_messages/destroy.json',
453 payload_type='direct_message',
454 allowed_param=['id'],
459 def create_friendship(self):
460 """ :reference: https://dev.twitter.com/rest/reference/post/friendships/create
461 :allowed_param:'id', 'user_id', 'screen_name', 'follow'
465 path='/friendships/create.json',
468 allowed_param=['id', 'user_id', 'screen_name', 'follow'],
473 def destroy_friendship(self):
474 """ :reference: https://dev.twitter.com/rest/reference/post/friendships/destroy
475 :allowed_param:'id', 'user_id', 'screen_name'
479 path='/friendships/destroy.json',
482 allowed_param=['id', 'user_id', 'screen_name'],
487 def show_friendship(self):
488 """ :reference: https://dev.twitter.com/rest/reference/get/friendships/show
489 :allowed_param:'source_id', 'source_screen_name'
493 path='/friendships/show.json',
494 payload_type='friendship',
495 allowed_param=['source_id', 'source_screen_name',
496 'target_id', 'target_screen_name']
499 def lookup_friendships(self, user_ids=None, screen_names=None):
500 """ Perform bulk look up of friendships from user ID or screenname """
501 return self._lookup_friendships(list_to_csv(user_ids), list_to_csv(screen_names))
504 def _lookup_friendships(self):
505 """ :reference: https://dev.twitter.com/rest/reference/get/friendships/lookup
506 :allowed_param:'user_id', 'screen_name'
510 path='/friendships/lookup.json',
511 payload_type='relationship', payload_list=True,
512 allowed_param=['user_id', 'screen_name'],
517 def friends_ids(self):
518 """ :reference: https://dev.twitter.com/rest/reference/get/friends/ids
519 :allowed_param:'id', 'user_id', 'screen_name', 'cursor'
523 path='/friends/ids.json',
525 allowed_param=['id', 'user_id', 'screen_name', 'cursor']
530 """ :reference: https://dev.twitter.com/rest/reference/get/friends/list
531 :allowed_param:'id', 'user_id', 'screen_name', 'cursor', 'skip_status', 'include_user_entities'
535 path='/friends/list.json',
536 payload_type='user', payload_list=True,
537 allowed_param=['id', 'user_id', 'screen_name', 'cursor', 'skip_status', 'include_user_entities']
541 def friendships_incoming(self):
542 """ :reference: https://dev.twitter.com/rest/reference/get/friendships/incoming
543 :allowed_param:'cursor'
547 path='/friendships/incoming.json',
549 allowed_param=['cursor']
553 def friendships_outgoing(self):
554 """ :reference: https://dev.twitter.com/rest/reference/get/friendships/outgoing
555 :allowed_param:'cursor'
559 path='/friendships/outgoing.json',
561 allowed_param=['cursor']
565 def followers_ids(self):
566 """ :reference: https://dev.twitter.com/rest/reference/get/followers/ids
567 :allowed_param:'id', 'user_id', 'screen_name', 'cursor', 'count'
571 path='/followers/ids.json',
573 allowed_param=['id', 'user_id', 'screen_name', 'cursor', 'count']
578 """ :reference: https://dev.twitter.com/rest/reference/get/followers/list
579 :allowed_param:'id', 'user_id', 'screen_name', 'cursor', 'count', 'skip_status', 'include_user_entities'
583 path='/followers/list.json',
584 payload_type='user', payload_list=True,
585 allowed_param=['id', 'user_id', 'screen_name', 'cursor', 'count',
586 'skip_status', 'include_user_entities']
590 def get_settings(self):
591 """ :reference: https://dev.twitter.com/rest/reference/get/account/settings
595 path='/account/settings.json',
601 def set_settings(self):
602 """ :reference: https://dev.twitter.com/rest/reference/post/account/settings
603 :allowed_param:'sleep_time_enabled', 'start_sleep_time',
604 'end_sleep_time', 'time_zone', 'trend_location_woeid',
605 'allow_contributor_request', 'lang'
609 path='/account/settings.json',
612 allowed_param=['sleep_time_enabled', 'start_sleep_time',
613 'end_sleep_time', 'time_zone',
614 'trend_location_woeid', 'allow_contributor_request',
619 def verify_credentials(self, **kargs):
620 """ :reference: https://dev.twitter.com/rest/reference/get/account/verify_credentials
621 :allowed_param:'include_entities', 'skip_status', 'include_email'
626 path='/account/verify_credentials.json',
629 allowed_param=['include_entities', 'skip_status', 'include_email'],
631 except TweepError as e:
632 if e.response and e.response.status == 401:
637 def rate_limit_status(self):
638 """ :reference: https://dev.twitter.com/rest/reference/get/application/rate_limit_status
639 :allowed_param:'resources'
643 path='/application/rate_limit_status.json',
645 allowed_param=['resources'],
650 def set_delivery_device(self):
651 """ :reference: https://dev.twitter.com/rest/reference/post/account/update_delivery_device
652 :allowed_param:'device'
656 path='/account/update_delivery_device.json',
658 allowed_param=['device'],
664 def update_profile_colors(self):
665 """ :reference: https://dev.twitter.com/docs/api/1.1/post/account/update_profile_colors
666 :allowed_param:'profile_background_color', 'profile_text_color',
667 'profile_link_color', 'profile_sidebar_fill_color',
668 'profile_sidebar_border_color'],
672 path='/account/update_profile_colors.json',
675 allowed_param=['profile_background_color', 'profile_text_color',
676 'profile_link_color', 'profile_sidebar_fill_color',
677 'profile_sidebar_border_color'],
681 def update_profile_image(self, filename, file_=None):
682 """ :reference: https://dev.twitter.com/rest/reference/post/account/update_profile_image
683 :allowed_param:'include_entities', 'skip_status'
685 headers, post_data = API._pack_image(filename, 700, f=file_)
688 path='/account/update_profile_image.json',
691 allowed_param=['include_entities', 'skip_status'],
693 )(self, post_data=post_data, headers=headers)
695 def update_profile_background_image(self, filename, **kargs):
696 """ :reference: https://dev.twitter.com/rest/reference/post/account/update_profile_background_image
697 :allowed_param:'tile', 'include_entities', 'skip_status', 'use'
699 f = kargs.pop('file', None)
700 headers, post_data = API._pack_image(filename, 800, f=f)
703 path='/account/update_profile_background_image.json',
706 allowed_param=['tile', 'include_entities', 'skip_status', 'use'],
708 )(post_data=post_data, headers=headers)
710 def update_profile_banner(self, filename, **kargs):
711 """ :reference: https://dev.twitter.com/rest/reference/post/account/update_profile_banner
712 :allowed_param:'width', 'height', 'offset_left', 'offset_right'
714 f = kargs.pop('file', None)
715 headers, post_data = API._pack_image(filename, 700, form_field="banner", f=f)
718 path='/account/update_profile_banner.json',
720 allowed_param=['width', 'height', 'offset_left', 'offset_right'],
722 )(post_data=post_data, headers=headers)
725 def update_profile(self):
726 """ :reference: https://dev.twitter.com/rest/reference/post/account/update_profile
727 :allowed_param:'name', 'url', 'location', 'description'
731 path='/account/update_profile.json',
734 allowed_param=['name', 'url', 'location', 'description'],
740 """ :reference: https://dev.twitter.com/rest/reference/get/favorites/list
741 :allowed_param:'screen_name', 'user_id', 'max_id', 'count', 'since_id', 'max_id'
745 path='/favorites/list.json',
746 payload_type='status', payload_list=True,
747 allowed_param=['screen_name', 'user_id', 'max_id', 'count', 'since_id', 'max_id']
751 def create_favorite(self):
752 """ :reference:https://dev.twitter.com/rest/reference/post/favorites/create
757 path='/favorites/create.json',
759 payload_type='status',
760 allowed_param=['id'],
765 def destroy_favorite(self):
766 """ :reference: https://dev.twitter.com/rest/reference/post/favorites/destroy
771 path='/favorites/destroy.json',
773 payload_type='status',
774 allowed_param=['id'],
779 def create_block(self):
780 """ :reference: https://dev.twitter.com/rest/reference/post/blocks/create
781 :allowed_param:'id', 'user_id', 'screen_name'
785 path='/blocks/create.json',
788 allowed_param=['id', 'user_id', 'screen_name'],
793 def destroy_block(self):
794 """ :reference: https://dev.twitter.com/rest/reference/post/blocks/destroy
795 :allowed_param:'id', 'user_id', 'screen_name'
799 path='/blocks/destroy.json',
802 allowed_param=['id', 'user_id', 'screen_name'],
808 """ :reference: https://dev.twitter.com/rest/reference/get/blocks/list
809 :allowed_param:'cursor'
813 path='/blocks/list.json',
814 payload_type='user', payload_list=True,
815 allowed_param=['cursor'],
820 def blocks_ids(self):
821 """ :reference: https://dev.twitter.com/rest/reference/get/blocks/ids """
824 path='/blocks/ids.json',
830 def report_spam(self):
831 """ :reference: https://dev.twitter.com/rest/reference/post/users/report_spam
832 :allowed_param:'user_id', 'screen_name'
836 path='/users/report_spam.json',
839 allowed_param=['user_id', 'screen_name'],
844 def saved_searches(self):
845 """ :reference: https://dev.twitter.com/rest/reference/get/saved_searches/show/%3Aid """
848 path='/saved_searches/list.json',
849 payload_type='saved_search', payload_list=True,
854 def get_saved_search(self):
855 """ :reference: https://dev.twitter.com/rest/reference/get/saved_searches/show/%3Aid
860 path='/saved_searches/show/{id}.json',
861 payload_type='saved_search',
862 allowed_param=['id'],
867 def create_saved_search(self):
868 """ :reference: https://dev.twitter.com/rest/reference/post/saved_searches/create
869 :allowed_param:'query'
873 path='/saved_searches/create.json',
875 payload_type='saved_search',
876 allowed_param=['query'],
881 def destroy_saved_search(self):
882 """ :reference: https://dev.twitter.com/rest/reference/post/saved_searches/destroy/%3Aid
887 path='/saved_searches/destroy/{id}.json',
889 payload_type='saved_search',
890 allowed_param=['id'],
895 def create_list(self):
896 """ :reference: https://dev.twitter.com/rest/reference/post/lists/create
897 :allowed_param:'name', 'mode', 'description'
901 path='/lists/create.json',
904 allowed_param=['name', 'mode', 'description'],
909 def destroy_list(self):
910 """ :reference: https://dev.twitter.com/rest/reference/post/lists/destroy
911 :allowed_param:'owner_screen_name', 'owner_id', 'list_id', 'slug'
915 path='/lists/destroy.json',
918 allowed_param=['owner_screen_name', 'owner_id', 'list_id', 'slug'],
923 def update_list(self):
924 """ :reference: https://dev.twitter.com/rest/reference/post/lists/update
925 :allowed_param: list_id', 'slug', 'name', 'mode', 'description', 'owner_screen_name', 'owner_id'
929 path='/lists/update.json',
932 allowed_param=['list_id', 'slug', 'name', 'mode', 'description', 'owner_screen_name', 'owner_id'],
938 """ :reference: https://dev.twitter.com/rest/reference/get/lists/list
939 :allowed_param:'screen_name', 'user_id'
943 path='/lists/list.json',
944 payload_type='list', payload_list=True,
945 allowed_param=['screen_name', 'user_id'],
950 def lists_memberships(self):
951 """ :reference: https://dev.twitter.com/rest/reference/get/lists/memberships
952 :allowed_param:'screen_name', 'user_id', 'filter_to_owned_lists', 'cursor'
956 path='/lists/memberships.json',
957 payload_type='list', payload_list=True,
958 allowed_param=['screen_name', 'user_id', 'filter_to_owned_lists', 'cursor'],
963 def lists_subscriptions(self):
964 """ :reference: https://dev.twitter.com/rest/reference/get/lists/subscriptions
965 :allowed_param:'screen_name', 'user_id', 'cursor'
969 path='/lists/subscriptions.json',
970 payload_type='list', payload_list=True,
971 allowed_param=['screen_name', 'user_id', 'cursor'],
976 def list_timeline(self):
977 """ :reference: https://dev.twitter.com/docs/api/1.1/get/lists/statuses
978 :allowed_param:'owner_screen_name', 'slug', 'owner_id', 'list_id',
979 'since_id', 'max_id', 'count', 'include_rts
983 path='/lists/statuses.json',
984 payload_type='status', payload_list=True,
985 allowed_param=['owner_screen_name', 'slug', 'owner_id',
986 'list_id', 'since_id', 'max_id', 'count',
992 """ :reference: https://dev.twitter.com/rest/reference/get/lists/show
993 :allowed_param:'owner_screen_name', 'owner_id', 'slug', 'list_id'
997 path='/lists/show.json',
999 allowed_param=['owner_screen_name', 'owner_id', 'slug', 'list_id']
1003 def add_list_member(self):
1004 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/members/create
1005 :allowed_param:'screen_name', 'user_id', 'owner_screen_name',
1006 'owner_id', 'slug', 'list_id'
1010 path='/lists/members/create.json',
1012 payload_type='list',
1013 allowed_param=['screen_name', 'user_id', 'owner_screen_name',
1014 'owner_id', 'slug', 'list_id'],
1019 def remove_list_member(self):
1020 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/members/destroy
1021 :allowed_param:'screen_name', 'user_id', 'owner_screen_name',
1022 'owner_id', 'slug', 'list_id'
1026 path='/lists/members/destroy.json',
1028 payload_type='list',
1029 allowed_param=['screen_name', 'user_id', 'owner_screen_name',
1030 'owner_id', 'slug', 'list_id'],
1034 def add_list_members(self, screen_name=None, user_id=None, slug=None,
1035 list_id=None, owner_id=None, owner_screen_name=None):
1036 """ Perform bulk add of list members from user ID or screenname """
1037 return self._add_list_members(list_to_csv(screen_name),
1038 list_to_csv(user_id),
1039 slug, list_id, owner_id,
1043 def _add_list_members(self):
1044 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/members/create_all
1045 :allowed_param:'screen_name', 'user_id', 'slug', 'list_id',
1046 'owner_id', 'owner_screen_name'
1051 path='/lists/members/create_all.json',
1053 payload_type='list',
1054 allowed_param=['screen_name', 'user_id', 'slug', 'list_id',
1055 'owner_id', 'owner_screen_name'],
1059 def remove_list_members(self, screen_name=None, user_id=None, slug=None,
1060 list_id=None, owner_id=None, owner_screen_name=None):
1061 """ Perform bulk remove of list members from user ID or screenname """
1062 return self._remove_list_members(list_to_csv(screen_name),
1063 list_to_csv(user_id),
1064 slug, list_id, owner_id,
1068 def _remove_list_members(self):
1069 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/members/destroy_all
1070 :allowed_param:'screen_name', 'user_id', 'slug', 'list_id',
1071 'owner_id', 'owner_screen_name'
1076 path='/lists/members/destroy_all.json',
1078 payload_type='list',
1079 allowed_param=['screen_name', 'user_id', 'slug', 'list_id',
1080 'owner_id', 'owner_screen_name'],
1085 def list_members(self):
1086 """ :reference: https://dev.twitter.com/docs/api/1.1/get/lists/members
1087 :allowed_param:'owner_screen_name', 'slug', 'list_id',
1092 path='/lists/members.json',
1093 payload_type='user', payload_list=True,
1094 allowed_param=['owner_screen_name', 'slug', 'list_id',
1095 'owner_id', 'cursor']
1099 def show_list_member(self):
1100 """ :reference: https://dev.twitter.com/docs/api/1.1/get/lists/members/show
1101 :allowed_param:'list_id', 'slug', 'user_id', 'screen_name',
1102 'owner_screen_name', 'owner_id
1106 path='/lists/members/show.json',
1107 payload_type='user',
1108 allowed_param=['list_id', 'slug', 'user_id', 'screen_name',
1109 'owner_screen_name', 'owner_id']
1113 def subscribe_list(self):
1114 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/subscribers/create
1115 :allowed_param:'owner_screen_name', 'slug', 'owner_id',
1120 path='/lists/subscribers/create.json',
1122 payload_type='list',
1123 allowed_param=['owner_screen_name', 'slug', 'owner_id',
1129 def unsubscribe_list(self):
1130 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/subscribers/destroy
1131 :allowed_param:'owner_screen_name', 'slug', 'owner_id',
1136 path='/lists/subscribers/destroy.json',
1138 payload_type='list',
1139 allowed_param=['owner_screen_name', 'slug', 'owner_id',
1145 def list_subscribers(self):
1146 """ :reference: https://dev.twitter.com/docs/api/1.1/get/lists/subscribers
1147 :allowed_param:'owner_screen_name', 'slug', 'owner_id',
1152 path='/lists/subscribers.json',
1153 payload_type='user', payload_list=True,
1154 allowed_param=['owner_screen_name', 'slug', 'owner_id',
1155 'list_id', 'cursor']
1159 def show_list_subscriber(self):
1160 """ :reference: https://dev.twitter.com/docs/api/1.1/get/lists/subscribers/show
1161 :allowed_param:'owner_screen_name', 'slug', 'screen_name',
1162 'owner_id', 'list_id', 'user_id
1166 path='/lists/subscribers/show.json',
1167 payload_type='user',
1168 allowed_param=['owner_screen_name', 'slug', 'screen_name',
1169 'owner_id', 'list_id', 'user_id']
1173 def trends_available(self):
1174 """ :reference: https://dev.twitter.com/rest/reference/get/trends/available """
1177 path='/trends/available.json',
1182 def trends_place(self):
1183 """ :reference: https://dev.twitter.com/rest/reference/get/trends/place
1184 :allowed_param:'id', 'exclude'
1188 path='/trends/place.json',
1189 payload_type='json',
1190 allowed_param=['id', 'exclude']
1194 def trends_closest(self):
1195 """ :reference: https://dev.twitter.com/rest/reference/get/trends/closest
1196 :allowed_param:'lat', 'long'
1200 path='/trends/closest.json',
1201 payload_type='json',
1202 allowed_param=['lat', 'long']
1207 """ :reference: https://dev.twitter.com/rest/reference/get/search/tweets
1208 :allowed_param:'q', 'lang', 'locale', 'since_id', 'geocode',
1209 'max_id', 'since', 'until', 'result_type', 'count',
1210 'include_entities', 'from', 'to', 'source']
1214 path='/search/tweets.json',
1215 payload_type='search_results',
1216 allowed_param=['q', 'lang', 'locale', 'since_id', 'geocode',
1217 'max_id', 'since', 'until', 'result_type',
1218 'count', 'include_entities', 'from',
1223 def reverse_geocode(self):
1224 """ :reference: https://dev.twitter.com/rest/reference/get/geo/reverse_geocode
1225 :allowed_param:'lat', 'long', 'accuracy', 'granularity', 'max_results'
1229 path='/geo/reverse_geocode.json',
1230 payload_type='place', payload_list=True,
1231 allowed_param=['lat', 'long', 'accuracy', 'granularity',
1237 """ :reference: https://dev.twitter.com/rest/reference/get/geo/id/%3Aplace_id
1242 path='/geo/id/{id}.json',
1243 payload_type='place',
1244 allowed_param=['id']
1248 def geo_search(self):
1249 """ :reference: https://dev.twitter.com/docs/api/1.1/get/geo/search
1250 :allowed_param:'lat', 'long', 'query', 'ip', 'granularity',
1251 'accuracy', 'max_results', 'contained_within
1256 path='/geo/search.json',
1257 payload_type='place', payload_list=True,
1258 allowed_param=['lat', 'long', 'query', 'ip', 'granularity',
1259 'accuracy', 'max_results', 'contained_within']
1263 def geo_similar_places(self):
1264 """ :reference: https://dev.twitter.com/rest/reference/get/geo/similar_places
1265 :allowed_param:'lat', 'long', 'name', 'contained_within'
1269 path='/geo/similar_places.json',
1270 payload_type='place', payload_list=True,
1271 allowed_param=['lat', 'long', 'name', 'contained_within']
1275 def supported_languages(self):
1276 """ :reference: https://dev.twitter.com/rest/reference/get/help/languages """
1279 path='/help/languages.json',
1280 payload_type='json',
1285 def configuration(self):
1286 """ :reference: https://dev.twitter.com/rest/reference/get/help/configuration """
1289 path='/help/configuration.json',
1290 payload_type='json',
1294 """ Internal use only """
1297 def _pack_image(filename, max_size, form_field="image", f=None):
1298 """Pack image from file into multipart-formdata post body"""
1299 # image must be less than 700kb in size
1302 if os.path.getsize(filename) > (max_size * 1024):
1303 raise TweepError('File is too big, must be less than %skb.' % max_size)
1304 except os.error as e:
1305 raise TweepError('Unable to access file: %s' % e.strerror)
1307 # build the mulitpart-formdata body
1308 fp = open(filename, 'rb')
1310 f.seek(0, 2) # Seek to end of file
1311 if f.tell() > (max_size * 1024):
1312 raise TweepError('File is too big, must be less than %skb.' % max_size)
1313 f.seek(0) # Reset to beginning of file
1316 # image must be gif, jpeg, or png
1317 file_type = mimetypes.guess_type(filename)
1318 if file_type is None:
1319 raise TweepError('Could not determine file type')
1320 file_type = file_type[0]
1321 if file_type not in ['image/gif', 'image/jpeg', 'image/png']:
1322 raise TweepError('Invalid file type for image: %s' % file_type)
1324 if isinstance(filename, six.text_type):
1325 filename = filename.encode("utf-8")
1327 BOUNDARY = b'Tw3ePy'
1329 body.append(b'--' + BOUNDARY)
1330 body.append('Content-Disposition: form-data; name="{0}";'
1331 ' filename="{1}"'.format(form_field, filename)
1333 body.append('Content-Type: {0}'.format(file_type).encode('utf-8'))
1335 body.append(fp.read())
1336 body.append(b'--' + BOUNDARY + b'--')
1339 body = b'\r\n'.join(body)
1343 'Content-Type': 'multipart/form-data; boundary=Tw3ePy',
1344 'Content-Length': str(len(body))
1347 return headers, body