Skip to content

Commit fdb83f7

Browse files
committed
fix(api-core): filter bound path and body fields from required fields in query params
1 parent d9f591b commit fdb83f7

2 files changed

Lines changed: 56 additions & 3 deletions

File tree

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

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,33 @@ def transcode_request(
160160
)
161161

162162
if required_fields_default_values:
163-
for k, v in required_fields_default_values.items():
164-
if k not in query_params_json:
165-
query_params_json[k] = v
163+
matched_option = None
164+
for option in http_options:
165+
if option.get("method", "").lower() == transcoded_request.get("method", "").lower():
166+
if path_template.validate(option.get("uri", ""), transcoded_request.get("uri", "")):
167+
matched_option = option
168+
break
169+
170+
bound_fields = set()
171+
if matched_option:
172+
uri_template = matched_option.get("uri", "")
173+
for m in path_template._VARIABLE_RE.finditer(uri_template):
174+
name = m.group("name")
175+
if name:
176+
bound_fields.add(name.split(".")[0])
177+
body_param = matched_option.get("body")
178+
if body_param:
179+
if body_param == "*":
180+
bound_fields = None
181+
else:
182+
bound_fields.add(body_param.split(".")[0])
183+
184+
if bound_fields is not None:
185+
for k, v in required_fields_default_values.items():
186+
if k in bound_fields:
187+
continue
188+
if k not in query_params_json:
189+
query_params_json[k] = v
166190

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

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,32 @@ def test_transcode_request_proto_plus_wrapper():
276276

277277
transcoded, _, _ = transcode_request(http_options, mock_proto_plus)
278278
assert transcoded["uri"] == "/v1/test/proto-plus-field"
279+
280+
281+
def test_transcode_required_fields_bound_to_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_required_fields_bound_to_body_star():
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 query_params == {}

0 commit comments

Comments
 (0)