Skip to content

Commit bead606

Browse files
author
Chris Park
committed
Added connection pooling and test
- Added the responsive max pool setting - Unit test added and passed
1 parent 6ba4889 commit bead606

File tree

2 files changed

+44
-22
lines changed

2 files changed

+44
-22
lines changed

rosette/api.py

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,8 @@ def call(self, parameters):
482482
'application/json')}
483483
request = requests.Request(
484484
'POST', url, files=files, headers=headers)
485-
prepared_request = request.prepare()
486485
session = requests.Session()
486+
prepared_request = session.prepare_request(request)
487487
resp = session.send(prepared_request)
488488
rdata = resp.content
489489
response_headers = {"responseHeaders": dict(resp.headers)}
@@ -512,7 +512,6 @@ def __init__(
512512
user_key=None,
513513
service_url='https://api.rosette.com/rest/v1/',
514514
retries=5,
515-
reuse_connection=True,
516515
refresh_duration=0.5,
517516
debug=False):
518517
""" Create an L{API} object.
@@ -534,22 +533,20 @@ def __init__(
534533
refresh_duration = 0
535534

536535
self.num_retries = retries
537-
self.reuse_connection = reuse_connection
538536
self.connection_refresh_duration = refresh_duration
539-
self.http_connection = None
540537
self.options = {}
541538
self.customHeaders = {}
539+
self.maxPoolSize = 1
540+
self.session = requests.Session()
541+
542+
def _set_pool_size(self):
543+
adapter = requests.adapters.HTTPAdapter(pool_maxsize=self.maxPoolSize)
544+
if 'https:' in self.service_url:
545+
self.session.mount('https://', adapter)
546+
else:
547+
self.session.mount('http://', adapter)
548+
542549

543-
def _connect(self, parsedUrl):
544-
""" Simple connection method
545-
@param parsedUrl: The URL on which to process
546-
"""
547-
if not self.reuse_connection or self.http_connection is None:
548-
loc = parsedUrl.netloc
549-
if parsedUrl.scheme == "https":
550-
self.http_connection = httplib.HTTPSConnection(loc)
551-
else:
552-
self.http_connection = httplib.HTTPConnection(loc)
553550

554551
def _make_request(self, op, url, data, headers):
555552
"""
@@ -561,25 +558,28 @@ def _make_request(self, op, url, data, headers):
561558
@param headers: request headers
562559
"""
563560
headers['User-Agent'] = "RosetteAPIPython/" + _BINDING_VERSION
564-
parsedUrl = urlparse.urlparse(url)
565-
566-
self._connect(parsedUrl)
567561

568562
message = None
569563
code = "unknownError"
570564
rdata = None
571565
response_headers = {}
572566

573567
request = requests.Request(op, url, data=data, headers=headers)
574-
prepared_request = request.prepare()
575568
session = requests.Session()
569+
prepared_request = session.prepare_request(request)
576570

577571
for i in range(self.num_retries + 1):
578572
try:
579573
response = session.send(prepared_request)
580574
status = response.status_code
581575
rdata = response.content
582-
response_headers = {"responseHeaders": dict(response.headers)}
576+
dict_headers = dict(response.headers)
577+
response_headers = {"responseHeaders": dict_headers}
578+
if 'x-rosetteapi-concurrency' in dict_headers:
579+
if dict_headers['x-rosetteapi-concurrency'] != self.maxPoolSize:
580+
self.maxPoolSize = dict_headers['x-rosetteapi-concurrency']
581+
self._set_pool_size()
582+
583583

584584
if status == 200:
585585
return rdata, status, response_headers
@@ -598,6 +598,7 @@ def _make_request(self, op, url, data, headers):
598598
else:
599599
code = status
600600
raise RosetteException(code, message, url)
601+
601602
except:
602603
raise
603604
except requests.exceptions.RequestException as e:
@@ -606,9 +607,6 @@ def _make_request(self, op, url, data, headers):
606607
"Unable to establish connection to the Rosette API server",
607608
url)
608609

609-
if not self.reuse_connection:
610-
self.http_connection.close()
611-
612610
raise RosetteException(code, message, url)
613611

614612
def _get_http(self, url, headers):
@@ -644,6 +642,12 @@ def _post_http(self, url, data, headers):
644642

645643
return _ReturnObject(_my_loads(rdata, response_headers), status)
646644

645+
def getPoolSize(self):
646+
"""
647+
Returns the maximum pool size, which is the returned x-rosetteapi-concurrency value
648+
"""
649+
return int(self.maxPoolSize)
650+
647651
def setOption(self, name, value):
648652
"""
649653
Sets an option

tests/test_rosette_api.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,24 @@ def test_for_409(api, json_409):
170170
httpretty.disable()
171171
httpretty.reset()
172172

173+
# Test the maxPoolSize
174+
175+
176+
def test_the_max_pool_size(json_response, doc_params):
177+
httpretty.enable()
178+
httpretty.register_uri(httpretty.POST, "https://api.rosette.com/rest/v1/language",
179+
body=json_response, status=200, content_type="application/json",
180+
adding_headers={
181+
'x-rosetteapi-concurrency': 5
182+
})
183+
api = API('bogus_key')
184+
assert api.getPoolSize() == 1
185+
result = api.language(doc_params)
186+
assert result["name"] == "Rosette API"
187+
assert api.getPoolSize() == 5
188+
httpretty.disable()
189+
httpretty.reset()
190+
173191
# Test the language endpoint
174192

175193

0 commit comments

Comments
 (0)