Skip to content

feat: add support for reading apiVersion in discovery artifacts #2380

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion googleapiclient/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -1170,9 +1170,11 @@ def method(self, **kwargs):
elif "response" not in methodDesc:
model = RawModel()

api_version = methodDesc.get("apiVersion", None)

headers = {}
headers, params, query, body = model.request(
headers, actual_path_params, actual_query_params, body_value
headers, actual_path_params, actual_query_params, body_value, api_version
)

expanded_url = uritemplate.expand(pathUrl, params)
Expand Down
24 changes: 22 additions & 2 deletions googleapiclient/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,18 @@
import logging
import platform
import urllib
import warnings

from googleapiclient import version as googleapiclient_version
from googleapiclient.errors import HttpError

try:
from google.api_core.version_header import API_VERSION_METADATA_KEY

HAS_API_VERSION = True
except ImportError:
HAS_API_VERSION = False

_LIBRARY_VERSION = googleapiclient_version.__version__
_PY_VERSION = platform.python_version()

Expand Down Expand Up @@ -121,15 +129,18 @@ def _log_request(self, headers, path_params, query, body):
LOGGER.info("query: %s", query)
LOGGER.info("--request-end--")

def request(self, headers, path_params, query_params, body_value):
def request(self, headers, path_params, query_params, body_value, api_version=None):
"""Updates outgoing requests with a serialized body.
Args:
headers: dict, request headers
path_params: dict, parameters that appear in the request path
query_params: dict, parameters that appear in the query
body_value: object, the request body as a Python object, which must be
serializable by json.
serializable by json.
api_version: str, The precise API version represented by this request,
which will result in an API Version header being sent along with the
HTTP request.
Returns:
A tuple of (headers, path_params, query, body)
Expand All @@ -155,6 +166,15 @@ def request(self, headers, path_params, query_params, body_value):
_PY_VERSION,
)

if api_version and HAS_API_VERSION:
headers[API_VERSION_METADATA_KEY] = api_version
elif api_version:
warnings.warn(
"The `api_version` argument is ignored as a newer version of "
"`google-api-core` is required to use this feature."
"Please upgrade `google-api-core` to 2.19.0 or newer."
)

if body_value is not None:
headers["content-type"] = self.content_type
body_value = self.serialize(body_value)
Expand Down
30 changes: 30 additions & 0 deletions tests/test_json_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@
import googleapiclient.model
from googleapiclient.model import JsonModel

try:
from google.api_core.version_header import API_VERSION_METADATA_KEY

HAS_API_VERSION = True
except ImportError:
HAS_API_VERSION = False

_LIBRARY_VERSION = googleapiclient_version.__version__
CSV_TEXT_MOCK = "column1,column2,column3\nstring1,1.2,string2"

Expand Down Expand Up @@ -172,6 +179,29 @@ def test_x_goog_api_client(self):
+ platform.python_version(),
)

@unittest.skipIf(
not HAS_API_VERSION,
"Skip this test when an older version of google-api-core is used",
)
def test_x_goog_api_version(self):
model = JsonModel(data_wrapper=False)

# test header composition for clients that wrap discovery
headers = {}
path_params = {}
query_params = {}
body = {}
api_version = "20240401"

headers, _, _, body = model.request(
headers, path_params, query_params, body, api_version
)

self.assertEqual(
headers[API_VERSION_METADATA_KEY],
api_version,
)

def test_bad_response(self):
model = JsonModel(data_wrapper=False)
resp = httplib2.Response({"status": "401"})
Expand Down