From df346e8703bcd279ceba524f0272f7d86c3586d1 Mon Sep 17 00:00:00 2001 From: SergioLangaritaBenitez Date: Thu, 18 Jun 2026 13:32:53 +0200 Subject: [PATCH 1/5] fix: add DELETE support and Content-Type header in make_request --- oscar_python/_utils.py | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/oscar_python/_utils.py b/oscar_python/_utils.py index 945d8c4..5f3a27b 100644 --- a/oscar_python/_utils.py +++ b/oscar_python/_utils.py @@ -15,6 +15,7 @@ import base64 import json import os +import time as _time import requests import liboidcagent as agent _DEFAULT_TIMEOUT = 60 @@ -32,21 +33,29 @@ def make_request(c, path, method, **kwargs): url = c.endpoint+path - if method in ["post", "put"]: - if "token" in kwargs.keys() and kwargs["token"]: - headers = get_headers_with_token(kwargs["token"]) - req_kwargs = {"headers": headers, "verify": c.ssl, "timeout": timeout} - if "data" in kwargs.keys() and kwargs["data"]: - req_kwargs["data"] = kwargs["data"] - result = requests.request(method, url, **req_kwargs) - else: - result = requests.request(method, url, headers=headers, verify=c.ssl, timeout=timeout) + max_retries = 3 + for attempt in range(max_retries): + if method in ["post", "put", "delete"]: + if "token" in kwargs.keys() and kwargs["token"]: + headers = get_headers_with_token(kwargs["token"]) + req_kwargs = {"headers": headers, "verify": c.ssl, "timeout": timeout} + if "data" in kwargs.keys() and kwargs["data"]: + req_kwargs["data"] = kwargs["data"] + req_kwargs["headers"]["Content-Type"] = "application/json" + result = requests.request(method, url, **req_kwargs) + else: + result = requests.request(method, url, headers=headers, verify=c.ssl, timeout=timeout) - if "handle" in kwargs.keys() and kwargs["handle"] is False: - return result + if "handle" in kwargs.keys() and kwargs["handle"] is False: + return result - result.raise_for_status() - return result + if result.status_code == 500 and method == "put": + if attempt < max_retries - 1: + _time.sleep(0.5 * (2 ** attempt)) + continue + + result.raise_for_status() + return result def get_headers(c): From 8a2c2e28d4e5a43efa8569a160bf19a3ee0dee43 Mon Sep 17 00:00:00 2001 From: SergioLangaritaBenitez Date: Thu, 18 Jun 2026 13:38:27 +0200 Subject: [PATCH 2/5] fix: update test_make_request_post to expect Content-Type header --- tests/test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index dcc66dc..cb99af7 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -78,7 +78,7 @@ class MockClient: assert response.status_code == 200 mock_request.assert_called_once_with( "post", "http://test.com/test", - headers={"Authorization": "Bearer test_token"}, + headers={"Authorization": "Bearer test_token", "Content-Type": "application/json"}, verify=True, data="test_data", timeout=60) From 66da7aeadda8d8429f6a3e655dcd53d107af51d8 Mon Sep 17 00:00:00 2001 From: SergioLangaritaBenitez Date: Thu, 30 Jul 2026 11:47:27 +0200 Subject: [PATCH 3/5] add headers in run service --- oscar_python/_utils.py | 4 ++++ oscar_python/default_client.py | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/oscar_python/_utils.py b/oscar_python/_utils.py index 5f3a27b..b6ebf0d 100644 --- a/oscar_python/_utils.py +++ b/oscar_python/_utils.py @@ -42,6 +42,10 @@ def make_request(c, path, method, **kwargs): if "data" in kwargs.keys() and kwargs["data"]: req_kwargs["data"] = kwargs["data"] req_kwargs["headers"]["Content-Type"] = "application/json" + if "headers" in kwargs.keys() and kwargs["headers"]: + for header in kwargs["headers"].split(","): + chunck = header.split(":") + req_kwargs["headers"][chunck[0]] = chunck[1].lstrip() result = requests.request(method, url, **req_kwargs) else: result = requests.request(method, url, headers=headers, verify=c.ssl, timeout=timeout) diff --git a/oscar_python/default_client.py b/oscar_python/default_client.py index e748d4b..416b7c2 100644 --- a/oscar_python/default_client.py +++ b/oscar_python/default_client.py @@ -31,7 +31,8 @@ def run_service(self, name, **kwargs): path = _JOB_PATH + "/" + name response = utils.make_request(self, path, _POST, data=send_data, - token=token, timeout=kwargs.get("timeout")) + token=token, timeout=kwargs.get("timeout"), + headers=kwargs.get("headers")) if kwargs.get("output"): utils.decode_output(response.text, kwargs["output"]) From c499aeac3fce500bb0c8c77fc0abfa44bd81dece Mon Sep 17 00:00:00 2001 From: SergioLangaritaBenitez Date: Thu, 30 Jul 2026 11:56:35 +0200 Subject: [PATCH 4/5] add exception --- oscar_python/_utils.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/oscar_python/_utils.py b/oscar_python/_utils.py index b6ebf0d..212432e 100644 --- a/oscar_python/_utils.py +++ b/oscar_python/_utils.py @@ -43,9 +43,12 @@ def make_request(c, path, method, **kwargs): req_kwargs["data"] = kwargs["data"] req_kwargs["headers"]["Content-Type"] = "application/json" if "headers" in kwargs.keys() and kwargs["headers"]: - for header in kwargs["headers"].split(","): - chunck = header.split(":") - req_kwargs["headers"][chunck[0]] = chunck[1].lstrip() + try: + for header in kwargs["headers"].split(","): + chunck = header.split(":") + req_kwargs["headers"][chunck[0]] = chunck[1].lstrip() + except Exception as e: + print("error: " + str(e)) result = requests.request(method, url, **req_kwargs) else: result = requests.request(method, url, headers=headers, verify=c.ssl, timeout=timeout) From 1f2bf6b417f358a38314dd72ccad697f8ce4fe1d Mon Sep 17 00:00:00 2001 From: SergioLangaritaBenitez Date: Thu, 30 Jul 2026 12:04:28 +0200 Subject: [PATCH 5/5] fix tests --- tests/test_default_client.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_default_client.py b/tests/test_default_client.py index 74428e1..c17afdb 100644 --- a/tests/test_default_client.py +++ b/tests/test_default_client.py @@ -27,7 +27,7 @@ def test_run_service_with_input_and_token(mock_decode_output, mock_encode_input, mock_encode_input.assert_called_once_with("test_input") mock_make_request.assert_called_once_with( client, _RUN_PATH+"/test_service", _POST, - data="encoded_input", token="test_token", timeout=30) + data="encoded_input", token="test_token", timeout=30, headers=None) mock_decode_output.assert_called_once_with("response_text", "output_file") assert response == mock_response @@ -45,7 +45,7 @@ def test_run_service_with_input_no_token(mock_encode_input, mock_make_request, c mock_encode_input.assert_called_once_with("test_input") mock_make_request.assert_called_once_with( client, _RUN_PATH+"/test_service", _POST, - data="encoded_input", token="test_token", timeout=None) + data="encoded_input", token="test_token", timeout=None, headers=None) assert response == mock_response @@ -57,9 +57,9 @@ def test_run_service_no_input(mock_make_request, client): response = client.run_service("test_service", input="data") mock_make_request.assert_called_with(client, _RUN_PATH+"/test_service", _POST, - token="test_token", data=b'ZGF0YQ==', timeout=None) + token="test_token", data=b'ZGF0YQ==', timeout=None, headers=None) response = client.run_service("test_service", input="data", async_call=True, timeout=30) mock_make_request.assert_called_with(client, _JOB_PATH+"/test_service", _POST, - token="test_token", data=b'ZGF0YQ==', timeout=30) + token="test_token", data=b'ZGF0YQ==', timeout=30, headers=None) assert response == mock_response