Skip to content

Commit

Permalink
Added api as argument of bind_api, changed to explicit arguments for …
Browse files Browse the repository at this point in the history
…bind_api.
  • Loading branch information
foutoucour committed May 31, 2014
1 parent 84ef039 commit ccfe2eb
Showing 1 changed file with 45 additions and 35 deletions.
80 changes: 45 additions & 35 deletions tweepy/binder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,60 @@
# Copyright 2009-2010 Joshua Roesslein
# See LICENSE for details.

import requests
import urllib
import time
import re
from StringIO import StringIO
import gzip

import requests

from tweepy.error import TweepError
from tweepy.utils import convert_to_utf8_str
from tweepy.models import Model


re_path_template = re.compile('{\w+}')


def bind_api(**config):
def bind_api(api,
path,
use_cache=True,
search_api=False,
require_auth=False,
method='GET',
allowed_param=None,
payload_list=False,
payload_type=None):
# common practice to avoid the bug when a list is in arguments.
allowed_param = allowed_param or []

class APIMethod(object):

path = config['path']
payload_type = config.get('payload_type', None)
payload_list = config.get('payload_list', False)
allowed_param = config.get('allowed_param', [])
method = config.get('method', 'GET')
require_auth = config.get('require_auth', False)
search_api = config.get('search_api', False)
use_cache = config.get('use_cache', True)
path = path
payload_type = payload_type
payload_list = payload_list
allowed_param = allowed_param
method = method
require_auth = require_auth
search_api = search_api
use_cache = use_cache
session = requests.Session()
api = api

def __init__(self, api, args, kargs):
def __init__(self, args, kwargs):
# If authentication is required and no credentials
# are provided, throw an error.
if self.require_auth and not api.auth:
raise TweepError('Authentication required!')

self.api = api
self.post_data = kargs.pop('post_data', None)
self.retry_count = kargs.pop('retry_count', api.retry_count)
self.retry_delay = kargs.pop('retry_delay', api.retry_delay)
self.retry_errors = kargs.pop('retry_errors', api.retry_errors)
self.wait_on_rate_limit = kargs.pop('wait_on_rate_limit', api.wait_on_rate_limit)
self.wait_on_rate_limit_notify = kargs.pop('wait_on_rate_limit_notify', api.wait_on_rate_limit_notify)
self.parser = kargs.pop('parser', api.parser)
self.session.headers = kargs.pop('headers', {})
self.build_parameters(args, kargs)
self.post_data = kwargs.pop('post_data', None)
self.retry_count = kwargs.pop('retry_count', api.retry_count)
self.retry_delay = kwargs.pop('retry_delay', api.retry_delay)
self.retry_errors = kwargs.pop('retry_errors', api.retry_errors)
self.wait_on_rate_limit = kwargs.pop('wait_on_rate_limit', api.wait_on_rate_limit)
self.wait_on_rate_limit_notify = kwargs.pop('wait_on_rate_limit_notify', api.wait_on_rate_limit_notify)
self.parser = kwargs.pop('parser', api.parser)
self.session.headers = kwargs.pop('headers', {})
self.build_parameters(args, kwargs)

# Pick correct URL root to use
if self.search_api:
Expand All @@ -71,7 +81,7 @@ def __init__(self, api, args, kargs):
self._remaining_calls = None
self._reset_time = None

def build_parameters(self, args, kargs):
def build_parameters(self, args, kwargs):
self.session.params = {}
for idx, arg in enumerate(args):
if arg is None:
Expand All @@ -81,7 +91,7 @@ def build_parameters(self, args, kargs):
except IndexError:
raise TweepError('Too many parameters supplied!')

for k, arg in kargs.items():
for k, arg in kwargs.items():
if arg is None:
continue
if k in self.session.params:
Expand Down Expand Up @@ -135,12 +145,12 @@ def execute(self):
while retries_performed < self.retry_count + 1:
# handle running out of api calls
if self.wait_on_rate_limit and self._reset_time is not None and \
self._remaining_calls is not None and self._remaining_calls < 1:
self._remaining_calls is not None and self._remaining_calls < 1:
sleep_time = self._reset_time - int(time.time())
if sleep_time > 0:
if self.wait_on_rate_limit_notify:
print "Max retries reached. Sleeping for: " + str(sleep_time)
time.sleep(sleep_time + 5) # sleep for few extra sec
time.sleep(sleep_time + 5) # sleep for few extra sec

# Apply authentication
if self.api.auth:
Expand All @@ -153,8 +163,8 @@ def execute(self):
# Execute request
try:
resp = self.session.request(self.method, full_url,
data=self.post_data, timeout=self.api.timeout,
auth=auth, proxies=self.api.proxy)
data=self.post_data, timeout=self.api.timeout,
auth=auth, proxies=self.api.proxy)
except Exception, e:
raise TweepError('Failed to send request: %s' % e)
rem_calls = resp.headers.get('x-rate-limit-remaining')
Expand All @@ -165,7 +175,8 @@ def execute(self):
reset_time = resp.headers.get('x-rate-limit-reset')
if reset_time is not None:
self._reset_time = int(reset_time)
if self.wait_on_rate_limit and self._remaining_calls == 0 and (resp.status == 429 or resp.status == 420): # if ran out of calls before waiting switching retry last call
if self.wait_on_rate_limit and self._remaining_calls == 0 and (
resp.status == 429 or resp.status == 420): # if ran out of calls before waiting switching retry last call
continue
retry_delay = self.retry_delay
# Exit request loop if non-retry error code
Expand Down Expand Up @@ -199,10 +210,9 @@ def execute(self):

return result

def _call(api, *args, **kargs):

method = APIMethod(api, args, kargs)
if kargs.get('create'):
def _call(*args, **kwargs):
method = APIMethod(args, kwargs)
if kwargs.get('create'):
return method
else:
return method.execute()
Expand All @@ -211,7 +221,7 @@ def _call(api, *args, **kargs):
if 'cursor' in APIMethod.allowed_param:
_call.pagination_mode = 'cursor'
elif 'max_id' in APIMethod.allowed_param and \
'since_id' in APIMethod.allowed_param:
'since_id' in APIMethod.allowed_param:
_call.pagination_mode = 'id'
elif 'page' in APIMethod.allowed_param:
_call.pagination_mode = 'page'
Expand Down

0 comments on commit ccfe2eb

Please sign in to comment.