Merge lp:~james-w/requestsplus/optional-elapsed into lp:requestsplus

Proposed by James Westby
Status: Merged
Approved by: James Westby
Approved revision: 12
Merged at revision: 11
Proposed branch: lp:~james-w/requestsplus/optional-elapsed
Merge into: lp:requestsplus
Diff against target: 90 lines (+32/-3)
2 files modified
requestsplus/__init__.py (+9/-2)
requestsplus/tests/__init__.py (+23/-1)
To merge this branch: bzr merge lp:~james-w/requestsplus/optional-elapsed
Reviewer Review Type Date Requested Status
Michael Nelson (community) Approve
Review via email: mp+239562@code.launchpad.net

Commit message

Don't rely on requests providing the elapsed attribute.

To post a comment you must log in.
12. By James Westby

Only set elapsed if requests doesn't.

Revision history for this message
Michael Nelson (michael.nelson) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'requestsplus/__init__.py'
--- requestsplus/__init__.py 2014-10-22 19:19:54 +0000
+++ requestsplus/__init__.py 2014-10-24 13:47:34 +0000
@@ -1,4 +1,5 @@
1from contextlib import contextmanager1from contextlib import contextmanager
2from datetime import datetime
23
3from requests import Session as _Session4from requests import Session as _Session
45
@@ -36,7 +37,13 @@
36 kwargs.setdefault('headers', {})37 kwargs.setdefault('headers', {})
37 kwargs['headers'][REQUEST_ID_HEADER] = request_id38 kwargs['headers'][REQUEST_ID_HEADER] = request_id
38 with maybe_timeline(self.timeline_factory, method, url) as action:39 with maybe_timeline(self.timeline_factory, method, url) as action:
40 start_time = datetime.utcnow()
39 resp = super(Session, self).request(method, url, **kwargs)41 resp = super(Session, self).request(method, url, **kwargs)
42 if getattr(resp, 'elapsed', None) is None:
43 # Older requests doesn't record elapsed, so we fake it.
44 # We can drop this when we make requests 1.2 the minimum
45 # version
46 resp.elapsed = datetime.utcnow() - start_time
40 if action is not None:47 if action is not None:
41 action.detail += " {}".format(resp.status_code)48 action.detail += " {}".format(resp.status_code)
42 if self.logger:49 if self.logger:
@@ -90,11 +97,11 @@
9097
91 logger.info(98 logger.info(
92 "%(method)s %(url)s returned %(status_code)s "99 "%(method)s %(url)s returned %(status_code)s "
93 "in %(duration)s %(extra)s",100 "in %(duration)sms %(extra)s",
94 dict(method=request.method,101 dict(method=request.method,
95 url=request.url,102 url=request.url,
96 status_code=response.status_code,103 status_code=response.status_code,
97 duration=str(response.elapsed),104 duration=int(response.elapsed.total_seconds()*1000),
98 extra=["{}={}".format(key, value)105 extra=["{}={}".format(key, value)
99 for key, value in sorted(extra.items())],106 for key, value in sorted(extra.items())],
100 )107 )
101108
=== modified file 'requestsplus/tests/__init__.py'
--- requestsplus/tests/__init__.py 2014-10-22 19:19:54 +0000
+++ requestsplus/tests/__init__.py 2014-10-24 13:47:34 +0000
@@ -8,6 +8,7 @@
8 Request,8 Request,
9 Response,9 Response,
10)10)
11from requests.adapters import HTTPAdapter
11from timeline import Timeline12from timeline import Timeline
1213
13from .. import (14from .. import (
@@ -192,6 +193,14 @@
192 self.assertEqual(request_id, get_request_id(request))193 self.assertEqual(request_id, get_request_id(request))
193194
194195
196class NoElapsedAdapter(HTTPAdapter):
197
198 def build_response(self, req, resp):
199 resp = super(NoElapsedAdapter, self).build_response(req, resp)
200 del resp.elapsed
201 return resp
202
203
195class SessionTests(TestCase):204class SessionTests(TestCase):
196205
197 def test_sends_request_id_header(self):206 def test_sends_request_id_header(self):
@@ -253,7 +262,7 @@
253 s.get('http://localhost')262 s.get('http://localhost')
254 self.assertEqual(263 self.assertEqual(
255 "GET http://localhost/ returned 200 "264 "GET http://localhost/ returned 200 "
256 "in 0:00:00 ['Content-Type=text/plain']\n",265 "in 0ms ['Content-Type=text/plain']\n",
257 log_capture.output)266 log_capture.output)
258267
259 def test_uses_timeline_factory(self):268 def test_uses_timeline_factory(self):
@@ -280,3 +289,16 @@
280 with responses:289 with responses:
281 s.get(url)290 s.get(url)
282 self.assertEqual(4, len(statsd.timings))291 self.assertEqual(4, len(statsd.timings))
292
293 def test_missing_elapsed_attr(self):
294 # Old versions of requests don't have response.elapsed
295 # so we have to work around it.
296 statsd = MockStatsd()
297 s = Session(statsd=statsd, statsd_prefix='a')
298 s.mount('http://', NoElapsedAdapter())
299 responses = RequestsMock()
300 url = 'http://localhost'
301 responses.add('GET', url)
302 with responses:
303 s.get(url)
304 self.assertEqual(4, len(statsd.timings))

Subscribers

People subscribed via source and target branches