diff --git a/google/cloud/_http/__init__.py b/google/cloud/_http/__init__.py index 4c3ed96..af25e65 100644 --- a/google/cloud/_http/__init__.py +++ b/google/cloud/_http/__init__.py @@ -282,6 +282,7 @@ def _make_request( headers=None, target_object=None, timeout=_DEFAULT_TIMEOUT, + extra_api_info=None, ): """A low level method to send a request to the API. @@ -317,6 +318,10 @@ def _make_request( Can also be passed as a tuple (connect_timeout, read_timeout). See :meth:`requests.Session.request` documentation for details. + :type extra_api_info: string + :param extra_api_info: (optional) Extra api info to be appended to + the X-Goog-API-Client header + :rtype: :class:`requests.Response` :returns: The HTTP response. """ @@ -327,7 +332,10 @@ def _make_request( if content_type: headers["Content-Type"] = content_type - headers[CLIENT_INFO_HEADER] = self.user_agent + if extra_api_info: + headers[CLIENT_INFO_HEADER] = f"{self.user_agent} {extra_api_info}" + else: + headers[CLIENT_INFO_HEADER] = self.user_agent headers["User-Agent"] = self.user_agent return self._do_request( @@ -385,6 +393,7 @@ def api_request( expect_json=True, _target_object=None, timeout=_DEFAULT_TIMEOUT, + extra_api_info=None, ): """Make a request over the HTTP transport to the API. @@ -446,6 +455,10 @@ def api_request( Can also be passed as a tuple (connect_timeout, read_timeout). See :meth:`requests.Session.request` documentation for details. + :type extra_api_info: string + :param extra_api_info: (optional) Extra api info to be appended to + the X-Goog-API-Client header + :raises ~google.cloud.exceptions.GoogleCloudError: if the response code is not 200 OK. :raises ValueError: if the response content type is not JSON. @@ -474,6 +487,7 @@ def api_request( headers=headers, target_object=_target_object, timeout=timeout, + extra_api_info=extra_api_info, ) if not 200 <= response.status_code < 300: diff --git a/tests/unit/test__http.py b/tests/unit/test__http.py index ab03fac..faee193 100644 --- a/tests/unit/test__http.py +++ b/tests/unit/test__http.py @@ -575,6 +575,31 @@ def test_api_request_w_timeout(self): timeout=(2.2, 3.3), ) + def test_api_request_w_extra_api_info(self): + from google.cloud._http import CLIENT_INFO_HEADER + + session = make_requests_session([self.EMPTY_JSON_RESPONSE]) + client = mock.Mock(_http=session, spec=["_http"]) + conn = self._make_mock_one(client) + + EXTRA_API_INFO = "gccl-invocation-id/testing-id-123" + result = conn.api_request("GET", "/", extra_api_info=EXTRA_API_INFO) + + self.assertEqual(result, {}) + + expected_headers = { + "Accept-Encoding": "gzip", + "User-Agent": conn.user_agent, + CLIENT_INFO_HEADER: f"{conn.user_agent} {EXTRA_API_INFO}", + } + session.request.assert_called_once_with( + method="GET", + url=mock.ANY, + headers=expected_headers, + data=None, + timeout=self._get_default_timeout(), + ) + def test_api_request_w_404(self): from google.cloud import exceptions