26
26
'fec' ,
27
27
)
28
28
29
+
29
30
# Stolen from http://codereview.stackexchange.com/a/21035/28391
30
31
def flatten_dict (d ):
31
32
def flat_items ():
32
33
for k , v in d .items ():
33
34
if isinstance (v , dict ):
34
35
for kk , vv in flatten_dict (v ).items ():
35
- yield '{0}.{1}' .format (k ,kk ), vv
36
+ yield '{0}.{1}' .format (k , kk ), vv
36
37
else :
37
38
yield k , v
38
39
39
40
return dict (flat_items ())
40
41
42
+
41
43
def preencode_values (d ):
42
44
for k , v in d .items ():
43
45
if isinstance (v , bool ):
44
46
d [k ] = str (v ).lower ()
45
47
return d
46
48
49
+
47
50
class Congress (sunlight .service .Service ):
48
51
"""
49
52
Bindings to the `Congress API <http://sunlightlabs.github.io/congress/>`_.
@@ -61,7 +64,7 @@ def legislators(self, **kwargs):
61
64
For details see `Legislators API docs
62
65
<http://sunlightlabs.github.io/congress/legislators.html>`
63
66
"""
64
- return self .get ('legislators' , ** kwargs )
67
+ return self .get ([ 'legislators' ] , ** kwargs )
65
68
66
69
@pageable
67
70
def legislator (self , identifier , id_type = LEGISLATOR_ID_TYPES [0 ], ** kwargs ):
@@ -90,7 +93,7 @@ def legislator(self, identifier, id_type=LEGISLATOR_ID_TYPES[0], **kwargs):
90
93
id_arg [id_key ] = identifier
91
94
92
95
kwargs .update (id_arg )
93
- results = self .get ('legislators' , ** kwargs )
96
+ results = self .get ([ 'legislators' ] , ** kwargs )
94
97
if len (results ):
95
98
return EntityDict (results [0 ], results ._meta )
96
99
return None
@@ -105,7 +108,7 @@ def all_legislators_in_office(self, **kwargs):
105
108
kwargs .update ({
106
109
"per_page" : "all"
107
110
})
108
- return self .get ('legislators' , ** kwargs )
111
+ return self .get ([ 'legislators' ] , ** kwargs )
109
112
110
113
@pageable
111
114
def locate_legislators_by_lat_lon (self , lat , lon , ** kwargs ):
@@ -119,7 +122,7 @@ def locate_legislators_by_lat_lon(self, lat, lon, **kwargs):
119
122
"latitude" : lat ,
120
123
"longitude" : lon
121
124
})
122
- return self .get ('legislators/locate' , ** kwargs )
125
+ return self .get ([ 'legislators/locate' ] , ** kwargs )
123
126
124
127
@pageable
125
128
def locate_legislators_by_zip (self , zipcode , ** kwargs ):
@@ -132,7 +135,7 @@ def locate_legislators_by_zip(self, zipcode, **kwargs):
132
135
kwargs .update ({
133
136
"zip" : zipcode
134
137
})
135
- return self .get ('legislators/locate' , ** kwargs )
138
+ return self .get ([ 'legislators/locate' ] , ** kwargs )
136
139
137
140
@pageable
138
141
def bills (self , ** kwargs ):
@@ -142,7 +145,7 @@ def bills(self, **kwargs):
142
145
For details see `Bills API docs
143
146
<http://sunlightlabs.github.io/congress/bills.html>`_
144
147
"""
145
- return self .get ('bills' , ** kwargs )
148
+ return self .get ([ 'bills' ] , ** kwargs )
146
149
147
150
@pageable
148
151
def bill (self , bill_id , ** kwargs ):
@@ -155,7 +158,7 @@ def bill(self, bill_id, **kwargs):
155
158
kwargs .update ({
156
159
"bill_id" : bill_id
157
160
})
158
- results = self .get ('bills' , ** kwargs )
161
+ results = self .get ([ 'bills' ] , ** kwargs )
159
162
if len (results ):
160
163
return EntityDict (results [0 ], results ._meta )
161
164
return None
@@ -171,7 +174,7 @@ def search_bills(self, query, **kwargs):
171
174
kwargs .update ({
172
175
"query" : query
173
176
})
174
- return self .get ('bills/search' , ** kwargs )
177
+ return self .get ([ 'bills/search' ] , ** kwargs )
175
178
176
179
@pageable
177
180
def upcoming_bills (self , ** kwargs ):
@@ -184,7 +187,7 @@ def upcoming_bills(self, **kwargs):
184
187
For details see `Upcoming Bills API docs
185
188
<http://sunlightlabs.github.io/congress/upcoming_bills.html>`_
186
189
"""
187
- return self .get ('upcoming_bills' , ** kwargs )
190
+ return self .get ([ 'upcoming_bills' ] , ** kwargs )
188
191
189
192
@pageable
190
193
def locate_districts_by_lat_lon (self , lat , lon , ** kwargs ):
@@ -198,7 +201,7 @@ def locate_districts_by_lat_lon(self, lat, lon, **kwargs):
198
201
"latitude" : lat ,
199
202
"longitude" : lon
200
203
})
201
- return self .get ('/districts/locate' , ** kwargs )
204
+ return self .get ([ '/districts/locate' ] , ** kwargs )
202
205
203
206
@pageable
204
207
def locate_districts_by_zip (self , zipcode , ** kwargs ):
@@ -211,7 +214,7 @@ def locate_districts_by_zip(self, zipcode, **kwargs):
211
214
kwargs .update ({
212
215
"zip" : zipcode ,
213
216
})
214
- return self .get ('/districts/locate' , ** kwargs )
217
+ return self .get ([ '/districts/locate' ] , ** kwargs )
215
218
216
219
@pageable
217
220
def committees (self , ** kwargs ):
@@ -221,7 +224,7 @@ def committees(self, **kwargs):
221
224
For details see `Committees API docs
222
225
<http://sunlightlabs.github.io/congress/committees.html>`_
223
226
"""
224
- return self .get ('committees' , ** kwargs )
227
+ return self .get ([ 'committees' ] , ** kwargs )
225
228
226
229
@pageable
227
230
def amendments (self , ** kwargs ):
@@ -231,7 +234,7 @@ def amendments(self, **kwargs):
231
234
For details see `Amendments API docs
232
235
<http://sunlightlabs.github.io/congress/amendments.html>`_
233
236
"""
234
- return self .get ('amendments' , ** kwargs )
237
+ return self .get ([ 'amendments' ] , ** kwargs )
235
238
236
239
@pageable
237
240
def votes (self , ** kwargs ):
@@ -241,7 +244,7 @@ def votes(self, **kwargs):
241
244
For details see `Votes API docs
242
245
<http://sunlightlabs.github.io/congress/votes.html>`_
243
246
"""
244
- return self .get ('votes' , ** kwargs )
247
+ return self .get ([ 'votes' ] , ** kwargs )
245
248
246
249
@pageable
247
250
def floor_updates (self , ** kwargs ):
@@ -251,7 +254,7 @@ def floor_updates(self, **kwargs):
251
254
For details see `Floor Updates API docs
252
255
<http://sunlightlabs.github.io/congress/floor_updates.html>`_
253
256
"""
254
- return self .get ('floor_updates' , ** kwargs )
257
+ return self .get ([ 'floor_updates' ] , ** kwargs )
255
258
256
259
@pageable
257
260
def hearings (self , ** kwargs ):
@@ -261,7 +264,7 @@ def hearings(self, **kwargs):
261
264
For details see `Hearings API docs
262
265
<http://sunlightlabs.github.io/congress/hearings.html>`_
263
266
"""
264
- return self .get ('hearings' , ** kwargs )
267
+ return self .get ([ 'hearings' ] , ** kwargs )
265
268
266
269
@pageable
267
270
def nominations (self , ** kwargs ):
@@ -271,18 +274,27 @@ def nominations(self, **kwargs):
271
274
For details see `Nominations API docs
272
275
<http://sunlightlabs.github.io/congress/nominations.html>`_
273
276
"""
274
- return self .get ('nominations' , ** kwargs )
277
+ return self .get ([ 'nominations' ] , ** kwargs )
275
278
276
279
# implementation methods
277
- def _get_url (self , endpoint , apikey , ** kwargs ):
278
- url_args = preencode_values ( flatten_dict (kwargs ) )
279
- url = "%s/%s?apikey=%s&%s" % (
280
- API_ROOT , endpoint , apikey ,
281
- sunlight .service .safe_encode (url_args )
282
- )
280
+ def _get_url (self , pathparts , apikey , ** kwargs ):
281
+ url_args = preencode_values (flatten_dict (kwargs ))
282
+
283
+ # join pieces by slashes and add a trailing slash
284
+ endpoint_path = "/" .join (pathparts )
285
+
286
+ url = "{api_root}/{path}?apikey={apikey}&{url_args}" .format (
287
+ api_root = API_ROOT ,
288
+ path = endpoint_path ,
289
+ apikey = apikey ,
290
+ url_args = sunlight .service .safe_encode (url_args )
291
+ ).strip ('&' )
283
292
return url
284
293
285
294
def _decode_response (self , response ):
286
295
data = json .loads (response )
287
- results = data .pop ('results' )
288
- return EntityList (results , data )
296
+ results = data .pop ('results' , None )
297
+ if results :
298
+ return EntityList (results , data )
299
+ else :
300
+ return data
0 commit comments