Skip to content

Commit

Permalink
feat: Support field presence for query parameters in REST clients (#866)
Browse files Browse the repository at this point in the history
Also fix witespace issues in rest transport ands tests.
Also update bazel-specific dependencies.
  • Loading branch information
vam-google authored May 7, 2021
1 parent 99633a4 commit 5339db1
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class {{ service.name }}RestTransport({{ service.name }}Transport):
client_info=client_info,
)
self._session = AuthorizedSession(self._credentials, default_host=self.DEFAULT_HOST)
{%- if service.has_lro %}
{% if service.has_lro %}
self._operations_client = None
{% endif %}
if client_cert_source_for_mtls:
Expand Down Expand Up @@ -133,10 +133,10 @@ class {{ service.name }}RestTransport({{ service.name }}Transport):
request: {{ method.input.ident }}, *,
metadata: Sequence[Tuple[str, str]] = (),
) -> {{ method.output.ident }}:
r"""Call the {{ ' ' }}
r"""Call the {{- ' ' -}}
{{ (method.name|snake_case).replace('_',' ')|wrap(
width=70, offset=45, indent=8) }}
{{ ' ' }} method over HTTP.
{{- ' ' -}} method over HTTP.

Args:
request (~.{{ method.input.ident }}):
Expand Down Expand Up @@ -189,21 +189,26 @@ class {{ service.name }}RestTransport({{ service.name }}Transport):
#}
# TODO(yon-mg): handle nested fields corerctly rather than using only top level fields
# not required for GCE
query_params = {
{% for field in method.query_params | sort%}
'{{ field|camel_case }}': request.{{ field }},
{% endfor %}
}
query_params = {}
{% for field in method.query_params | sort%}
{% if method.input.fields[field].proto3_optional %}
if {{ method.input.ident }}.{{ field }} in request:
query_params['{{ field|camel_case }}'] = request.{{ field }}
{% else %}
query_params['{{ field|camel_case }}'] = request.{{ field }}
{% endif %}
{% endfor %}

# TODO(yon-mg): further discussion needed whether 'python truthiness' is appropriate here
# discards default values
# TODO(yon-mg): add test for proper url encoded strings
query_params = ['{k}={v}'.format(k=k, v=v) for k, v in query_params.items() if v]
url += '?{}'.format('&'.join(query_params)).replace(' ', '+')

# Send the request
{% if not method.void %}response = {% endif %}self._session.{{ method.http_opt['verb'] }}(
url
{% if 'body' in method.http_opt %},
response = self._session.{{ method.http_opt['verb'] }}(
url,
{% if 'body' in method.http_opt %}
data=body,
{% endif %}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1189,7 +1189,11 @@ def test_{{ method.name|snake_case }}_rest_flattened():
{% endfor %}
client.{{ method.name|snake_case }}(
{% for field in method.flattened_fields.values() %}
{% if field.field_pb is msg_field_pb %}{{ field.name }}={{ field.name }},{% else %}{{ field.name }}={{ field.mock_value }},{% endif %}
{% if field.field_pb is msg_field_pb %}
{{ field.name }}={{ field.name }},
{% else %}
{{ field.name }}={{ field.mock_value }},
{% endif %}
{% endfor %}
)

Expand All @@ -1198,16 +1202,17 @@ def test_{{ method.name|snake_case }}_rest_flattened():
assert len(req.mock_calls) == 1
_, http_call, http_params = req.mock_calls[0]
body = http_params.get('data')
{% for key, field in method.flattened_fields.items() %}{% if not field.oneof or field.proto3_optional %}
{% for key, field in method.flattened_fields.items() %}
{% if not field.oneof or field.proto3_optional %}
{% if field.ident|string() == 'timestamp.Timestamp' %}
assert TimestampRule().to_proto(http_call[0].{{ key }}) == {{ field.mock_value }}
{% elif field.ident|string() == 'duration.Duration' %}
assert DurationRule().to_proto(http_call[0].{{ key }}) == {{ field.mock_value }}
{% else %}
assert {% if field.field_pb is msg_field_pb %}{{ field.ident }}.to_json({{ field.name }}, including_default_value_fields=False, use_integers_for_enums=False)
{% elif field.field_pb is str_field_pb %}{{ field.mock_value }}
{% else %}str({{ field.mock_value }})
{% endif %} in http_call[1] + str(body)
{%- elif field.field_pb is str_field_pb %}{{ field.mock_value }}
{%- else %}str({{ field.mock_value }})
{%- endif %} in http_call[1] + str(body)
{% endif %}
{% endif %}{% endfor %}

Expand Down
6 changes: 3 additions & 3 deletions repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def gapic_generator_python():
requirements = "@gapic_generator_python//:requirements.txt",
)

_protobuf_version = "3.14.0"
_protobuf_version = "3.15.8"
_protobuf_version_in_link = "v%s" % _protobuf_version
_maybe(
http_archive,
Expand All @@ -34,8 +34,8 @@ def gapic_generator_python():
_maybe(
http_archive,
name = "com_github_grpc_grpc",
strip_prefix = "grpc-8347f4753568b5b66e49111c60ae2841278d3f33", # this is 1.25.0 with fixes
urls = ["https://github.com/grpc/grpc/archive/8347f4753568b5b66e49111c60ae2841278d3f33.zip"],
strip_prefix = "grpc-1.36.4",
urls = ["https://github.com/grpc/grpc/archive/v1.36.4.zip"],
)

_maybe(
Expand Down

0 comments on commit 5339db1

Please sign in to comment.