Merge lp:~jderose/microfiber/generalize into lp:microfiber

Proposed by Jason Gerard DeRose
Status: Merged
Approved by: James Raymond
Approved revision: 153
Merged at revision: 147
Proposed branch: lp:~jderose/microfiber/generalize
Merge into: lp:microfiber
Diff against target: 183 lines (+34/-36)
2 files modified
microfiber.py (+26/-32)
test_microfiber.py (+8/-4)
To merge this branch: bzr merge lp:~jderose/microfiber/generalize
Reviewer Review Type Date Requested Status
James Raymond Approve
Review via email: mp+126205@code.launchpad.net

Description of the change

* Renamed CouchBase._request() to CouchBase.request()

* CouchBase.request() no longer reads the response data, now returns the http.client response only

* CouchBase.request() now only sets 'User-Agent' header, doesn't always set 'Accept'

* Added CouchBase.recv_json() method that captures the common JSON response pattern

To post a comment you must log in.
Revision history for this message
James Raymond (jamesmr) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'microfiber.py'
2--- microfiber.py 2012-09-25 02:35:10 +0000
3+++ microfiber.py 2012-09-25 09:28:29 +0000
4@@ -323,9 +323,9 @@
5 Base class for custom `microfiber` exceptions.
6 """
7
8- def __init__(self, response, data, method, url):
9+ def __init__(self, response, method, url):
10 self.response = response
11- self.data = data
12+ self.data = response.read()
13 self.method = method
14 self.url = url
15 super().__init__()
16@@ -335,9 +335,6 @@
17 self.response.status, self.response.reason, self.method, self.url
18 )
19
20- def loads(self):
21- return json.loads(self.data.decode('utf-8'))
22-
23
24 class ClientError(HTTPError):
25 """
26@@ -669,11 +666,8 @@
27 def _full_url(self, path):
28 return self.ctx.full_url(path)
29
30- def _request(self, method, parts, options, body=None, headers=None):
31- h = {
32- 'User-Agent': USER_AGENT,
33- 'Accept': 'application/json',
34- }
35+ def request(self, method, parts, options, body=None, headers=None):
36+ h = {'User-Agent': USER_AGENT}
37 if headers:
38 h.update(headers)
39 path = (self.basepath + '/'.join(parts) if parts else self.basepath)
40@@ -686,7 +680,6 @@
41 try:
42 conn.request(method, path, body, h)
43 response = conn.getresponse()
44- data = response.read()
45 break
46 except BadStatusLine as e:
47 conn.close()
48@@ -696,11 +689,19 @@
49 conn.close()
50 raise e
51 if response.status >= 500:
52- raise ServerError(response, data, method, path)
53+ raise ServerError(response, method, path)
54 if response.status >= 400:
55 E = errors.get(response.status, ClientError)
56- raise E(response, data, method, path)
57- return (response, data)
58+ raise E(response, method, path)
59+ return response
60+
61+ def recv_json(self, method, parts, options, body=None, headers=None):
62+ if headers is None:
63+ headers = {}
64+ headers['Accept'] = 'application/json'
65+ response = self.request(method, parts, options, body, headers)
66+ data = response.read()
67+ return json.loads(data.decode('utf-8'))
68
69 def post(self, obj, *parts, **options):
70 """
71@@ -718,11 +719,9 @@
72 {'ok': True}
73
74 """
75- (response, data) = self._request('POST', parts, options,
76- body=_json_body(obj),
77- headers={'Content-Type': 'application/json'},
78+ return self.recv_json('POST', parts, options, _json_body(obj),
79+ {'Content-Type': 'application/json'}
80 )
81- return json.loads(data.decode('utf-8'))
82
83 def put(self, obj, *parts, **options):
84 """
85@@ -740,11 +739,9 @@
86 {'rev': '1-fae0708c46b4a6c9c497c3a687170ad6', 'ok': True, 'id': 'bar'}
87
88 """
89- (response, data) = self._request('PUT', parts, options,
90- body=_json_body(obj),
91- headers={'Content-Type': 'application/json'},
92+ return self.recv_json('PUT', parts, options, _json_body(obj),
93+ {'Content-Type': 'application/json'}
94 )
95- return json.loads(data.decode('utf-8'))
96
97 def get(self, *parts, **options):
98 """
99@@ -762,8 +759,7 @@
100 >>> cb.get('foo', 'bar', attachments=True) #doctest: +SKIP
101 {'_rev': '1-967a00dff5e02add41819138abb3284d', '_id': 'bar'}
102 """
103- (response, data) = self._request('GET', parts, options)
104- return json.loads(data.decode('utf-8'))
105+ return self.recv_json('GET', parts, options)
106
107 def delete(self, *parts, **options):
108 """
109@@ -781,8 +777,7 @@
110 {'ok': True}
111
112 """
113- (response, data) = self._request('DELETE', parts, options)
114- return json.loads(data.decode('utf-8'))
115+ return self.recv_json('DELETE', parts, options)
116
117 def head(self, *parts, **options):
118 """
119@@ -791,7 +786,7 @@
120 Returns a ``dict`` containing the response headers from the HEAD
121 request.
122 """
123- (response, data) = self._request('HEAD', parts, options)
124+ response = self.request('HEAD', parts, options)
125 return dict(response.getheaders())
126
127 def put_att(self, mime, data, *parts, **options):
128@@ -814,11 +809,9 @@
129 :param parts: path components to construct URL relative to base path
130 :param options: optional keyword arguments to include in query
131 """
132- (response, data) = self._request('PUT', parts, options,
133- body=data,
134- headers={'Content-Type': mime},
135+ return self.recv_json('PUT', parts, options, data,
136+ {'Content-Type': mime}
137 )
138- return json.loads(data.decode('utf-8'))
139
140 def get_att(self, *parts, **options):
141 """
142@@ -838,7 +831,8 @@
143 :param parts: path components to construct URL relative to base path
144 :param options: optional keyword arguments to include in query
145 """
146- (response, data) = self._request('GET', parts, options)
147+ response = self.request('GET', parts, options)
148+ data = response.read()
149 return (response.getheader('Content-Type'), data)
150
151
152
153=== modified file 'test_microfiber.py'
154--- test_microfiber.py 2012-09-19 10:05:11 +0000
155+++ test_microfiber.py 2012-09-25 09:28:29 +0000
156@@ -136,10 +136,14 @@
157 )
158
159
160-class FakeResponse(object):
161- def __init__(self, status, reason):
162+class FakeResponse:
163+ def __init__(self, status, reason, data):
164 self.status = status
165 self.reason = reason
166+ self.__data = data
167+
168+ def read(self):
169+ return self.__data
170
171
172 class TestFunctions(TestCase):
173@@ -986,8 +990,8 @@
174 for (status, klass) in microfiber.errors.items():
175 reason = b32encode(os.urandom(10))
176 data = os.urandom(20)
177- r = FakeResponse(status, reason)
178- inst = klass(r, data, method, url)
179+ r = FakeResponse(status, reason, data)
180+ inst = klass(r, method, url)
181 self.assertIs(inst.response, r)
182 self.assertEqual(inst.method, method)
183 self.assertEqual(inst.url, url)

Subscribers

People subscribed via source and target branches