Commit ccfe2eb1 authored by Jordi Riera's avatar Jordi Riera
Browse files

Added api as argument of bind_api, changed to explicit arguments for bind_api.

parent 84ef0393
......@@ -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:
......@@ -71,7 +81,7 @@ def bind_api(**config):
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:
......@@ -81,7 +91,7 @@ def bind_api(**config):
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:
......@@ -135,12 +145,12 @@ def bind_api(**config):
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:
......@@ -153,8 +163,8 @@ def bind_api(**config):
# 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')
......@@ -165,7 +175,8 @@ def bind_api(**config):
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
......@@ -199,10 +210,9 @@ def bind_api(**config):
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()
......@@ -211,7 +221,7 @@ def bind_api(**config):
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'
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment