Skip to content

Commit 5a37ba2

Browse files
feat(http-header): add support for complex types (#91)
This commits adds support for processing complex object-typed header parameters in the request builder class. Also, adds the case-insensitivity behavior in the headers which was previously missing. Also, adds unit tests to validate handling of complex header parameters Closes #90 * removed duplication in the test input values
1 parent 9096bc3 commit 5a37ba2

4 files changed

Lines changed: 53 additions & 39 deletions

File tree

apimatic_core/configurations/global_configuration.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from requests.structures import CaseInsensitiveDict
2+
13
from apimatic_core.http.configurations.http_client_configuration import HttpClientConfiguration
24
from apimatic_core.utilities.api_helper import ApiHelper
35

@@ -27,8 +29,8 @@ def __init__(
2729
):
2830
self._http_client_configuration = http_client_configuration
2931
self._global_errors = {}
30-
self._global_headers = {}
31-
self._additional_headers = {}
32+
self._global_headers = CaseInsensitiveDict()
33+
self._additional_headers = CaseInsensitiveDict()
3234
self._auth_managers = {}
3335
self._base_uri_executor = None
3436

apimatic_core/request_builder.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from requests.structures import CaseInsensitiveDict
2+
13
from apimatic_core.exceptions.auth_validation_exception import AuthValidationException
24
from apimatic_core.http.request.http_request import HttpRequest
35
from apimatic_core.types.array_serialization_format import SerializationFormats
@@ -15,12 +17,11 @@ def get_param_name(param_value):
1517
def __init__(
1618
self
1719
):
18-
1920
self._server = None
2021
self._path = None
2122
self._http_method = None
2223
self._template_params = {}
23-
self._header_params = {}
24+
self._header_params = CaseInsensitiveDict()
2425
self._query_params = {}
2526
self._form_params = {}
2627
self._additional_form_params = {}
@@ -107,10 +108,10 @@ def xml_attributes(self, xml_attributes):
107108
def build(self, global_configuration):
108109
_url = self.process_url(global_configuration)
109110

110-
_request_headers = self.process_request_headers(global_configuration)
111-
112111
_request_body = self.process_body_params()
113112

113+
_request_headers = self.process_request_headers(global_configuration)
114+
114115
_multipart_params = self.process_multipart_params()
115116

116117
http_request = HttpRequest(http_method=self._http_method,
@@ -147,14 +148,19 @@ def process_request_headers(self, global_configuration):
147148
additional_headers = global_configuration.get_additional_headers()
148149

149150
if global_headers:
150-
prepared_headers = {key: str(value) if value is not None else value
151-
for key, value in self._header_params.items()}
152-
request_headers = {**global_headers, **prepared_headers}
151+
request_headers = {**global_headers, **self._header_params}
153152

154153
if additional_headers:
155154
request_headers.update(additional_headers)
156155

157-
return request_headers
156+
serialized_headers = CaseInsensitiveDict(
157+
{
158+
key: ApiHelper.json_serialize(value)
159+
if value is not None else value
160+
for key, value in request_headers.items()
161+
}
162+
)
163+
return serialized_headers
158164

159165
def process_body_params(self):
160166
if self._xml_attributes:

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
setup(
1414
name='apimatic-core',
15-
version='0.2.18',
15+
version='0.2.19',
1616
description='A library that contains core logic and utilities for '
1717
'consuming REST APIs using Python SDKs generated by APIMatic.',
1818
long_description=long_description,

tests/apimatic_core/request_builder_tests/test_request_builder.py

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -176,62 +176,68 @@ def test_additional_query_params(self, input_additional_query_params_value, expe
176176
assert http_request.query_url == 'http://localhost:3000/test?{}'.format(expected_additional_query_params_value)
177177

178178
@pytest.mark.parametrize('input_local_header_param_value, expected_local_header_param_value', [
179-
('string', {'header_param': 'string'}),
180-
(500, {'header_param': 500}),
181-
(500.12, {'header_param': 500.12}),
182-
(str(date(1994, 2, 13)), {'header_param': '1994-02-13'}),
179+
('string', {'header': 'string'}),
180+
(200, {'header': '200'}),
181+
(200.12, {'header': '200.12'}),
182+
(str(date(1994, 2, 13)), {'header': '1994-02-13'}),
183183
(ApiHelper.UnixDateTime.from_datetime(datetime(1994, 2, 13, 5, 30, 15)),
184-
{'header_param': 761117415}),
184+
{'header': '761117415'}),
185185
(Base.get_http_datetime(datetime(1994, 2, 13, 5, 30, 15)),
186-
{'header_param': '{}'.format(Base.get_http_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
186+
{'header': '{}'.format(Base.get_http_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
187187
(Base.get_rfc3339_datetime(datetime(1994, 2, 13, 5, 30, 15)),
188-
{'header_param': '{}'.format(Base.get_rfc3339_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
189-
([1, 2, 3, 4], {'header_param': [1, 2, 3, 4]})
188+
{'header': '{}'.format(Base.get_rfc3339_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
189+
([1, 2, 3, 4], {'header': '[1, 2, 3, 4]'}),
190+
({'alpha': 'val', 'beta': 'val'}, {'header': '{"alpha": "val", "beta": "val"}'}),
191+
(Base.employee_model(), {'header': ApiHelper.json_serialize(Base.employee_model())})
190192
])
191193
def test_local_headers(self, input_local_header_param_value, expected_local_header_param_value):
192194
http_request = self.new_request_builder \
193195
.header_param(Parameter()
194-
.key('header_param')
196+
.key('header')
195197
.value(input_local_header_param_value)) \
196198
.build(self.global_configuration)
197199
assert http_request.headers == expected_local_header_param_value
198200

199201
@pytest.mark.parametrize('input_global_header_param_value, expected_global_header_param_value', [
200-
('my-string', {'header_param': 'my-string'}),
201-
(5000, {'header_param': 5000}),
202-
(5000.12, {'header_param': 5000.12}),
203-
(str(date(1998, 2, 13)), {'header_param': '1998-02-13'}),
202+
('my-string', {'global_header': 'my-string'}),
203+
(5000, {'global_header': '5000'}),
204+
(5000.12, {'global_header': '5000.12'}),
205+
(str(date(1998, 2, 13)), {'global_header': '1998-02-13'}),
204206
(ApiHelper.UnixDateTime.from_datetime(datetime(1994, 2, 13, 5, 30, 15)),
205-
{'header_param': 761117415}),
207+
{'global_header': '761117415'}),
206208
(Base.get_http_datetime(datetime(1994, 2, 13, 5, 30, 15)),
207-
{'header_param': '{}'.format(Base.get_http_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
209+
{'global_header': '{}'.format(Base.get_http_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
208210
(Base.get_rfc3339_datetime(datetime(1994, 2, 13, 5, 30, 15)),
209-
{'header_param': '{}'.format(Base.get_rfc3339_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
210-
([100, 200, 300, 400], {'header_param': [100, 200, 300, 400]})
211+
{'global_header': '{}'.format(Base.get_rfc3339_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
212+
([100, 200, 300, 400], {'global_header': '[100, 200, 300, 400]'}),
213+
({'key1': 'val1', 'key2': 'val2'}, {'global_header': '{"key1": "val1", "key2": "val2"}'}),
214+
(Base.employee_model(), {'global_header': ApiHelper.json_serialize(Base.employee_model())})
211215
])
212216
def test_global_headers(self, input_global_header_param_value, expected_global_header_param_value):
213217
http_request = self.new_request_builder \
214218
.build(self.global_configuration
215-
.global_header('header_param', input_global_header_param_value))
219+
.global_header('global_header', input_global_header_param_value))
216220
assert http_request.headers == expected_global_header_param_value
217221

218222
@pytest.mark.parametrize('input_additional_header_param_value, expected_additional_header_param_value', [
219-
('my-string', {'header_param': 'my-string'}),
220-
(5000, {'header_param': 5000}),
221-
(5000.12, {'header_param': 5000.12}),
222-
(str(date(1998, 2, 13)), {'header_param': '1998-02-13'}),
223+
('my-string', {'additional_header': 'my-string'}),
224+
(2000, {'additional_header': '2000'}),
225+
(2000.12, {'additional_header': '2000.12'}),
226+
(str(date(1998, 2, 13)), {'additional_header': '1998-02-13'}),
223227
(ApiHelper.UnixDateTime.from_datetime(datetime(1994, 2, 13, 5, 30, 15)),
224-
{'header_param': 761117415}),
228+
{'additional_header': '761117415'}),
225229
(Base.get_http_datetime(datetime(1994, 2, 13, 5, 30, 15)),
226-
{'header_param': '{}'.format(Base.get_http_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
230+
{'additional_header': '{}'.format(Base.get_http_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
227231
(Base.get_rfc3339_datetime(datetime(1994, 2, 13, 5, 30, 15)),
228-
{'header_param': '{}'.format(Base.get_rfc3339_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
229-
([100, 200, 300, 400], {'header_param': [100, 200, 300, 400]})
232+
{'additional_header': '{}'.format(Base.get_rfc3339_datetime(datetime(1994, 2, 13, 5, 30, 15)))}),
233+
([100, 200, 300, 400], {'additional_header': '[100, 200, 300, 400]'}),
234+
({'alpha': 'val1', 'bravo': 'val2'}, {'additional_header': '{"alpha": "val1", "bravo": "val2"}'}),
235+
(Base.employee_model(), {'additional_header': ApiHelper.json_serialize(Base.employee_model())})
230236
])
231237
def test_additional_headers(self, input_additional_header_param_value, expected_additional_header_param_value):
232238
http_request = self.new_request_builder \
233239
.build(self.global_configuration
234-
.additional_header('header_param', input_additional_header_param_value))
240+
.additional_header('additional_header', input_additional_header_param_value))
235241
assert http_request.headers == expected_additional_header_param_value
236242

237243
@pytest.mark.parametrize('input_global_header_param_value,'
@@ -510,7 +516,7 @@ def test_file_as_body_param(self, input_body_param_value, expected_body_param_va
510516
actual_body_param_value = http_request.parameters
511517

512518
assert actual_body_param_value.read() == expected_body_param_value.read() \
513-
and http_request.headers['content-type'] == expected_content_type
519+
and http_request.headers['Content-Type'] == expected_content_type
514520
finally:
515521
actual_body_param_value.close()
516522
expected_body_param_value.close()

0 commit comments

Comments
 (0)