public
Description: python client library for interacting with Sunlight Labs API
Homepage:
Clone URL: git://github.com/sunlightlabs/python-sunlightapi.git
python-sunlightapi / sunlightapi.py
100644 219 lines (178 sloc) 8.22 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
""" Python library for interacting with the Sunlight Labs API.
 
The Sunlight Labs API (http://services.sunlightlabs.com/api/) provides basic
legislator data, conversion between ids, and zipcode-district lookups.
"""
 
__author__ = "James Turk (jturk@sunlightfoundation.com)"
__version__ = "0.5.0"
__copyright__ = "Copyright (c) 2009 Sunlight Labs"
__license__ = "BSD"
 
import urllib, urllib2
import warnings
try:
    import json
except ImportError:
    import simplejson as json
 
class SunlightApiError(Exception):
    """ Exception for Sunlight API errors """
 
# results #
class SunlightApiObject(object):
    def __init__(self, d):
        self.__dict__ = d
 
class Legislator(SunlightApiObject):
    def __str__(self):
        if self.nickname:
            fname = self.nickname
        else:
            fname = self.firstname
        return '%s. %s %s (%s-%s)' % (self.title, fname, self.lastname,
                                      self.party, self.state)
 
class LegislatorSearchResult(SunlightApiObject):
    def __init__(self, d):
        self.legislator = Legislator(d['legislator'])
        self.score = d['score']
 
    def __str__(self):
        return '%s %s' % (self.score, self.legislator)
 
class Committee(SunlightApiObject):
    def __init__(self, d):
        self.__dict__ = d
        self.subcommittees = [Committee(sc['committee']) for sc in getattr(self, 'subcommittees', [])]
        self.members = [Legislator(m['legislator']) for m in getattr(self, 'members', [])]
 
    def __str__(self):
        return '%s' % (self.name)
 
class District(SunlightApiObject):
    def __str__(self):
        return '%s-%s' % (self.state, self.number)
 
class Lobbyist(SunlightApiObject):
    def __str__(self):
        return '%s %s' % (self.firstname, self.lastname)
 
class Issue(SunlightApiObject):
    def __str__(self):
        return '%s (%s)' % (self.code, self.specific_issue)
 
class Filing(SunlightApiObject):
    def __init__(self, d):
        self.__dict__ = d
        self.lobbyists = [Lobbyist(l['lobbyist']) for l in self.lobbyists]
        self.issues = [Issue(i['issue']) for i in self.issues]
 
    def __str__(self):
        return '%s - %s for %s' % (self.filing_id, self.registrant_name,
                                   self.client_name)
 
class FilingSearchResult(SunlightApiObject):
    def __init__(self, d):
        self.__dict__ = d['lobbyist']
        self.score = d['score']
 
    def __str__(self):
        return '%s %s %s (%s)' % (self.score, self.firstname, self.lastname,
                                  self.registrant_name)
 
# namespaces #
 
class sunlight(object):
 
    apikey = None
 
    @staticmethod
    def _apicall(func, params):
        if sunlight.apikey is None:
            raise SunlightApiError('Missing sunlight apikey')
 
        url = 'http://services.sunlightlabs.com/api/%s.json?apikey=%s&%s' % \
              (func, sunlight.apikey, urllib.urlencode(params))
        try:
            response = urllib2.urlopen(url).read()
            return json.loads(response)['response']
        except urllib2.HTTPError, e:
            raise SunlightApiError(e.read())
        except (ValueError, KeyError), e:
            raise SunlightApiError('Invalid Response')
 
    class legislators(object):
        @staticmethod
        def get(**kwargs):
            result = sunlight._apicall('legislators.get', kwargs)['legislator']
            return Legislator(result)
 
        @staticmethod
        def getList(**kwargs):
            results = sunlight._apicall('legislators.getList', kwargs)
            return [Legislator(l['legislator']) for l in results['legislators']]
 
        @staticmethod
        def search(name, threshold=0.9, all_legislators=False):
            params = {'name':name, 'threshold': threshold}
            if all_legislators:
                params['all_legislators'] = 1
            results = sunlight._apicall('legislators.search', params)['results']
            return [LegislatorSearchResult(r['result']) for r in results]
 
        @staticmethod
        def allForZip(zipcode):
            results = sunlight._apicall('legislators.allForZip', {'zip':zipcode})
            return [Legislator(l['legislator']) for l in results['legislators']]
 
    class committees(object):
        @staticmethod
        def get(committee_id):
            results = sunlight._apicall('committees.get', {'id':committee_id})
            return Committee(results['committee'])
 
        @staticmethod
        def getList(chamber):
            results = sunlight._apicall('committees.getList', {'chamber':chamber})
            return [Committee(c['committee']) for c in results['committees']]
 
        @staticmethod
        def allForLegislator(bioguide_id):
            results = sunlight._apicall('committees.allForLegislator',
                                        {'bioguide_id': bioguide_id})
            return [Committee(c['committee']) for c in results['committees']]
 
    class districts(object):
        @staticmethod
        def getDistrictsFromZip(zipcode):
            results = sunlight._apicall('districts.getDistrictsFromZip', {'zip':zipcode})
            return [District(r['district']) for r in results['districts']]
 
        @staticmethod
        def getZipsFromDistrict(state, district):
            params = {'state':state, 'district':district}
            results = sunlight._apicall('districts.getZipsFromDistrict', params)
            return results['zips']
 
        @staticmethod
        def getDistrictFromLatLong(latitude, longitude):
            params = {'latitude':latitude, 'longitude':longitude}
            result = sunlight._apicall('districts.getDistrictFromLatLong', params)
            return District(result['districts'][0]['district'])
 
    class lobbyists(object):
        @staticmethod
        def getFiling(id):
            warnings.warn('lobbyist methods deprecated as of September 2009', DeprecationWarning)
            result = sunlight._apicall('lobbyists.getFiling', {'id':id})
            return Filing(result['filing'])
 
        @staticmethod
        def getFilingList(**kwargs):
            warnings.warn('lobbyist methods deprecated as of September 2009', DeprecationWarning)
            results = sunlight._apicall('lobbyists.getFilingList', kwargs)
            return [Filing(f['filing']) for f in results['filings']]
 
        @staticmethod
        def search(name, year=None, threshold=0.9):
            warnings.warn('lobbyist methods deprecated as of September 2009', DeprecationWarning)
            if year == None:
                import time
                year = time.strftime('%Y')
            params = {'name':name, 'year':year, 'threshold': threshold}
            results = sunlight._apicall('lobbyists.search', params)['results']
            return [FilingSearchResult(f['result']) for f in results]
 
    class wordlist(object):
 
        @staticmethod
        def _apicall(call, body=None):
            warnings.warn('wordlist methods deprecated as of September 2009', DeprecationWarning)
            base_url = 'http://services.sunlightlabs.com/api/wordlist'
            url = '%s/%s/?apikey=%s' % (base_url, call, sunlight.apikey)
            try:
                if body:
                    data = urllib.urlencode(body)
                else:
                    data = None
                return urllib2.urlopen(url, data).read()
            except urllib2.HTTPError, e:
                raise SunlightApiError(e.read())
 
        @staticmethod
        def get(list_name):
            warnings.warn('wordlist methods deprecated as of September 2009', DeprecationWarning)
            words = sunlight.wordlist._apicall(list_name)
            return words.split('~')
 
        @staticmethod
        def update(list_name, words):
            warnings.warn('wordlist methods deprecated as of September 2009', DeprecationWarning)
            sunlight.wordlist._apicall(list_name, {'words': '\n'.join(words)})
 
        @staticmethod
        def filter_stopwords(list_name, text):
            warnings.warn('wordlist methods deprecated as of September 2009', DeprecationWarning)
            call = '%s/filter_stopwords' % list_name
            return sunlight.wordlist._apicall(call, {'text': text})