Skip to content

Commit 9e13443

Browse files
committed
Merge pull request #30 from balanced/requests-1.1.0
Requests 1.1.0 is [metal](http://www.youtube.com/watch?v=A43JOxLa5MM)
2 parents abdc04d + ca445bb commit 9e13443

File tree

4 files changed

+70
-53
lines changed

4 files changed

+70
-53
lines changed

balanced/config.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ def __init__(self):
2323
'Content-Type': 'application/json',
2424
'User-agent': _make_user_agent(),
2525
},
26-
'danger_mode': True,
2726
}
2827

2928
@property

balanced/http_client.py

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -27,42 +27,48 @@
2727

2828
def wrap_raise_for_status(http_client):
2929

30-
def wrapper(response_instance):
31-
32-
raise_for_status = response_instance.raise_for_status
33-
34-
def wrapped():
35-
try:
36-
raise_for_status(allow_redirects=False)
37-
except requests.HTTPError, ex:
38-
if ex.response.status_code in REDIRECT_STATI:
39-
redirection = exc.MoreInformationRequiredError('%s' % ex)
40-
redirection.status_code = ex.response.status_code
41-
redirection.response = ex.response
42-
redirection.redirect_uri = ex.response.headers['Location']
43-
raise redirection
44-
deserialized = http_client.deserialize(
45-
response_instance
46-
)
47-
response_instance.deserialized = deserialized
48-
extra = deserialized.get('additional') or ''
49-
if extra:
50-
extra = ' -- {0}.'.format(extra)
51-
error_msg = '{name}: {code}: {msg} {extra}'.format(
52-
name=deserialized['status'],
53-
code=deserialized['status_code'],
54-
msg=deserialized['description'].encode('utf8'),
55-
extra=extra.encode('utf8'),
56-
)
57-
category_code = deserialized.get('category_code', None)
58-
error_cls = exc.category_code_map.get(
59-
category_code, exc.HTTPError)
60-
http_error = error_cls(error_msg)
61-
for error, value in deserialized.iteritems():
62-
setattr(http_error, error, value)
63-
raise http_error
64-
65-
response_instance.raise_for_status = wrapped
30+
def handle_exception(response):
31+
deserialized = http_client.deserialize(
32+
response
33+
)
34+
response.deserialized = deserialized
35+
extra = deserialized.get('additional') or ''
36+
if extra:
37+
extra = ' -- {0}.'.format(extra)
38+
error_msg = '{name}: {code}: {msg} {extra}'.format(
39+
name=deserialized['status'],
40+
code=deserialized['status_code'],
41+
msg=deserialized['description'].encode('utf8'),
42+
extra=extra.encode('utf8'),
43+
)
44+
category_code = deserialized.get('category_code', None)
45+
error_cls = exc.category_code_map.get(
46+
category_code, exc.HTTPError)
47+
http_error = error_cls(error_msg)
48+
for error, value in deserialized.iteritems():
49+
setattr(http_error, error, value)
50+
raise http_error
51+
52+
def handle_redirect(response):
53+
reason = '%s Client Error: %s' % (
54+
response.status_code,
55+
response.reason,
56+
)
57+
redirection = exc.MoreInformationRequiredError(reason)
58+
redirection.status_code = response.status_code
59+
redirection.response = response
60+
redirection.redirect_uri = response.headers['Location']
61+
raise redirection
62+
63+
def wrapper(response):
64+
65+
try:
66+
response.raise_for_status()
67+
except requests.HTTPError:
68+
handle_exception(response)
69+
else:
70+
if response.status_code in REDIRECT_STATI:
71+
handle_redirect(response)
6672

6773
return wrapper
6874

@@ -103,8 +109,11 @@ def make_absolute_url(client, url, **kwargs):
103109
request_body.update(fixed_up_body)
104110
kwargs['data'] = request_body
105111
# TODO: merge config dictionaries if it exists.
106-
kwargs['config'] = client.config.requests.copy()
112+
headers = kwargs.pop('headers', {})
113+
headers.update(client.config.requests['base_headers'])
114+
kwargs['headers'] = headers
107115
kwargs['allow_redirects'] = False
116+
108117
kwargs['hooks'] = {
109118
'response': wrap_raise_for_status(client)
110119
}
@@ -137,31 +146,28 @@ def __init__(self, keep_alive=True, *args, **kwargs):
137146
def get(self, uri, **kwargs):
138147
kwargs = self.serialize(kwargs.copy())
139148
resp = self.interface.get(uri, **kwargs)
140-
if kwargs.get('return_response', True):
141-
resp.deserialized = self.deserialize(resp)
149+
resp.deserialized = self.deserialize(resp)
142150
return resp
143151

144152
@munge_request
145153
def post(self, uri, data=None, **kwargs):
146154
data = self.serialize({'data': data}).pop('data')
147155
resp = self.interface.post(uri, data=data, **kwargs)
148-
if kwargs.get('return_response', True):
149-
resp.deserialized = self.deserialize(resp)
156+
resp.deserialized = self.deserialize(resp)
150157
return resp
151158

152159
@munge_request
153160
def put(self, uri, data=None, **kwargs):
154161
data = self.serialize({'data': data}).pop('data')
155162
resp = self.interface.put(uri, data=data, **kwargs)
156-
if kwargs.get('return_response', True):
157-
resp.deserialized = self.deserialize(resp)
163+
resp.deserialized = self.deserialize(resp)
158164
return resp
159165

160166
@munge_request
161167
def delete(self, uri, **kwargs):
162168
kwargs = self.serialize(kwargs.copy())
163169
resp = self.interface.delete(uri, **kwargs)
164-
if kwargs.get('return_response', True) and resp.status_code != 204:
170+
if resp.status_code != 204:
165171
resp.deserialized = self.deserialize(resp)
166172
return resp
167173

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ certifi==0.0.8
22
chardet==1.0.1
33
simplejson==2.3.2
44
iso8601==0.1.4
5-
requests>=0.11, <0.12
5+
requests==1.1.0
66
mock>=0.8,<0.9

tests/test_client.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,29 @@ def test_default_config(self):
2525
self.assertEqual(config.version, 'v1')
2626

2727

28+
def no_hook(client, http_op, url, kwargs):
29+
kwargs.pop('hooks', None)
30+
31+
2832
class TestClient(unittest.TestCase):
33+
34+
def setUp(self):
35+
before_request_hooks.append(no_hook)
36+
37+
def tearDown(self):
38+
while before_request_hooks:
39+
before_request_hooks.pop()
40+
2941
def test_http_operations(self):
42+
3043
ops = ['get', 'post', 'put', 'delete']
3144
for op in ops:
32-
request = getattr(balanced.http_client, op)(
45+
response = getattr(balanced.http_client, op)(
3346
'hithere',
34-
return_response=False
3547
)
36-
self.assertEqual(request.method, op.upper())
48+
self.assertEqual(response.request.method, op.upper())
3749
self.assertEqual(
38-
request.url, 'https://api.balancedpayments.com/v1/hithere'
50+
response.url, 'https://api.balancedpayments.com/v1/hithere'
3951
)
4052

4153
def test_client_reference_config(self):
@@ -55,11 +67,12 @@ def test_client_key_switch(self):
5567

5668
def test_before_request_hook(self):
5769
momo = mock.Mock()
70+
71+
before_request_hooks.append(no_hook)
5872
before_request_hooks.append(momo)
5973

6074
balanced.http_client.get(
6175
'hithere',
62-
return_response=False
6376
)
6477
self.assertEqual(momo.call_count, 1)
6578
args, _ = momo.call_args
@@ -119,10 +132,9 @@ def test_wrap_raise_for_status(self):
119132
response.raise_for_status.side_effect = ex
120133

121134
wrapped = wrap_raise_for_status(client)
122-
wrapped(response)
123135

124136
with self.assertRaises(balanced.exc.HTTPError) as ex:
125-
response.raise_for_status()
137+
wrapped(response)
126138
self.assertEqual(ex.exception.description, api_response['description'])
127139

128140

0 commit comments

Comments
 (0)