From fc0470c7929f8912cd2853ec8dec37a8b665c786 Mon Sep 17 00:00:00 2001 From: Jack Brown Date: Fri, 2 Dec 2022 14:41:41 -0500 Subject: [PATCH 1/8] add request argument to connection --- tests/test_connection.py | 25 +++++++++++++++++++++++++ xcc/connection.py | 12 ++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/tests/test_connection.py b/tests/test_connection.py index d4147b2..847fc87 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -4,6 +4,7 @@ """ import json +from unittest.mock import MagicMock import pytest import requests @@ -271,6 +272,30 @@ def mock_request(*args, **kwargs): with pytest.raises(RequestException, match=r"Failed to resolve hostname 'test.xanadu.ai'"): connection.request("GET", "/healthz") + def test_request_headers(self, connection): + """Test that request() passes the headers attribute to _request if the headers argument + is not provided.""" + + connection._request = MagicMock() + connection.request(method="method", path="path") + + connection._request.assert_called_once_with( + method="method", url=connection.url("path"), headers=connection.headers + ) + + @pytest.mark.parametrize("extra_headers", [{"X-Test": "data"}, {}]) + def test_request_extra_headers(self, connection, extra_headers): + """Tests that request() passes the combined headers from the headers attribute + and the headers argument to the _request method.""" + connection._request = MagicMock() + + connection.request(method="post", path="path", headers=extra_headers) + connection._request.assert_called_once_with( + method="post", + url=connection.url("path"), + headers={**connection.headers, **extra_headers}, + ) + @responses.activate def test_update_access_token_success(self, connection): """Tests that the access token of a connection can be updated.""" diff --git a/xcc/connection.py b/xcc/connection.py index 80d34c8..b0363f5 100644 --- a/xcc/connection.py +++ b/xcc/connection.py @@ -210,12 +210,15 @@ def ping(self) -> requests.Response: """ return self.request(method="GET", path="/healthz") - def request(self, method: str, path: str, **kwargs) -> requests.Response: + def request( + self, method: str, path: str, *, headers: Optional[Dict[str, str]] = None, **kwargs + ) -> requests.Response: """Sends an HTTP request to the Xanadu Cloud. Args: method (str): HTTP request method path (str): HTTP request path + headers (Mapping[str, str]): Extra headers to pass to request **kwargs: optional arguments to pass to :func:`requests.request()` Returns: @@ -235,7 +238,12 @@ def request(self, method: str, path: str, **kwargs) -> requests.Response: """ url = self.url(path) - response = self._request(method=method, url=url, headers=self.headers, **kwargs) + if headers: + headers = {**self.headers, **headers} + else: + headers = self.headers + + response = self._request(method=method, url=url, headers=headers, **kwargs) if response.status_code == 401: self.update_access_token() From bf1732aa69914835cf372c2755664aa8d99b299a Mon Sep 17 00:00:00 2001 From: Jack Brown Date: Fri, 2 Dec 2022 14:46:45 -0500 Subject: [PATCH 2/8] update changelog --- .github/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 83a3b3e..b565361 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -2,6 +2,9 @@ ### New features since last release +* Extra request headers may be passed to `Connection.request()`. + [(#36)](https://github.com/XanaduAI/xanadu-cloud-client/pull/36) + * Job lists can now be filtered by status. [(#30)](https://github.com/XanaduAI/xanadu-cloud-client/pull/30) From 5bb36e56b576f0194fab080ccab24251f314d713 Mon Sep 17 00:00:00 2001 From: Jack Brown Date: Fri, 2 Dec 2022 15:21:13 -0500 Subject: [PATCH 3/8] try respones --- requirements-dev.txt | 2 +- tests/test_connection.py | 33 ++++++++++++++++++++++----------- xcc/connection.py | 1 + 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 45088be..cf9fdc3 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,5 +3,5 @@ build==0.7.0 isort[colors]==5.9.3 pylint==2.11.1 pytest-cov==3.0.0 -responses==0.14.0 +responses==0.22.0 wheel==0.37.1 diff --git a/tests/test_connection.py b/tests/test_connection.py index 847fc87..7540e13 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -10,6 +10,7 @@ import requests import responses from requests.exceptions import HTTPError, RequestException +from responses import matchers import xcc @@ -272,28 +273,38 @@ def mock_request(*args, **kwargs): with pytest.raises(RequestException, match=r"Failed to resolve hostname 'test.xanadu.ai'"): connection.request("GET", "/healthz") + @responses.activate def test_request_headers(self, connection): """Test that request() passes the headers attribute to _request if the headers argument is not provided.""" - connection._request = MagicMock() - connection.request(method="method", path="path") - - connection._request.assert_called_once_with( - method="method", url=connection.url("path"), headers=connection.headers + responses.add( + url=connection.url("path"), + method="POST", + status=200, + match=(matchers.request_kwargs_matcher({"headers": connection.headers}),), ) + assert connection.request(method="POST", path="path").status_code == 200 + + @responses.activate @pytest.mark.parametrize("extra_headers", [{"X-Test": "data"}, {}]) def test_request_extra_headers(self, connection, extra_headers): """Tests that request() passes the combined headers from the headers attribute and the headers argument to the _request method.""" - connection._request = MagicMock() - - connection.request(method="post", path="path", headers=extra_headers) - connection._request.assert_called_once_with( - method="post", + responses.add( url=connection.url("path"), - headers={**connection.headers, **extra_headers}, + method="POST", + status=200, + match=( + matchers.request_kwargs_matcher( + {"headers": {**connection.headers, **extra_headers}} + ), + ), + ) + + assert ( + connection.request(method="POST", path="path", headers=extra_headers).status_code == 200 ) @responses.activate diff --git a/xcc/connection.py b/xcc/connection.py index b0363f5..f396284 100644 --- a/xcc/connection.py +++ b/xcc/connection.py @@ -357,6 +357,7 @@ def _request(self, method: str, url: str, **kwargs) -> requests.Response: """ try: timeout = kwargs.pop("timeout", 10) + return requests.request(method=method, url=url, timeout=timeout, **kwargs) except requests.exceptions.Timeout as exc: From cdde6b7a31658cf97f5ed371f528f5fe5f94130e Mon Sep 17 00:00:00 2001 From: Jack Brown Date: Fri, 2 Dec 2022 15:24:46 -0500 Subject: [PATCH 4/8] use header matcher --- tests/test_connection.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/test_connection.py b/tests/test_connection.py index 7540e13..edec540 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -282,7 +282,7 @@ def test_request_headers(self, connection): url=connection.url("path"), method="POST", status=200, - match=(matchers.request_kwargs_matcher({"headers": connection.headers}),), + match=(matchers.header_matcher(connection.headers),), ) assert connection.request(method="POST", path="path").status_code == 200 @@ -296,11 +296,7 @@ def test_request_extra_headers(self, connection, extra_headers): url=connection.url("path"), method="POST", status=200, - match=( - matchers.request_kwargs_matcher( - {"headers": {**connection.headers, **extra_headers}} - ), - ), + match=(matchers.header_matcher({**connection.headers, **extra_headers}),), ) assert ( From a9579b56da49d639ad4f771723aed63c242faf15 Mon Sep 17 00:00:00 2001 From: Jack Brown Date: Fri, 2 Dec 2022 15:26:59 -0500 Subject: [PATCH 5/8] unused import --- tests/test_connection.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_connection.py b/tests/test_connection.py index edec540..a157dc1 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -4,7 +4,6 @@ """ import json -from unittest.mock import MagicMock import pytest import requests From 651dbedac3ae9c28de770154e42bf659ed2fce0f Mon Sep 17 00:00:00 2001 From: Jack Brown Date: Tue, 6 Dec 2022 11:08:29 -0500 Subject: [PATCH 6/8] Apply suggestions from code review Co-authored-by: Mikhail Andrenkov --- tests/test_connection.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/test_connection.py b/tests/test_connection.py index a157dc1..9607239 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -274,8 +274,7 @@ def mock_request(*args, **kwargs): @responses.activate def test_request_headers(self, connection): - """Test that request() passes the headers attribute to _request if the headers argument - is not provided.""" + """Tests that the correct headers are passed when the headers argument is not provided. responses.add( url=connection.url("path"), @@ -284,13 +283,12 @@ def test_request_headers(self, connection): match=(matchers.header_matcher(connection.headers),), ) - assert connection.request(method="POST", path="path").status_code == 200 + connection.request(method="POST", path="path") @responses.activate @pytest.mark.parametrize("extra_headers", [{"X-Test": "data"}, {}]) def test_request_extra_headers(self, connection, extra_headers): - """Tests that request() passes the combined headers from the headers attribute - and the headers argument to the _request method.""" + """Tests that the correct headers are passed when the headers argument is provided. responses.add( url=connection.url("path"), method="POST", @@ -298,9 +296,7 @@ def test_request_extra_headers(self, connection, extra_headers): match=(matchers.header_matcher({**connection.headers, **extra_headers}),), ) - assert ( - connection.request(method="POST", path="path", headers=extra_headers).status_code == 200 - ) + connection.request(method="POST", path="path", headers=extra_headers) @responses.activate def test_update_access_token_success(self, connection): From 44b131bcdb23a340d3f731b51c2e6e037629bb58 Mon Sep 17 00:00:00 2001 From: Jack Brown Date: Tue, 6 Dec 2022 11:08:51 -0500 Subject: [PATCH 7/8] Update xcc/connection.py Co-authored-by: Mikhail Andrenkov --- xcc/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xcc/connection.py b/xcc/connection.py index f396284..632b259 100644 --- a/xcc/connection.py +++ b/xcc/connection.py @@ -218,7 +218,7 @@ def request( Args: method (str): HTTP request method path (str): HTTP request path - headers (Mapping[str, str]): Extra headers to pass to request + headers (Mapping[str, str]): extra headers to pass to the request **kwargs: optional arguments to pass to :func:`requests.request()` Returns: From b521e1bd20da85938c93974432a125399a0b1e2a Mon Sep 17 00:00:00 2001 From: Jack Brown Date: Tue, 6 Dec 2022 11:12:23 -0500 Subject: [PATCH 8/8] fix line --- tests/test_connection.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_connection.py b/tests/test_connection.py index 9607239..89fe53b 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -274,7 +274,7 @@ def mock_request(*args, **kwargs): @responses.activate def test_request_headers(self, connection): - """Tests that the correct headers are passed when the headers argument is not provided. + """Tests that the correct headers are passed when the headers argument is not provided.""" responses.add( url=connection.url("path"), @@ -288,7 +288,7 @@ def test_request_headers(self, connection): @responses.activate @pytest.mark.parametrize("extra_headers", [{"X-Test": "data"}, {}]) def test_request_extra_headers(self, connection, extra_headers): - """Tests that the correct headers are passed when the headers argument is provided. + """Tests that the correct headers are passed when the headers argument is provided.""" responses.add( url=connection.url("path"), method="POST",