RequestsHttpConnection class handling the actual http communication
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import logging
|
||||
import time
|
||||
import requests
|
||||
import json
|
||||
|
||||
from .exceptions import TransportError, HTTP_EXCEPTIONS
|
||||
|
||||
logger = logging.getLogger('elasticsearch')
|
||||
tracer = logging.getLogger('elasticsearch.trace')
|
||||
tracer.propagate = False
|
||||
|
||||
class Connection(object):
|
||||
transport_schema = 'http'
|
||||
|
||||
def __init__(self, host='localhost', port=9200, **kwargs):
|
||||
self.host = '%s://%s:%s' % (self.transport_schema, host, port)
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s: %s>' % (self.__class__.__name__, self.host)
|
||||
|
||||
|
||||
class RequestsHttpConnection(Connection):
|
||||
def __init__(self, **kwargs):
|
||||
super(RequestsHttpConnection, self).__init__(**kwargs)
|
||||
self.session = requests.session()
|
||||
|
||||
def perform_request(self, method, url, params=None, body=None):
|
||||
url = self.host + url
|
||||
|
||||
request = requests.Request(method, url, params=params or {}, data=body).prepare()
|
||||
try:
|
||||
response = self.session.send(request)
|
||||
raw_data = response.text
|
||||
except requests.ConnectionError as e:
|
||||
raise TransportError(e)
|
||||
|
||||
# raise errors based on http status codes, let the client handle those if needed
|
||||
if response.status_code >= 300:
|
||||
|
||||
if response.status_code in HTTP_EXCEPTIONS:
|
||||
raise HTTP_EXCEPTIONS[response.status_code]()
|
||||
|
||||
raise TransportError()
|
||||
|
||||
return response.status_code, raw_data
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
class ElastiSearchException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class TransportError(ElastiSearchException):
|
||||
pass
|
||||
|
||||
|
||||
class NotFoundError(TransportError):
|
||||
" 404 "
|
||||
|
||||
|
||||
HTTP_EXCEPTIONS = {
|
||||
404: NotFoundError,
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
from unittest import TestCase
|
||||
|
||||
from mock import Mock
|
||||
|
||||
from elasticsearch.connection import RequestsHttpConnection
|
||||
|
||||
class TestRequestsConnection(TestCase):
|
||||
def _get_mock_connection(self, connection_params={}, status_code=200, response_body=u'{}'):
|
||||
con = RequestsHttpConnection(**connection_params)
|
||||
|
||||
con.session.send = Mock()
|
||||
|
||||
dummy_response = Mock()
|
||||
con.session.send.return_value = dummy_response
|
||||
dummy_response.status_code = status_code
|
||||
dummy_response.text = response_body
|
||||
return con
|
||||
|
||||
def _get_request(self, connection, *args, **kwargs):
|
||||
status, data = connection.perform_request(*args, **kwargs)
|
||||
self.assertEquals(200, status)
|
||||
self.assertEquals(u'{}', data)
|
||||
|
||||
self.assertEquals(1, connection.session.send.call_count)
|
||||
|
||||
args, kwargs = connection.session.send.call_args
|
||||
self.assertEquals({}, kwargs)
|
||||
self.assertEquals(1, len(args))
|
||||
return args[0]
|
||||
|
||||
def test_defaults(self):
|
||||
con = self._get_mock_connection()
|
||||
request = self._get_request(con, 'GET', '/')
|
||||
|
||||
self.assertEquals('http://localhost:9200/', request.url)
|
||||
self.assertEquals('GET', request.method)
|
||||
self.assertEquals(None, request.body)
|
||||
|
||||
def test_params_properly_encoded(self):
|
||||
con = self._get_mock_connection()
|
||||
request = self._get_request(con, 'GET', '/', params={'param': 'value with spaces'})
|
||||
|
||||
self.assertEquals('http://localhost:9200/?param=value+with+spaces', request.url)
|
||||
self.assertEquals('GET', request.method)
|
||||
self.assertEquals(None, request.body)
|
||||
|
||||
def test_body_attached(self):
|
||||
con = self._get_mock_connection()
|
||||
request = self._get_request(con, 'GET', '/', body='{"answer": 42}')
|
||||
|
||||
self.assertEquals('http://localhost:9200/', request.url)
|
||||
self.assertEquals('GET', request.method)
|
||||
self.assertEquals('{"answer": 42}', request.body)
|
||||
Reference in New Issue
Block a user