Skip to content

Commit e1f5c4a

Browse files
feat(request_options): add test
1 parent f3bf111 commit e1f5c4a

File tree

5 files changed

+61
-30
lines changed

5 files changed

+61
-30
lines changed

algoliasearch/client.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,22 @@
4545
MAX_API_KEY_LENGTH = 500
4646

4747

48+
class RequestOptions:
49+
HEADERS = {
50+
'forwardedFor': 'X-Forwarded-For'
51+
}
52+
53+
def __init__(self, options):
54+
self.headers = {}
55+
self.parameters = {}
56+
57+
for k, v in options.items():
58+
if k in self.HEADERS:
59+
self.headers[self.HEADERS[k]] = v
60+
else:
61+
self.parameters[k] = v
62+
63+
4864
class Client(object):
4965
"""
5066
Entry point in the Python Client API.

algoliasearch/index.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,17 @@
3535
from .helpers import safe
3636

3737

38-
class RequestOptions:
39-
def __init__(self, options):
40-
self.headers = {}
41-
self.parameters = {}
42-
43-
if 'forwaredFor' in options:
44-
self.headers['X-Forwarded-For'] = options['forwaredFor']
45-
46-
4738
class IndexIterator:
4839
"""Iterator on index."""
4940

50-
def __init__(self, index, params=None, cursor=None):
41+
def __init__(self, index, params=None, cursor=None, request_options=None):
5142
if params is None:
5243
params = {}
5344

5445
self.index = index
5546
self.params = params
5647
self.cursor = cursor
48+
self.request_options = request_options
5749

5850
def __iter__(self):
5951
self._load_next_page()
@@ -74,7 +66,7 @@ def next(self):
7466
raise StopIteration
7567

7668
def _load_next_page(self):
77-
self.answer = self.index.browse_from(self.params, self.cursor)
69+
self.answer = self.index.browse_from(self.params, self.cursor, self.request_options)
7870
self.pos = 0
7971
self.cursor = self.answer.get('cursor', None)
8072

@@ -271,7 +263,7 @@ def partial_update_objects(self, objects, no_create=False, request_options=None)
271263
'objectID': obj['objectID'],
272264
'body': obj
273265
})
274-
return self.batch(requests, request_options, no_create=no_create)
266+
return self.batch(requests, no_create=no_create, request_options=request_options)
275267

276268
@deprecated
277269
def saveObject(self, obj):
@@ -591,7 +583,7 @@ def browse(self, page=0, hits_per_page=1000):
591583
of hits per page. Defaults to 1000.
592584
"""
593585
params = {'page': page, 'hitsPerPage': hits_per_page}
594-
return self._req(True, '/browse', 'GET', params)
586+
return self._req(True, '/browse', 'GET', None, params)
595587

596588
def browse_from(self, params=None, cursor=None, request_options=None):
597589
"""
@@ -683,7 +675,7 @@ def delete_synonym(self, object_id, forward_to_slaves=False,
683675

684676
path = '/synonyms/%s' % safe(object_id)
685677
params = {'forwardToReplicas': forward_to_replicas}
686-
return self._req(False, path, 'DELETE', params)
678+
return self._req(False, path, 'DELETE', request_options, params)
687679

688680
def clear_synonyms(self, forward_to_slaves=False,
689681
forward_to_replicas=False, request_options=None):
@@ -1141,4 +1133,4 @@ def search_rules(self, query=None, anchoring=None, context=None, page=None, hits
11411133
def _req(self, is_search, path, meth, request_options, params=None, data=None):
11421134
"""Perform an HTTPS request with retry logic."""
11431135
path = '%s%s' % (self._request_path, path)
1144-
return self.client._req(is_search, path, meth, params, data, request_options)
1136+
return self.client._req(is_search, path, meth, request_options, params, data)

algoliasearch/transport.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,23 +144,17 @@ def req(self, is_search, path, meth, params, data, request_options):
144144
"""Perform an HTTPS request with retry logic."""
145145

146146
# Merge params and request_options params.
147-
if params is None:
148-
params = request_options.parameters
149-
elif request_options.parameters is not None:
150-
old_params = params
151-
params = params.copy()
152-
params.update(old_params)
147+
params = {} if params is None else params.copy()
148+
if request_options is not None and request_options.parameters is not None:
149+
params.update(request_options.parameters)
150+
151+
params = urlify(params)
153152

154153
# Merge headers and request_options headers.
155-
if self.headers is None:
156-
headers = request_options.headers
157-
elif request_options.headers is not None:
158-
headers = self.headers.copy()
154+
headers = {} if self.headers is None else self.headers.copy()
155+
if request_options is not None and request_options.headers is not None:
159156
headers.update(request_options.headers)
160157

161-
if params is not None:
162-
params = urlify(params)
163-
164158
if data is not None:
165159
data = json.dumps(data, cls=CustomJSONEncoder)
166160

tests/helpers.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from faker import Factory
1010
from algoliasearch.client import Client
1111

12+
from collections import namedtuple
13+
1214

1315
class FakeData(object):
1416
def __init__(self):
@@ -87,3 +89,17 @@ def wait_missing_key(index, key):
8789
except:
8890
# Not found.
8991
return
92+
93+
FakeResp = namedtuple('FakeResp', ['status_code', 'json'])
94+
95+
class FakeSession(object):
96+
def __init__(self, test_class, exp_headers, exp_params):
97+
self.test_class = test_class
98+
self.headers = exp_headers
99+
self.params = exp_params
100+
101+
def request(self, path, meth, timeout, params, data, headers):
102+
self.test_class.assertDictEqual(headers, self.headers)
103+
self.test_class.assertDictEqual(params, self.params)
104+
105+
return FakeResp(status_code=200, json=lambda: '{}')

tests/test_client.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
except ImportError:
1212
import unittest
1313

14-
from algoliasearch.client import Client, MAX_API_KEY_LENGTH
14+
from algoliasearch.client import Client, MAX_API_KEY_LENGTH, RequestOptions
1515
from algoliasearch.helpers import AlgoliaException
1616

1717
from .helpers import safe_index_name
1818
from .helpers import get_api_client
19-
from .helpers import FakeData
19+
from .helpers import FakeData, FakeSession
2020

2121

2222
class ClientTest(unittest.TestCase):
@@ -44,6 +44,19 @@ def tearDownClass(cls):
4444
class ClientNoDataOperationsTest(ClientTest):
4545
"""Tests that use two index and don't make any data operations."""
4646

47+
def test_request_options(self):
48+
options = {'forwardedFor': 'blabla', 'hitsPerPage': 40}
49+
50+
expected_headers = self.client._transport.headers.copy()
51+
expected_headers.update({'X-Forwarded-For': 'blabla'})
52+
53+
fake_session = FakeSession(self, expected_headers , {'hitsPerPage': 40})
54+
55+
old_session = self.client._transport.session
56+
self.client._transport.session = fake_session
57+
self.client.is_alive(RequestOptions(options))
58+
self.client._transport.session = old_session
59+
4760
def test_rate_limit_forward(self):
4861
hearders_rate_limit = {
4962
'X-Forwarded-For': '127.0.0.1',

0 commit comments

Comments
 (0)