Skip to content

Commit 52f3575

Browse files
authored
feat: Add REST Interceptors to support reading metadata (#2299)
1 parent b3fe7a2 commit 52f3575

File tree

13 files changed

+1788
-132
lines changed

13 files changed

+1788
-132
lines changed

packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/services/%service/_shared_macros.j2

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,13 +383,36 @@ class {{ async_method_name_prefix }}{{ service.name }}RestInterceptor:
383383
{% endif %}
384384
"""Post-rpc interceptor for {{ method.name|snake_case }}
385385

386-
Override in a subclass to manipulate the response
386+
DEPRECATED. Please use the `post_{{ method.name|snake_case }}_with_metadata`
387+
interceptor instead.
388+
389+
Override in a subclass to read or manipulate the response
387390
after it is returned by the {{ service.name }} server but before
388-
it is returned to user code.
391+
it is returned to user code. This `post_{{ method.name|snake_case }}` interceptor runs
392+
before the `post_{{ method.name|snake_case }}_with_metadata` interceptor.
389393
"""
390394
return response
391395

396+
{% if not method.server_streaming %}
397+
{{ async_prefix }}def post_{{ method.name|snake_case }}_with_metadata(self, response: {{method.output.ident}}, {{ client_method_metadata_argument() }}) -> Tuple[{{method.output.ident}}, {{ client_method_metadata_type() }}]:
398+
{% else %}
399+
{{ async_prefix }}def post_{{ method.name|snake_case }}_with_metadata(self, response: rest_streaming{{ async_suffix }}.{{ async_method_name_prefix }}ResponseIterator, {{ client_method_metadata_argument() }}) -> Tuple[rest_streaming{{ async_suffix }}.{{ async_method_name_prefix }}ResponseIterator, {{ client_method_metadata_type() }}]:
392400
{% endif %}
401+
"""Post-rpc interceptor for {{ method.name|snake_case }}
402+
403+
Override in a subclass to read or manipulate the response or metadata after it
404+
is returned by the {{ service.name }} server but before it is returned to user code.
405+
406+
We recommend only using this `post_{{ method.name|snake_case }}_with_metadata`
407+
interceptor in new development instead of the `post_{{ method.name|snake_case }}` interceptor.
408+
When both interceptors are used, this `post_{{ method.name|snake_case }}_with_metadata` interceptor runs after the
409+
`post_{{ method.name|snake_case }}` interceptor. The (possibly modified) response returned by
410+
`post_{{ method.name|snake_case }}` will be passed to
411+
`post_{{ method.name|snake_case }}_with_metadata`.
412+
"""
413+
return response, metadata
414+
415+
{% endif %}{# not method.void #}
393416
{% endfor %}
394417

395418
{% for name, signature in api.mixin_api_signatures.items() %}

packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/rest.py.j2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ class {{service.name}}RestTransport(_Base{{ service.name }}RestTransport):
256256
{% endif %}{# method.lro #}
257257
{#- TODO(https://github.com/googleapis/gapic-generator-python/issues/2274): Add debug log before intercepting a request #}
258258
resp = self._interceptor.post_{{ method.name|snake_case }}(resp)
259+
response_metadata = [(k, str(v)) for k, v in response.headers.items()]
260+
resp, _ = self._interceptor.post_{{ method.name|snake_case }}_with_metadata(resp, response_metadata)
259261
{# TODO(https://github.com/googleapis/gapic-generator-python/issues/2279): Add logging support for rest streaming. #}
260262
{% if not method.server_streaming %}
261263
if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(logging.DEBUG): # pragma: NO COVER

packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/services/%service/transports/rest_asyncio.py.j2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ class Async{{service.name}}RestTransport(_Base{{ service.name }}RestTransport):
217217
json_format.Parse(content, pb_resp, ignore_unknown_fields=True)
218218
{% endif %}{# if method.server_streaming #}
219219
resp = await self._interceptor.post_{{ method.name|snake_case }}(resp)
220+
response_metadata = [(k, str(v)) for k, v in response.headers.items()]
221+
resp, _ = await self._interceptor.post_{{ method.name|snake_case }}_with_metadata(resp, response_metadata)
220222
{# TODO(https://github.com/googleapis/gapic-generator-python/issues/2279): Add logging support for rest streaming. #}
221223
{% if not method.server_streaming %}
222224
if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(logging.DEBUG): # pragma: NO COVER

packages/gapic-generator/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_macros.j2

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2218,11 +2218,13 @@ def test_initialize_client_w_{{transport_name}}():
22182218
{% endif %}
22192219
{% if not method.void %}
22202220
mock.patch.object(transports.{{async_method_prefix}}{{ service.name }}RestInterceptor, "post_{{method.name|snake_case}}") as post, \
2221+
mock.patch.object(transports.{{async_method_prefix}}{{ service.name }}RestInterceptor, "post_{{method.name|snake_case}}_with_metadata") as post_with_metadata, \
22212222
{% endif %}
22222223
mock.patch.object(transports.{{async_method_prefix}}{{ service.name }}RestInterceptor, "pre_{{ method.name|snake_case }}") as pre:
22232224
pre.assert_not_called()
22242225
{% if not method.void %}
22252226
post.assert_not_called()
2227+
post_with_metadata.assert_not_called()
22262228
{% endif %}
22272229
{% if method.input.ident.is_proto_plus_type %}
22282230
pb_message = {{ method.input.ident }}.pb({{ method.input.ident }}())
@@ -2265,13 +2267,15 @@ def test_initialize_client_w_{{transport_name}}():
22652267
pre.return_value = request, metadata
22662268
{% if not method.void %}
22672269
post.return_value = {{ method.output.ident }}()
2270+
post_with_metadata.return_value = {{ method.output.ident }}(), metadata
22682271
{% endif %}
22692272

22702273
{{await_prefix}}client.{{ method_name }}(request, metadata=[("key", "val"), ("cephalopod", "squid"),])
22712274

22722275
pre.assert_called_once()
22732276
{% if not method.void %}
22742277
post.assert_called_once()
2278+
post_with_metadata.assert_called_once()
22752279
{% endif %}
22762280
{% endif %}{# end 'grpc' in transport #}
22772281
{% endmacro%}{# inteceptor_class_test #}

0 commit comments

Comments
 (0)