Skip to content

Commit 2d7cd16

Browse files
bartonipfilak-sap
authored andcommitted
Made headers attribute actually affect the headers
1 parent d1725fa commit 2d7cd16

File tree

2 files changed

+95
-17
lines changed

2 files changed

+95
-17
lines changed

pyodata/v2/service.py

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def __init__(self, url, connection, handler, headers=None):
239239
self._connection = connection
240240
self._url = url
241241
self._handler = handler
242-
self._headers = headers
242+
self._headers = headers or dict()
243243
self._logger = logging.getLogger(LOGGER_NAME)
244244

245245
@property
@@ -267,10 +267,32 @@ def get_body(self):
267267
# pylint: disable=no-self-use
268268
return None
269269

270-
def get_headers(self):
271-
"""Get dict of HTTP headers"""
270+
def get_default_headers(self):
271+
"""Get dict of Child specific HTTP headers"""
272272
# pylint: disable=no-self-use
273-
return None
273+
return dict()
274+
275+
def get_headers(self):
276+
"""Get dict of HTTP headers which is union of return value
277+
of the method get_default_headers() and the headers
278+
added via the method add_headers() where the latter
279+
headers have priority - same keys get value of the latter.
280+
"""
281+
282+
headers = self.get_default_headers()
283+
headers.update(self._headers)
284+
285+
return headers
286+
287+
def add_headers(self, value):
288+
"""Add the give dictionary of HTTP headers to
289+
HTTP request sent by this ODataHttpRequest instance.
290+
"""
291+
292+
if not isinstance(value, dict):
293+
raise TypeError("Headers must be of type 'dict' not {}".format(type(value)))
294+
295+
self._headers.update(value)
274296

275297
def execute(self):
276298
"""Fetches HTTP response and returns processed result
@@ -284,12 +306,7 @@ def execute(self):
284306
# pylint: disable=assignment-from-none
285307
body = self.get_body()
286308

287-
headers = {} if self._headers is None else self._headers
288-
289-
# pylint: disable=assignment-from-none
290-
extra_headers = self.get_headers()
291-
if extra_headers is not None:
292-
headers.update(extra_headers)
309+
headers = self.get_headers()
293310

294311
self._logger.debug('Send (execute) %s request to %s', self.get_method(), url)
295312
self._logger.debug(' query params: %s', self.get_query_params())
@@ -350,7 +367,7 @@ def expand(self, expand):
350367
def get_path(self):
351368
return self._entity_set_proxy.last_segment + self._entity_key.to_key_string()
352369

353-
def get_headers(self):
370+
def get_default_headers(self):
354371
return {'Accept': 'application/json'}
355372

356373
def get_query_params(self):
@@ -447,7 +464,7 @@ def _get_body(self):
447464
def get_body(self):
448465
return json.dumps(self._get_body())
449466

450-
def get_headers(self):
467+
def get_default_headers(self):
451468
return {'Accept': 'application/json', 'Content-Type': 'application/json', 'X-Requested-With': 'X'}
452469

453470
@staticmethod
@@ -547,7 +564,7 @@ def get_body(self):
547564
body[key] = val
548565
return json.dumps(body)
549566

550-
def get_headers(self):
567+
def get_default_headers(self):
551568
return {'Accept': 'application/json', 'Content-Type': 'application/json'}
552569

553570
def set(self, **kwargs):
@@ -640,7 +657,7 @@ def get_path(self):
640657

641658
return self._last_segment
642659

643-
def get_headers(self):
660+
def get_default_headers(self):
644661
if self._count:
645662
return {}
646663

@@ -703,9 +720,9 @@ def parameter(self, name, value):
703720
def get_method(self):
704721
return self._function_import.http_method
705722

706-
def get_headers(self):
723+
def get_default_headers(self):
707724
return {
708-
'Accept': 'application/json',
725+
'Accept': 'application/json'
709726
}
710727

711728

@@ -1461,7 +1478,7 @@ def get_boundary(self):
14611478
"""Get boundary used for request parts"""
14621479
return self.id
14631480

1464-
def get_headers(self):
1481+
def get_default_headers(self):
14651482
# pylint: disable=no-self-use
14661483
return {'Content-Type': 'multipart/mixed;boundary={}'.format(self.get_boundary())}
14671484

tests/test_service_v2.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,67 @@ def test_get_entity_with_entity_key_and_other_params(service):
763763
query = service.entity_sets.TemperatureMeasurements.update_entity(key=key, Foo='Bar')
764764
assert query.get_path() == "TemperatureMeasurements(Sensor='sensor1',Date=datetime'2017-12-24T18:00:00')"
765765

766+
767+
def test_get_entities_with_custom_headers(service):
768+
query = service.entity_sets.TemperatureMeasurements.get_entities()
769+
query.add_headers({"X-Foo": "bar"})
770+
771+
assert query.get_headers() == {"Accept": "application/json", "X-Foo": "bar"}
772+
773+
774+
def test_get_entity_with_custom_headers(service):
775+
key = EntityKey(
776+
service.schema.entity_type('TemperatureMeasurement'),
777+
Sensor='sensor1',
778+
Date=datetime.datetime(2017, 12, 24, 18, 0))
779+
780+
query = service.entity_sets.TemperatureMeasurements.get_entity(key)
781+
query.add_headers({"X-Foo": "bar"})
782+
783+
assert query.get_headers() == {"Accept": "application/json", "X-Foo": "bar"}
784+
785+
786+
def test_update_entities_with_custom_headers(service):
787+
key = EntityKey(
788+
service.schema.entity_type('TemperatureMeasurement'),
789+
Sensor='sensor1',
790+
Date=datetime.datetime(2017, 12, 24, 18, 0))
791+
792+
query = service.entity_sets.TemperatureMeasurements.update_entity(key)
793+
query.add_headers({"X-Foo": "bar"})
794+
795+
assert query.get_headers() == {"Accept": "application/json", "Content-Type": "application/json", "X-Foo": "bar"}
796+
797+
798+
def test_create_entity_with_custom_headers(service):
799+
query = service.entity_sets.TemperatureMeasurements.create_entity()
800+
query.add_headers({"X-Foo": "bar"})
801+
802+
assert query.get_headers() == {"Accept": "application/json", "Content-Type": "application/json", "X-Requested-With": "X", "X-Foo": "bar"}
803+
804+
805+
def test_create_entity_with_overwriting_custom_headers(service):
806+
query = service.entity_sets.TemperatureMeasurements.create_entity()
807+
query.add_headers({"X-Requested-With": "bar"})
808+
809+
assert query.get_headers() == {"Accept": "application/json", "Content-Type": "application/json", "X-Requested-With": "bar"}
810+
811+
812+
def test_create_entity_with_blank_custom_headers(service):
813+
query = service.entity_sets.TemperatureMeasurements.create_entity()
814+
query.add_headers({})
815+
816+
assert query.get_headers() == {"Accept": "application/json", "Content-Type": "application/json", "X-Requested-With": "X"}
817+
818+
819+
def test_pass_incorrect_header_type(service):
820+
query = service.entity_sets.TemperatureMeasurements.create_entity()
821+
822+
with pytest.raises(TypeError) as ex:
823+
query.add_headers(69420)
824+
assert str(ex) == "TypeError: Headers must be of type 'dict' not <class 'int'>"
825+
826+
766827
@responses.activate
767828
def test_get_entities(service):
768829
"""Get entities"""

0 commit comments

Comments
 (0)