From 6e05325c08c62f7bcf43ca881c24b6cf8d2e5784 Mon Sep 17 00:00:00 2001 From: Bowen Song Date: Thu, 4 Jun 2015 17:08:39 +0100 Subject: [PATCH] Use requests.Session to pyrax.http module in order to avoid frequently TCP reconnecting Also updated pyrax.http unit test cases according to the changes --- pyrax/http.py | 20 ++++++--------- tests/unit/test_http.py | 57 +++++++++++++++++------------------------ 2 files changed, 31 insertions(+), 46 deletions(-) diff --git a/pyrax/http.py b/pyrax/http.py index 575bfe00..4748d68d 100644 --- a/pyrax/http.py +++ b/pyrax/http.py @@ -20,19 +20,12 @@ import logging import json import requests +import threading import pyrax import pyrax.exceptions as exc - -req_methods = { - "HEAD": requests.head, - "GET": requests.get, - "POST": requests.post, - "PUT": requests.put, - "DELETE": requests.delete, - "PATCH": requests.patch, - } +tls = threading.local() # NOTE: FIX THIS!!! verify_ssl = False @@ -46,7 +39,6 @@ def request(method, uri, *args, **kwargs): Formats the request into a dict representing the headers and body that will be used to make the API call. """ - req_method = req_methods[method.upper()] raise_exception = kwargs.pop("raise_exception", True) raw_content = kwargs.pop("raw_content", False) kwargs["headers"] = kwargs.get("headers", {}) @@ -59,10 +51,14 @@ def request(method, uri, *args, **kwargs): if "Content-Type" not in kwargs["headers"]: kwargs["headers"]["Content-Type"] = "application/json" data = json.dumps(kwargs.pop("body")) + session = getattr(tls, 'pyrax_http_session', None) + if session is None: + session = requests.Session() + tls.pyrax_http_session = session if data: - resp = req_method(uri, data=data, **kwargs) + resp = session.request(method, uri, data=data, **kwargs) else: - resp = req_method(uri, **kwargs) + resp = session.request(method, uri, **kwargs) if raw_content: body = resp.content else: diff --git a/tests/unit/test_http.py b/tests/unit/test_http.py index 32be8bfb..909c9b3c 100644 --- a/tests/unit/test_http.py +++ b/tests/unit/test_http.py @@ -14,13 +14,14 @@ from pyrax import client from pyrax import fakes - +from requests import Session as req_session class HttpTest(unittest.TestCase): def __init__(self, *args, **kwargs): super(HttpTest, self).__init__(*args, **kwargs) self.http = pyrax.http + self.http_method_choices = ("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH") def setUp(self): pass @@ -29,77 +30,65 @@ def tearDown(self): pass def test_request(self): - mthd = random.choice(self.http.req_methods.keys()) - sav_method = self.http.req_methods[mthd] + mthd = random.choice(self.http_method_choices) resp = fakes.FakeResponse() - self.http.req_methods[mthd] = Mock(return_value=resp) uri = utils.random_unicode() hk = utils.random_unicode() hv = utils.random_unicode() headers = {hk: hv} - self.http.request(mthd, uri, headers=headers) - self.http.req_methods[mthd].assert_called_once_with(uri, - headers=headers) - self.http.req_methods[mthd] = sav_method + with patch.object(req_session, 'request', return_value=resp) as mocked: + self.http.request(mthd, uri, headers=headers) + mocked.assert_called_once_with(mthd, uri, headers=headers) def test_request_no_json(self): - mthd = random.choice(self.http.req_methods.keys()) - sav_method = self.http.req_methods[mthd] + mthd = random.choice(self.http_method_choices) resp = fakes.FakeResponse() resp.json = Mock(side_effect=ValueError("")) - self.http.req_methods[mthd] = Mock(return_value=resp) uri = utils.random_unicode() hk = utils.random_unicode() hv = utils.random_unicode() headers = {hk: hv} - self.http.request(mthd, uri, headers=headers) - self.http.req_methods[mthd].assert_called_once_with(uri, - headers=headers) - self.http.req_methods[mthd] = sav_method + with patch.object(req_session, 'request', return_value=resp) as mocked: + self.http.request(mthd, uri, headers=headers) + mocked.assert_called_once_with(mthd, uri, headers=headers) def test_request_exception(self): - mthd = random.choice(self.http.req_methods.keys()) - sav_method = self.http.req_methods[mthd] + mthd = random.choice(self.http_method_choices) resp = fakes.FakeResponse() resp.status_code = 404 - self.http.req_methods[mthd] = Mock(return_value=resp) uri = utils.random_unicode() hk = utils.random_unicode() hv = utils.random_unicode() headers = {hk: hv} - self.assertRaises(exc.NotFound, self.http.request, mthd, uri, - headers=headers) + with patch.object(req_session, 'request', return_value=resp) as mocked: + self.assertRaises(exc.NotFound, self.http.request, mthd, uri, + headers=headers) + mocked.assert_called_once_with(mthd, uri, headers=headers) def test_request_data(self): - mthd = random.choice(self.http.req_methods.keys()) - sav_method = self.http.req_methods[mthd] + mthd = random.choice(self.http_method_choices) resp = fakes.FakeResponse() - self.http.req_methods[mthd] = Mock(return_value=resp) uri = utils.random_unicode() hk = utils.random_unicode() hv = utils.random_unicode() headers = {hk: hv} data = utils.random_unicode() - self.http.request(mthd, uri, headers=headers, data=data) - self.http.req_methods[mthd].assert_called_once_with(uri, - headers=headers, data=data) - self.http.req_methods[mthd] = sav_method + with patch.object(req_session, 'request', return_value=resp) as mocked: + self.http.request(mthd, uri, headers=headers, data=data) + mocked.assert_called_once_with(mthd, uri, headers=headers, data=data) def test_request_body(self): - mthd = random.choice(self.http.req_methods.keys()) - sav_method = self.http.req_methods[mthd] + mthd = random.choice(self.http_method_choices) resp = fakes.FakeResponse() - self.http.req_methods[mthd] = Mock(return_value=resp) uri = utils.random_unicode() hk = utils.random_unicode() hv = utils.random_unicode() headers = {hk: hv} body = utils.random_unicode() jbody = json.dumps(body) - self.http.request(mthd, uri, headers=headers, body=body) - self.http.req_methods[mthd].assert_called_once_with(uri, - headers=headers, data=jbody) - self.http.req_methods[mthd] = sav_method + with patch.object(req_session, 'request', return_value=resp) as mocked: + self.http.request(mthd, uri, headers=headers, body=body) + mocked.assert_called_once_with(mthd, uri, headers=headers, data=jbody) def test_http_log_req(self): args = ("a", "b")