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'
535 path='/friends/list.json',
536 payload_type='user', payload_list=True,
537 allowed_param=['id', 'user_id', 'screen_name', 'cursor']
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']
589 def verify_credentials(self, **kargs):
590 """ :reference: https://dev.twitter.com/rest/reference/get/account/verify_credentials
591 :allowed_param:'include_entities', 'skip_status'
596 path='/account/verify_credentials.json',
599 allowed_param=['include_entities', 'skip_status'],
601 except TweepError as e:
602 if e.response and e.response.status == 401:
607 def rate_limit_status(self):
608 """ :reference: https://dev.twitter.com/rest/reference/get/application/rate_limit_status
609 :allowed_param:'resources'
613 path='/application/rate_limit_status.json',
615 allowed_param=['resources'],
620 def set_delivery_device(self):
621 """ :reference: https://dev.twitter.com/rest/reference/post/account/update_delivery_device
622 :allowed_param:'device'
626 path='/account/update_delivery_device.json',
628 allowed_param=['device'],
634 def update_profile_colors(self):
635 """ :reference: https://dev.twitter.com/docs/api/1.1/post/account/update_profile_colors
636 :allowed_param:'profile_background_color', 'profile_text_color',
637 'profile_link_color', 'profile_sidebar_fill_color',
638 'profile_sidebar_border_color'],
642 path='/account/update_profile_colors.json',
645 allowed_param=['profile_background_color', 'profile_text_color',
646 'profile_link_color', 'profile_sidebar_fill_color',
647 'profile_sidebar_border_color'],
651 def update_profile_image(self, filename, file_=None):
652 """ :reference: https://dev.twitter.com/rest/reference/post/account/update_profile_image
653 :allowed_param:'include_entities', 'skip_status'
655 headers, post_data = API._pack_image(filename, 700, f=file_)
658 path='/account/update_profile_image.json',
661 allowed_param=['include_entities', 'skip_status'],
663 )(self, post_data=post_data, headers=headers)
665 def update_profile_background_image(self, filename, **kargs):
666 """ :reference: https://dev.twitter.com/rest/reference/post/account/update_profile_background_image
667 :allowed_param:'tile', 'include_entities', 'skip_status', 'use'
669 f = kargs.pop('file', None)
670 headers, post_data = API._pack_image(filename, 800, f=f)
673 path='/account/update_profile_background_image.json',
676 allowed_param=['tile', 'include_entities', 'skip_status', 'use'],
678 )(post_data=post_data, headers=headers)
680 def update_profile_banner(self, filename, **kargs):
681 """ :reference: https://dev.twitter.com/rest/reference/post/account/update_profile_banner
682 :allowed_param:'width', 'height', 'offset_left', 'offset_right'
684 f = kargs.pop('file', None)
685 headers, post_data = API._pack_image(filename, 700, form_field="banner", f=f)
688 path='/account/update_profile_banner.json',
690 allowed_param=['width', 'height', 'offset_left', 'offset_right'],
692 )(post_data=post_data, headers=headers)
695 def update_profile(self):
696 """ :reference: https://dev.twitter.com/rest/reference/post/account/update_profile
697 :allowed_param:'name', 'url', 'location', 'description'
701 path='/account/update_profile.json',
704 allowed_param=['name', 'url', 'location', 'description'],
710 """ :reference: https://dev.twitter.com/rest/reference/get/favorites/list
711 :allowed_param:'screen_name', 'user_id', 'max_id', 'count', 'since_id', 'max_id'
715 path='/favorites/list.json',
716 payload_type='status', payload_list=True,
717 allowed_param=['screen_name', 'user_id', 'max_id', 'count', 'since_id', 'max_id']
721 def create_favorite(self):
722 """ :reference:https://dev.twitter.com/rest/reference/post/favorites/create
727 path='/favorites/create.json',
729 payload_type='status',
730 allowed_param=['id'],
735 def destroy_favorite(self):
736 """ :reference: https://dev.twitter.com/rest/reference/post/favorites/destroy
741 path='/favorites/destroy.json',
743 payload_type='status',
744 allowed_param=['id'],
749 def create_block(self):
750 """ :reference: https://dev.twitter.com/rest/reference/post/blocks/create
751 :allowed_param:'id', 'user_id', 'screen_name'
755 path='/blocks/create.json',
758 allowed_param=['id', 'user_id', 'screen_name'],
763 def destroy_block(self):
764 """ :reference: https://dev.twitter.com/rest/reference/post/blocks/destroy
765 :allowed_param:'id', 'user_id', 'screen_name'
769 path='/blocks/destroy.json',
772 allowed_param=['id', 'user_id', 'screen_name'],
778 """ :reference: https://dev.twitter.com/rest/reference/get/blocks/list
779 :allowed_param:'cursor'
783 path='/blocks/list.json',
784 payload_type='user', payload_list=True,
785 allowed_param=['cursor'],
790 def blocks_ids(self):
791 """ :reference: https://dev.twitter.com/rest/reference/get/blocks/ids """
794 path='/blocks/ids.json',
800 def report_spam(self):
801 """ :reference: https://dev.twitter.com/rest/reference/post/users/report_spam
802 :allowed_param:'user_id', 'screen_name'
806 path='/users/report_spam.json',
809 allowed_param=['user_id', 'screen_name'],
814 def saved_searches(self):
815 """ :reference: https://dev.twitter.com/rest/reference/get/saved_searches/show/%3Aid """
818 path='/saved_searches/list.json',
819 payload_type='saved_search', payload_list=True,
824 def get_saved_search(self):
825 """ :reference: https://dev.twitter.com/rest/reference/get/saved_searches/show/%3Aid
830 path='/saved_searches/show/{id}.json',
831 payload_type='saved_search',
832 allowed_param=['id'],
837 def create_saved_search(self):
838 """ :reference: https://dev.twitter.com/rest/reference/post/saved_searches/create
839 :allowed_param:'query'
843 path='/saved_searches/create.json',
845 payload_type='saved_search',
846 allowed_param=['query'],
851 def destroy_saved_search(self):
852 """ :reference: https://dev.twitter.com/rest/reference/post/saved_searches/destroy/%3Aid
857 path='/saved_searches/destroy/{id}.json',
859 payload_type='saved_search',
860 allowed_param=['id'],
865 def create_list(self):
866 """ :reference: https://dev.twitter.com/rest/reference/post/lists/create
867 :allowed_param:'name', 'mode', 'description'
871 path='/lists/create.json',
874 allowed_param=['name', 'mode', 'description'],
879 def destroy_list(self):
880 """ :reference: https://dev.twitter.com/rest/reference/post/lists/destroy
881 :allowed_param:'owner_screen_name', 'owner_id', 'list_id', 'slug'
885 path='/lists/destroy.json',
888 allowed_param=['owner_screen_name', 'owner_id', 'list_id', 'slug'],
893 def update_list(self):
894 """ :reference: https://dev.twitter.com/rest/reference/post/lists/update
895 :allowed_param: list_id', 'slug', 'name', 'mode', 'description', 'owner_screen_name', 'owner_id'
899 path='/lists/update.json',
902 allowed_param=['list_id', 'slug', 'name', 'mode', 'description', 'owner_screen_name', 'owner_id'],
908 """ :reference: https://dev.twitter.com/rest/reference/get/lists/list
909 :allowed_param:'screen_name', 'user_id'
913 path='/lists/list.json',
914 payload_type='list', payload_list=True,
915 allowed_param=['screen_name', 'user_id'],
920 def lists_memberships(self):
921 """ :reference: https://dev.twitter.com/rest/reference/get/lists/memberships
922 :allowed_param:'screen_name', 'user_id', 'filter_to_owned_lists', 'cursor'
926 path='/lists/memberships.json',
927 payload_type='list', payload_list=True,
928 allowed_param=['screen_name', 'user_id', 'filter_to_owned_lists', 'cursor'],
933 def lists_subscriptions(self):
934 """ :reference: https://dev.twitter.com/rest/reference/get/lists/subscriptions
935 :allowed_param:'screen_name', 'user_id', 'cursor'
939 path='/lists/subscriptions.json',
940 payload_type='list', payload_list=True,
941 allowed_param=['screen_name', 'user_id', 'cursor'],
946 def list_timeline(self):
947 """ :reference: https://dev.twitter.com/docs/api/1.1/get/lists/statuses
948 :allowed_param:'owner_screen_name', 'slug', 'owner_id', 'list_id',
949 'since_id', 'max_id', 'count', 'include_rts
953 path='/lists/statuses.json',
954 payload_type='status', payload_list=True,
955 allowed_param=['owner_screen_name', 'slug', 'owner_id',
956 'list_id', 'since_id', 'max_id', 'count',
962 """ :reference: https://dev.twitter.com/rest/reference/get/lists/show
963 :allowed_param:'owner_screen_name', 'owner_id', 'slug', 'list_id'
967 path='/lists/show.json',
969 allowed_param=['owner_screen_name', 'owner_id', 'slug', 'list_id']
973 def add_list_member(self):
974 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/members/create
975 :allowed_param:'screen_name', 'user_id', 'owner_screen_name',
976 'owner_id', 'slug', 'list_id'
980 path='/lists/members/create.json',
983 allowed_param=['screen_name', 'user_id', 'owner_screen_name',
984 'owner_id', 'slug', 'list_id'],
989 def remove_list_member(self):
990 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/members/destroy
991 :allowed_param:'screen_name', 'user_id', 'owner_screen_name',
992 'owner_id', 'slug', 'list_id'
996 path='/lists/members/destroy.json',
999 allowed_param=['screen_name', 'user_id', 'owner_screen_name',
1000 'owner_id', 'slug', 'list_id'],
1004 def add_list_members(self, screen_name=None, user_id=None, slug=None,
1005 list_id=None, owner_id=None, owner_screen_name=None):
1006 """ Perform bulk add of list members from user ID or screenname """
1007 return self._add_list_members(list_to_csv(screen_name),
1008 list_to_csv(user_id),
1009 slug, list_id, owner_id,
1013 def _add_list_members(self):
1014 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/members/create_all
1015 :allowed_param:'screen_name', 'user_id', 'slug', 'lit_id',
1016 'owner_id', 'owner_screen_name'
1021 path='/lists/members/create_all.json',
1023 payload_type='list',
1024 allowed_param=['screen_name', 'user_id', 'slug', 'lit_id',
1025 'owner_id', 'owner_screen_name'],
1029 def remove_list_members(self, screen_name=None, user_id=None, slug=None,
1030 list_id=None, owner_id=None, owner_screen_name=None):
1031 """ Perform bulk remove of list members from user ID or screenname """
1032 return self._remove_list_members(list_to_csv(screen_name),
1033 list_to_csv(user_id),
1034 slug, list_id, owner_id,
1038 def _remove_list_members(self):
1039 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/members/destroy_all
1040 :allowed_param:'screen_name', 'user_id', 'slug', 'lit_id',
1041 'owner_id', 'owner_screen_name'
1046 path='/lists/members/destroy_all.json',
1048 payload_type='list',
1049 allowed_param=['screen_name', 'user_id', 'slug', 'lit_id',
1050 'owner_id', 'owner_screen_name'],
1055 def list_members(self):
1056 """ :reference: https://dev.twitter.com/docs/api/1.1/get/lists/members
1057 :allowed_param:'owner_screen_name', 'slug', 'list_id',
1062 path='/lists/members.json',
1063 payload_type='user', payload_list=True,
1064 allowed_param=['owner_screen_name', 'slug', 'list_id',
1065 'owner_id', 'cursor']
1069 def show_list_member(self):
1070 """ :reference: https://dev.twitter.com/docs/api/1.1/get/lists/members/show
1071 :allowed_param:'list_id', 'slug', 'user_id', 'screen_name',
1072 'owner_screen_name', 'owner_id
1076 path='/lists/members/show.json',
1077 payload_type='user',
1078 allowed_param=['list_id', 'slug', 'user_id', 'screen_name',
1079 'owner_screen_name', 'owner_id']
1083 def subscribe_list(self):
1084 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/subscribers/create
1085 :allowed_param:'owner_screen_name', 'slug', 'owner_id',
1090 path='/lists/subscribers/create.json',
1092 payload_type='list',
1093 allowed_param=['owner_screen_name', 'slug', 'owner_id',
1099 def unsubscribe_list(self):
1100 """ :reference: https://dev.twitter.com/docs/api/1.1/post/lists/subscribers/destroy
1101 :allowed_param:'owner_screen_name', 'slug', 'owner_id',
1106 path='/lists/subscribers/destroy.json',
1108 payload_type='list',
1109 allowed_param=['owner_screen_name', 'slug', 'owner_id',
1115 def list_subscribers(self):
1116 """ :reference: https://dev.twitter.com/docs/api/1.1/get/lists/subscribers
1117 :allowed_param:'owner_screen_name', 'slug', 'owner_id',
1122 path='/lists/subscribers.json',
1123 payload_type='user', payload_list=True,
1124 allowed_param=['owner_screen_name', 'slug', 'owner_id',
1125 'list_id', 'cursor']
1129 def show_list_subscriber(self):
1130 """ :reference: https://dev.twitter.com/docs/api/1.1/get/lists/subscribers/show
1131 :allowed_param:'owner_screen_name', 'slug', 'screen_name',
1132 'owner_id', 'list_id', 'user_id
1136 path='/lists/subscribers/show.json',
1137 payload_type='user',
1138 allowed_param=['owner_screen_name', 'slug', 'screen_name',
1139 'owner_id', 'list_id', 'user_id']
1143 def trends_available(self):
1144 """ :reference: https://dev.twitter.com/rest/reference/get/trends/available """
1147 path='/trends/available.json',
1152 def trends_place(self):
1153 """ :reference: https://dev.twitter.com/rest/reference/get/trends/place
1154 :allowed_param:'id', 'exclude'
1158 path='/trends/place.json',
1159 payload_type='json',
1160 allowed_param=['id', 'exclude']
1164 def trends_closest(self):
1165 """ :reference: https://dev.twitter.com/rest/reference/get/trends/closest
1166 :allowed_param:'lat', 'long'
1170 path='/trends/closest.json',
1171 payload_type='json',
1172 allowed_param=['lat', 'long']
1177 """ :reference: https://dev.twitter.com/rest/reference/get/search/tweets
1178 :allowed_param:'q', 'lang', 'locale', 'since_id', 'geocode',
1179 'max_id', 'since', 'until', 'result_type', 'count',
1180 'include_entities', 'from', 'to', 'source']
1184 path='/search/tweets.json',
1185 payload_type='search_results',
1186 allowed_param=['q', 'lang', 'locale', 'since_id', 'geocode',
1187 'max_id', 'since', 'until', 'result_type',
1188 'count', 'include_entities', 'from',
1193 def reverse_geocode(self):
1194 """ :reference: https://dev.twitter.com/rest/reference/get/geo/reverse_geocode
1195 :allowed_param:'lat', 'long', 'accuracy', 'granularity', 'max_results'
1199 path='/geo/reverse_geocode.json',
1200 payload_type='place', payload_list=True,
1201 allowed_param=['lat', 'long', 'accuracy', 'granularity',
1207 """ :reference: https://dev.twitter.com/rest/reference/get/geo/id/%3Aplace_id
1212 path='/geo/id/{id}.json',
1213 payload_type='place',
1214 allowed_param=['id']
1218 def geo_search(self):
1219 """ :reference: https://dev.twitter.com/docs/api/1.1/get/geo/search
1220 :allowed_param:'lat', 'long', 'query', 'ip', 'granularity',
1221 'accuracy', 'max_results', 'contained_within
1226 path='/geo/search.json',
1227 payload_type='place', payload_list=True,
1228 allowed_param=['lat', 'long', 'query', 'ip', 'granularity',
1229 'accuracy', 'max_results', 'contained_within']
1233 def geo_similar_places(self):
1234 """ :reference: https://dev.twitter.com/rest/reference/get/geo/similar_places
1235 :allowed_param:'lat', 'long', 'name', 'contained_within'
1239 path='/geo/similar_places.json',
1240 payload_type='place', payload_list=True,
1241 allowed_param=['lat', 'long', 'name', 'contained_within']
1245 def supported_languages(self):
1246 """ :reference: https://dev.twitter.com/rest/reference/get/help/languages """
1249 path='/help/languages.json',
1250 payload_type='json',
1255 def configuration(self):
1256 """ :reference: https://dev.twitter.com/rest/reference/get/help/configuration """
1259 path='/help/configuration.json',
1260 payload_type='json',
1264 """ Internal use only """
1267 def _pack_image(filename, max_size, form_field="image", f=None):
1268 """Pack image from file into multipart-formdata post body"""
1269 # image must be less than 700kb in size
1272 if os.path.getsize(filename) > (max_size * 1024):
1273 raise TweepError('File is too big, must be less than %skb.' % max_size)
1274 except os.error as e:
1275 raise TweepError('Unable to access file: %s' % e.strerror)
1277 # build the mulitpart-formdata body
1278 fp = open(filename, 'rb')
1280 f.seek(0, 2) # Seek to end of file
1281 if f.tell() > (max_size * 1024):
1282 raise TweepError('File is too big, must be less than %skb.' % max_size)
1283 f.seek(0) # Reset to beginning of file
1286 # image must be gif, jpeg, or png
1287 file_type = mimetypes.guess_type(filename)
1288 if file_type is None:
1289 raise TweepError('Could not determine file type')
1290 file_type = file_type[0]
1291 if file_type not in ['image/gif', 'image/jpeg', 'image/png']:
1292 raise TweepError('Invalid file type for image: %s' % file_type)
1294 if isinstance(filename, six.text_type):
1295 filename = filename.encode("utf-8")
1297 BOUNDARY = b'Tw3ePy'
1299 body.append(b'--' + BOUNDARY)
1300 body.append('Content-Disposition: form-data; name="{0}";'
1301 ' filename="{1}"'.format(form_field, filename)
1303 body.append('Content-Type: {0}'.format(file_type).encode('utf-8'))
1305 body.append(fp.read())
1306 body.append(b'--' + BOUNDARY + b'--')
1309 body = b'\r\n'.join(body)
1313 'Content-Type': 'multipart/form-data; boundary=Tw3ePy',
1314 'Content-Length': str(len(body))
1317 return headers, body