Skip to content

Commit b804743

Browse files
committed
refactor(api-core): simplify required fields default value merging to keep consistent with original transports
1 parent 36e5f40 commit b804743

2 files changed

Lines changed: 4 additions & 123 deletions

File tree

packages/google-api-core/google/api_core/rest_helpers.py

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -159,49 +159,11 @@ def transcode_request(
159159
)
160160

161161
# If required_fields_default_values is provided, we merge default values for missing
162-
# required fields into the query parameters. However, we must exclude any fields
163-
# that are already bound to the URI path or the request body for the matched HTTP option.
162+
# required fields into the query parameters.
164163
if required_fields_default_values:
165-
# 1. Identify which HTTP option matched the transcoded request by comparing method and URI.
166-
matched_option = None
167-
for option in http_options:
168-
if (
169-
option.get("method", "").lower()
170-
== transcoded_request.get("method", "").lower()
171-
):
172-
if path_template.validate(
173-
option.get("uri", ""), transcoded_request.get("uri", "")
174-
):
175-
matched_option = option
176-
break
177-
178-
# 2. Determine which fields are bound to the path or body.
179-
# If the body is '*', all fields are bound to the body, so bound_fields is None.
180-
bound_fields: Optional[Set[str]] = set()
181-
if matched_option:
182-
body_param = matched_option.get("body")
183-
if body_param == "*":
184-
bound_fields = None
185-
else:
186-
assert bound_fields is not None
187-
uri_template = matched_option.get("uri", "")
188-
# Extract the top-level field names for variables in the URI path.
189-
# E.g., for URI "/v1/{name}" we extract "name".
190-
# For nested path variables like "{options.deprecated}", we split on "."
191-
# and extract the top-level field "options", because required_fields_default_values
192-
# only maps top-level request field names to their default values.
193-
for m in path_template._VARIABLE_RE.finditer(uri_template):
194-
bound_fields.add(m.group("name").split(".")[0])
195-
if body_param:
196-
bound_fields.add(body_param.split(".")[0])
197-
198-
# 3. Only merge default values for fields that are not bound to the path or body.
199-
if bound_fields is not None:
200-
for k, v in required_fields_default_values.items():
201-
if k in bound_fields:
202-
continue
203-
if k not in query_params_json:
204-
query_params_json[k] = v
164+
for k, v in required_fields_default_values.items():
165+
if k not in query_params_json:
166+
query_params_json[k] = v
205167

206168
if rest_numeric_enums:
207169
query_params_json["$alt"] = "json;enum-encoding=int"

packages/google-api-core/tests/unit/test_rest_helpers.py

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -278,84 +278,3 @@ def test_transcode_request_proto_plus_wrapper():
278278
assert transcoded["uri"] == "/v1/test/proto-plus-field"
279279

280280

281-
def test_transcode_with_required_fields_in_path():
282-
http_options = [{"method": "get", "uri": "/v1/test/{name}"}]
283-
request = descriptor_pb2.FieldDescriptorProto()
284-
request.name = "my-name"
285-
286-
required_defaults = {"name": "default-name", "filter": "default-filter"}
287-
transcoded, _, query_params = transcode_request(
288-
http_options, request, required_fields_default_values=required_defaults
289-
)
290-
291-
assert transcoded["uri"] == "/v1/test/my-name"
292-
assert "name" not in query_params
293-
assert query_params["filter"] == "default-filter"
294-
295-
296-
def test_transcode_with_required_fields_in_body():
297-
http_options = [{"method": "post", "uri": "/v1/test", "body": "*"}]
298-
request = descriptor_pb2.FieldDescriptorProto()
299-
request.name = "my-name"
300-
301-
required_defaults = {"name": "default-name"}
302-
_, body, query_params = transcode_request(
303-
http_options, request, required_fields_default_values=required_defaults
304-
)
305-
306-
assert body is not None
307-
assert "name" not in query_params
308-
assert query_params == {}
309-
310-
311-
def test_transcode_with_required_fields_in_body_param():
312-
http_options = [{"method": "post", "uri": "/v1/test/{name}", "body": "options"}]
313-
request = descriptor_pb2.FieldDescriptorProto()
314-
request.name = "my-name"
315-
316-
required_defaults = {
317-
"options": "default-options",
318-
"filter": "default-filter",
319-
}
320-
transcoded, body, query_params = transcode_request(
321-
http_options, request, required_fields_default_values=required_defaults
322-
)
323-
324-
assert transcoded["uri"] == "/v1/test/my-name"
325-
assert "options" not in query_params
326-
assert query_params["filter"] == "default-filter"
327-
328-
329-
def test_transcode_required_fields_no_matching_option():
330-
http_options = [{"method": "get", "uri": "/v1/test"}]
331-
request = descriptor_pb2.FieldDescriptorProto()
332-
required_defaults = {"name": "default-name"}
333-
334-
with mock.patch(
335-
"google.api_core.path_template.transcode",
336-
return_value={"method": "delete", "uri": "/v1/test"},
337-
):
338-
_, _, query_params = transcode_request(
339-
http_options, request, required_fields_default_values=required_defaults
340-
)
341-
assert query_params["name"] == "default-name"
342-
343-
344-
def test_transcode_required_fields_uri_mismatch():
345-
http_options = [
346-
{"method": "get", "uri": "/v1/wrong_path/{name}"},
347-
{"method": "get", "uri": "/v1/test/{name}"},
348-
]
349-
request = descriptor_pb2.FieldDescriptorProto()
350-
request.name = "my-name"
351-
required_defaults = {"name": "default-name", "filter": "default-filter"}
352-
353-
with mock.patch(
354-
"google.api_core.path_template.transcode",
355-
return_value={"method": "get", "uri": "/v1/test/my-name"},
356-
):
357-
transcoded, _, query_params = transcode_request(
358-
http_options, request, required_fields_default_values=required_defaults
359-
)
360-
assert "name" not in query_params
361-
assert query_params["filter"] == "default-filter"

0 commit comments

Comments
 (0)