binder.py 2.88 KB
Newer Older
1
2
3
4
# Tweepy
# Copyright 2009 Joshua Roesslein
# See LICENSE

5
import httplib
Josh Roesslein's avatar
Josh Roesslein committed
6
import urllib
7

8
from parsers import parse_error
9
from error import TweepError
10

11
12
def bind_api(path, parser, allowed_param=None, method='GET', require_auth=False,
              timeout=None, host=None):
13

14
15
  def _call(api, *args, **kargs):
    # If require auth, throw exception if credentials not provided
16
    if require_auth and not api.auth_handler:
17
18
      raise TweepError('Authentication required!')

19
    # build parameter dict
20
    if allowed_param:
21
22
23
24
25
26
27
28
29
      parameters = {}
      for idx, arg in enumerate(args):
        try:
          parameters[allowed_param[idx]] = arg
        except IndexError:
          raise TweepError('Too many parameters supplied!')
      for k, arg in kargs.items():
        if k in parameters:
          raise TweepError('Multiple values for parameter %s supplied!' % k)
Josh Roesslein's avatar
Josh Roesslein committed
30
31
        if k not in allowed_param:
          raise TweepError('Invalid parameter %s supplied!' % k)
32
        parameters[k] = arg
33
    else:
Josh Roesslein's avatar
Josh Roesslein committed
34
35
      if len(args) > 0 or len(kargs) > 0:
        raise TweepError('This method takes no parameters!')
36
37
      parameters = None

38
39
40
41
42
    # Assemble headers
    headers = {
      'User-Agent': 'tweepy'
    }

43
44
    # Build url with parameters
    if parameters:
45
      url = '%s?%s' % (api.api_root + path, urllib.urlencode(parameters))
46
    else:
47
      url = api.api_root + path
48

49
50
51
52
53
54
55
56
57
58
59
    # get scheme and host
    if api.secure:
      scheme = 'https://'
    else:
      scheme = 'http://'
    _host = host or api.host

    # Apply authentication
    if api.auth_handler:
      api.auth_handler.apply_auth(scheme + _host + url, method, headers, parameters)

60
61
    # Check cache if caching enabled and method is GET
    if api.cache and method == 'GET':
62
      cache_result = api.cache.get(url, timeout)
63
64
      if cache_result:
        # if cache result found and not expired, return it
65
        cache_result._api = api  # restore api reference to this api instance
66
67
        return cache_result

68
69
    # Open connection
    if api.secure:
Josh Roesslein's avatar
Josh Roesslein committed
70
      conn = httplib.HTTPSConnection(_host, timeout=10.0)
71
    else:
Josh Roesslein's avatar
Josh Roesslein committed
72
      conn = httplib.HTTPConnection(_host, timeout=10.0)
73
74
75
76
77
78
79
80
81
82
83
84

    # Build request
    conn.request(method, url, headers=headers)

    # Get response
    resp = conn.getresponse()

    # If an error was returned, throw an exception
    if resp.status != 200:
      raise TweepError(parse_error(resp.read()))

    # Pass returned body into parser and return parser output
85
    out =  parser(resp.read(), api)
86
87
88
89
90
91
92
93
94
95
96
97
98
    conn.close()

    # validate result
    if api.validate:
      # list of results
      if isinstance(out, list) and len(out) > 0:
        if hasattr(out[0], 'validate'):
          for result in out:
            result.validate()
      # single result
      else:
        if hasattr(out, 'validate'):
          out.validate()
99

100
101
102
103
    # store result in cache
    if api.cache and method == 'GET':
      api.cache.store(url, out)

104
    return out
105

106
  return _call