RequestsHttpConnection class handling the actual http communication

This commit is contained in:
Honza Kral
2013-05-01 21:55:44 +02:00
parent af1891c7ce
commit 71daa6ef14
3 changed files with 114 additions and 0 deletions
+46
View File
@@ -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
+15
View File
@@ -0,0 +1,15 @@
class ElastiSearchException(Exception):
pass
class TransportError(ElastiSearchException):
pass
class NotFoundError(TransportError):
" 404 "
HTTP_EXCEPTIONS = {
404: NotFoundError,
}
+53
View File
@@ -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)