7070)
7171
7272
73- warnings .simplefilter ('always' , DeprecationWarning )
74-
7573CHARACTER_LIMIT = 140
7674
7775# A singleton representing a lazily instantiated FileCache.
@@ -158,7 +156,8 @@ def __init__(self,
158156 debugHTTP = False ,
159157 timeout = None ,
160158 sleep_on_rate_limit = False ,
161- tweet_mode = 'compat' ):
159+ tweet_mode = 'compat' ,
160+ proxies = None ):
162161 """Instantiate a new twitter.Api object.
163162
164163 Args:
@@ -209,12 +208,15 @@ def __init__(self,
209208 tweet_mode (str, optional):
210209 Whether to use the new (as of Sept. 2016) extended tweet mode. See docs for
211210 details. Choices are ['compatibility', 'extended'].
211+ proxies (dict, optional):
212+ A dictionary of proxies for the request to pass through, if not specified
213+ allows requests lib to use environmental variables for proxy if any.
212214 """
213215
214216 # check to see if the library is running on a Google App Engine instance
215217 # see GAE.rst for more information
216218 if os .environ :
217- if 'Google App Engine ' in os .environ .get ( 'SERVER_SOFTWARE' , '' ):
219+ if 'APPENGINE_RUNTIME ' in os .environ .keys ( ):
218220 import requests_toolbelt .adapters .appengine # Adapter ensures requests use app engine's urlfetch
219221 requests_toolbelt .adapters .appengine .monkeypatch ()
220222 cache = None # App Engine does not like this caching strategy, disable caching
@@ -235,6 +237,7 @@ def __init__(self,
235237 self .rate_limit = RateLimit ()
236238 self .sleep_on_rate_limit = sleep_on_rate_limit
237239 self .tweet_mode = tweet_mode
240+ self .proxies = proxies
238241
239242 if base_url is None :
240243 self .base_url = 'https://api.twitter.com/1.1'
@@ -1055,6 +1058,7 @@ def PostUpdate(self,
10551058 parameters ['attachment_url' ] = attachment_url
10561059
10571060 if media :
1061+ chunked_types = ['video/mp4' , 'video/quicktime' , 'image/gif' ]
10581062 media_ids = []
10591063 if isinstance (media , int ):
10601064 media_ids .append (media )
@@ -1070,9 +1074,8 @@ def PostUpdate(self,
10701074 _ , _ , file_size , media_type = parse_media_file (media_file )
10711075 if media_type == 'image/gif' or media_type == 'video/mp4' :
10721076 raise TwitterError (
1073- 'You cannot post more than 1 GIF or 1 video in a '
1074- 'single status.' )
1075- if file_size > self .chunk_size :
1077+ 'You cannot post more than 1 GIF or 1 video in a single status.' )
1078+ if file_size > self .chunk_size or media_type in chunked_types :
10761079 media_id = self .UploadMediaChunked (
10771080 media = media_file ,
10781081 additional_owners = media_additional_owners ,
@@ -1084,13 +1087,11 @@ def PostUpdate(self,
10841087 media_category = media_category )
10851088 media_ids .append (media_id )
10861089 else :
1087- _ , _ , file_size , _ = parse_media_file (media )
1088- if file_size > self .chunk_size :
1089- media_ids .append (
1090- self .UploadMediaChunked (media , media_additional_owners ))
1090+ _ , _ , file_size , media_type = parse_media_file (media )
1091+ if file_size > self .chunk_size or media_type in chunked_types :
1092+ media_ids .append (self .UploadMediaChunked (media , media_additional_owners ))
10911093 else :
1092- media_ids .append (
1093- self .UploadMediaSimple (media , media_additional_owners ))
1094+ media_ids .append (self .UploadMediaSimple (media , media_additional_owners ))
10941095 parameters ['media_ids' ] = ',' .join ([str (mid ) for mid in media_ids ])
10951096
10961097 if latitude is not None and longitude is not None :
@@ -1292,7 +1293,7 @@ def _UploadMediaChunkedAppend(self,
12921293
12931294 try :
12941295 media_fp .close ()
1295- except :
1296+ except Exception as e :
12961297 pass
12971298
12981299 return True
@@ -1731,7 +1732,7 @@ def GetRetweeters(self,
17311732 """
17321733 url = '%s/statuses/retweeters/ids.json' % (self .base_url )
17331734 parameters = {
1734- 'status_id ' : enf_type ('status_id ' , int , status_id ),
1735+ 'id ' : enf_type ('id ' , int , status_id ),
17351736 'stringify_ids' : enf_type ('stringify_ids' , bool , stringify_ids )
17361737 }
17371738
@@ -1741,7 +1742,7 @@ def GetRetweeters(self,
17411742 while True :
17421743 if cursor :
17431744 try :
1744- parameters ['count ' ] = int (cursor )
1745+ parameters ['cursor ' ] = int (cursor )
17451746 except ValueError :
17461747 raise TwitterError ({'message' : "cursor must be an integer" })
17471748 resp = self ._RequestUrl (url , 'GET' , data = parameters )
@@ -2858,47 +2859,38 @@ def UsersLookup(self,
28582859 are queried is the union of all specified parameters.
28592860
28602861 Args:
2861- user_id:
2862- A list of user_ids to retrieve extended information. [Optional]
2863- screen_name:
2864- A list of screen_names to retrieve extended information. [Optional]
2865- users:
2862+ user_id (int, list, optional) :
2863+ A list of user_ids to retrieve extended information.
2864+ screen_name (str, optional) :
2865+ A list of screen_names to retrieve extended information.
2866+ users (list, optional) :
28662867 A list of twitter.User objects to retrieve extended information.
2867- [Optional]
2868- include_entities:
2868+ include_entities (bool, optional):
28692869 The entities node that may appear within embedded statuses will be
2870- disincluded when set to False. [Optional]
2870+ excluded when set to False.
28712871
28722872 Returns:
28732873 A list of twitter.User objects for the requested users
28742874 """
2875- if not user_id and not screen_name and not users :
2876- raise TwitterError ({ 'message' : "Specify at least one of user_id, screen_name, or users." } )
2875+ if not any ([ user_id , screen_name , users ]) :
2876+ raise TwitterError ("Specify at least one of user_id, screen_name, or users." )
28772877
28782878 url = '%s/users/lookup.json' % self .base_url
2879- parameters = {}
2879+ parameters = {
2880+ 'include_entities' : include_entities
2881+ }
28802882 uids = list ()
28812883 if user_id :
28822884 uids .extend (user_id )
28832885 if users :
28842886 uids .extend ([u .id for u in users ])
28852887 if len (uids ):
2886- parameters ['user_id' ] = ',' .join (["%s" % u for u in uids ])
2888+ parameters ['user_id' ] = ',' .join ([str ( u ) for u in uids ])
28872889 if screen_name :
28882890 parameters ['screen_name' ] = ',' .join (screen_name )
2889- if not include_entities :
2890- parameters ['include_entities' ] = 'false'
28912891
28922892 resp = self ._RequestUrl (url , 'GET' , data = parameters )
2893- try :
2894- data = self ._ParseAndCheckTwitter (resp .content .decode ('utf-8' ))
2895- except TwitterError as e :
2896- _ , e , _ = sys .exc_info ()
2897- t = e .args [0 ]
2898- if len (t ) == 1 and ('code' in t [0 ]) and (t [0 ]['code' ] == 34 ):
2899- data = []
2900- else :
2901- raise
2893+ data = self ._ParseAndCheckTwitter (resp .content .decode ('utf-8' ))
29022894 return [User .NewFromJsonDict (u ) for u in data ]
29032895
29042896 def GetUser (self ,
@@ -2908,29 +2900,27 @@ def GetUser(self,
29082900 """Returns a single user.
29092901
29102902 Args:
2911- user_id:
2912- The id of the user to retrieve. [Optional]
2913- screen_name:
2903+ user_id (int, optional) :
2904+ The id of the user to retrieve.
2905+ screen_name (str, optional) :
29142906 The screen name of the user for whom to return results for.
29152907 Either a user_id or screen_name is required for this method.
2916- [Optional]
2917- include_entities:
2908+ include_entities (bool, optional):
29182909 The entities node will be omitted when set to False.
2919- [Optional]
29202910
29212911 Returns:
29222912 A twitter.User instance representing that user
29232913 """
29242914 url = '%s/users/show.json' % (self .base_url )
2925- parameters = {}
2915+ parameters = {
2916+ 'include_entities' : include_entities
2917+ }
29262918 if user_id :
29272919 parameters ['user_id' ] = user_id
29282920 elif screen_name :
29292921 parameters ['screen_name' ] = screen_name
29302922 else :
2931- raise TwitterError ({'message' : "Specify at least one of user_id or screen_name." })
2932- if not include_entities :
2933- parameters ['include_entities' ] = 'false'
2923+ raise TwitterError ("Specify at least one of user_id or screen_name." )
29342924
29352925 resp = self ._RequestUrl (url , 'GET' , data = parameters )
29362926 data = self ._ParseAndCheckTwitter (resp .content .decode ('utf-8' ))
@@ -3621,8 +3611,8 @@ def CreateList(self, name, mode=None, description=None):
36213611 return List .NewFromJsonDict (data )
36223612
36233613 def DestroyList (self ,
3624- owner_screen_name = False ,
3625- owner_id = False ,
3614+ owner_screen_name = None ,
3615+ owner_id = None ,
36263616 list_id = None ,
36273617 slug = None ):
36283618 """Destroys the list identified by list_id or slug and one of
@@ -3660,8 +3650,8 @@ def DestroyList(self,
36603650 return List .NewFromJsonDict (data )
36613651
36623652 def CreateSubscription (self ,
3663- owner_screen_name = False ,
3664- owner_id = False ,
3653+ owner_screen_name = None ,
3654+ owner_id = None ,
36653655 list_id = None ,
36663656 slug = None ):
36673657 """Creates a subscription to a list by the authenticated user.
@@ -3697,8 +3687,8 @@ def CreateSubscription(self,
36973687 return User .NewFromJsonDict (data )
36983688
36993689 def DestroySubscription (self ,
3700- owner_screen_name = False ,
3701- owner_id = False ,
3690+ owner_screen_name = None ,
3691+ owner_id = None ,
37023692 list_id = None ,
37033693 slug = None ):
37043694 """Destroys the subscription to a list for the authenticated user.
@@ -3735,8 +3725,8 @@ def DestroySubscription(self,
37353725 return List .NewFromJsonDict (data )
37363726
37373727 def ShowSubscription (self ,
3738- owner_screen_name = False ,
3739- owner_id = False ,
3728+ owner_screen_name = None ,
3729+ owner_id = None ,
37403730 list_id = None ,
37413731 slug = None ,
37423732 user_id = None ,
@@ -4200,8 +4190,8 @@ def CreateListsMember(self,
42004190 def DestroyListsMember (self ,
42014191 list_id = None ,
42024192 slug = None ,
4203- owner_screen_name = False ,
4204- owner_id = False ,
4193+ owner_screen_name = None ,
4194+ owner_id = None ,
42054195 user_id = None ,
42064196 screen_name = None ):
42074197 """Destroys the subscription to a list for the authenticated user.
@@ -4219,10 +4209,10 @@ def DestroyListsMember(self,
42194209 owner_id (int, optional):
42204210 The user ID of the user who owns the list being requested by a slug.
42214211 user_id (int, optional):
4222- The user_id or a list of user_id's to add to the list.
4212+ The user_id or a list of user_id's to remove from the list.
42234213 If not given, then screen_name is required.
42244214 screen_name (str, optional):
4225- The screen_name or a list of Screen_name's to add to the list.
4215+ The screen_name or a list of Screen_name's to remove from the list.
42264216 If not given, then user_id is required.
42274217
42284218 Returns:
@@ -4916,7 +4906,8 @@ def _RequestChunkedUpload(self, url, headers, data):
49164906 headers = headers ,
49174907 data = data ,
49184908 auth = self .__auth ,
4919- timeout = self ._timeout
4909+ timeout = self ._timeout ,
4910+ proxies = self .proxies
49204911 )
49214912 except requests .RequestException as e :
49224913 raise TwitterError (str (e ))
@@ -4953,20 +4944,20 @@ def _RequestUrl(self, url, verb, data=None, json=None):
49534944 if data :
49544945 if 'media_ids' in data :
49554946 url = self ._BuildUrl (url , extra_params = {'media_ids' : data ['media_ids' ]})
4956- resp = requests .post (url , data = data , auth = self .__auth , timeout = self ._timeout )
4947+ resp = requests .post (url , data = data , auth = self .__auth , timeout = self ._timeout , proxies = self . proxies )
49574948 elif 'media' in data :
4958- resp = requests .post (url , files = data , auth = self .__auth , timeout = self ._timeout )
4949+ resp = requests .post (url , files = data , auth = self .__auth , timeout = self ._timeout , proxies = self . proxies )
49594950 else :
4960- resp = requests .post (url , data = data , auth = self .__auth , timeout = self ._timeout )
4951+ resp = requests .post (url , data = data , auth = self .__auth , timeout = self ._timeout , proxies = self . proxies )
49614952 elif json :
4962- resp = requests .post (url , json = json , auth = self .__auth , timeout = self ._timeout )
4953+ resp = requests .post (url , json = json , auth = self .__auth , timeout = self ._timeout , proxies = self . proxies )
49634954 else :
49644955 resp = 0 # POST request, but without data or json
49654956
49664957 elif verb == 'GET' :
49674958 data ['tweet_mode' ] = self .tweet_mode
49684959 url = self ._BuildUrl (url , extra_params = data )
4969- resp = requests .get (url , auth = self .__auth , timeout = self ._timeout )
4960+ resp = requests .get (url , auth = self .__auth , timeout = self ._timeout , proxies = self . proxies )
49704961
49714962 else :
49724963 resp = 0 # if not a POST or GET request
@@ -4998,14 +4989,15 @@ def _RequestStream(self, url, verb, data=None):
49984989 try :
49994990 return requests .post (url , data = data , stream = True ,
50004991 auth = self .__auth ,
5001- timeout = self ._timeout )
4992+ timeout = self ._timeout ,
4993+ proxies = self .proxies )
50024994 except requests .RequestException as e :
50034995 raise TwitterError (str (e ))
50044996 if verb == 'GET' :
50054997 url = self ._BuildUrl (url , extra_params = data )
50064998 try :
50074999 return requests .get (url , stream = True , auth = self .__auth ,
5008- timeout = self ._timeout )
5000+ timeout = self ._timeout , proxies = self . proxies )
50095001 except requests .RequestException as e :
50105002 raise TwitterError (str (e ))
50115003 return 0 # if not a POST or GET request
0 commit comments