diff --git a/gapic/schema/api.py b/gapic/schema/api.py index e303db8d88..a0c878517c 100644 --- a/gapic/schema/api.py +++ b/gapic/schema/api.py @@ -460,7 +460,7 @@ def __init__( else: raise TypeError( f"Unknown type referenced in " - "{self.file_descriptor.name}: '{key}'" + f"{self.file_descriptor.name}: '{key}'" ) # Only generate the service if this is a target file to be generated. diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index 68ec4e2316..8fc4b8d712 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1012,7 +1012,7 @@ def names(self) -> FrozenSet[str]: @utils.cached_property def resource_messages(self) -> FrozenSet[MessageType]: """Returns all the resource message types used in all - request fields in the service.""" + request and response fields in the service.""" def gen_resources(message): if message.resource_path: yield message @@ -1022,9 +1022,14 @@ def gen_resources(message): yield type_ return frozenset( - resource_msg + msg for method in self.methods.values() - for resource_msg in gen_resources(method.input) + for msg in chain( + gen_resources(method.input), + gen_resources( + method.lro.response_type if method.lro else method.output + ), + ) ) @utils.cached_property diff --git a/gapic/templates/%namespace/%name_%version/%sub/services/%service/client.py.j2 b/gapic/templates/%namespace/%name_%version/%sub/services/%service/client.py.j2 index d709792514..67cb2856d6 100644 --- a/gapic/templates/%namespace/%name_%version/%sub/services/%service/client.py.j2 +++ b/gapic/templates/%namespace/%name_%version/%sub/services/%service/client.py.j2 @@ -137,6 +137,7 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta): """Parse a {{ message.resource_type|snake_case }} path into its component segments.""" m = re.match(r"{{ message.path_regex_str }}", path) return m.groupdict() if m else {} + {% endfor %} {# resources #} {% for resource_msg in service.common_resources|sort(attribute="type_name") -%} @staticmethod diff --git a/noxfile.py b/noxfile.py index abaef7fa0c..47880e3d1c 100644 --- a/noxfile.py +++ b/noxfile.py @@ -37,13 +37,18 @@ def unit(session): session.run( "py.test", - "-vv", - "-n=auto", - "--cov=gapic", - "--cov-config=.coveragerc", - "--cov-report=term", - "--cov-report=html", - *(session.posargs or [path.join("tests", "unit")]), + *( + session.posargs + or [ + "-vv", + "-n=auto", + "--cov=gapic", + "--cov-config=.coveragerc", + "--cov-report=term", + "--cov-report=html", + path.join("tests", "unit"), + ] + ), ) diff --git a/tests/unit/schema/wrappers/test_service.py b/tests/unit/schema/wrappers/test_service.py index d733d1fa2d..28c7cbe5e7 100644 --- a/tests/unit/schema/wrappers/test_service.py +++ b/tests/unit/schema/wrappers/test_service.py @@ -32,6 +32,24 @@ make_service_with_method_options, ) +################################ +# Helper Functions +################################ + + +def make_resource_opts(*args): + # Resources are labeled via an options extension + opts = descriptor_pb2.MessageOptions() + opts.Extensions[resource_pb2.resource].pattern.append( + "/".join("{{{arg}}}/{arg}" for arg in args) + ) + return opts + + +################################ +# End Helper Functions +################################ + def test_service_properties(): service = make_service(name='ThingDoer') @@ -162,14 +180,6 @@ def test_module_name(): def test_resource_messages(): - # Resources are labeled via an options extension - def make_resource_opts(*args): - opts = descriptor_pb2.MessageOptions() - opts.Extensions[resource_pb2.resource].pattern.append( - "/".join("{{{arg}}}/{arg}" for arg in args) - ) - return opts - # Regular, top level resource squid_resource = make_message("Squid", options=make_resource_opts("squid")) squid_request = make_message( @@ -336,3 +346,34 @@ def test_common_resource_patterns(): assert species_msg.resource_type == "Species" assert species_msg.resource_path_args == ["family", "genus", "species"] assert species_msg.path_regex_str == '^families/(?P.+?)/genera/(?P.+?)/species/(?P.+?)$' + + +def test_resource_response(): + # Top level response resource + squid_resource = make_message("Squid", options=make_resource_opts("squid")) + squid_request = make_message("CreateSquidRequest") + + # Nested response resource + clam_resource = make_message("Clam", options=make_resource_opts("clam")) + clam_response = make_message( + "CreateClamResponse", + fields=( + make_field('clam', message=clam_resource), + ), + ) + clam_request = make_message("CreateClamRequest") + + mollusc_service = make_service( + "MolluscService", + methods=( + make_method(f"{request.name}", request, response) + for request, response in ( + (squid_request, squid_resource), + (clam_request, clam_response), + ) + ), + ) + + expected = {squid_resource, clam_resource} + actual = mollusc_service.resource_messages + assert expected == actual