From a9ce28840ddfec712da5b296f43e6c3131840db4 Mon Sep 17 00:00:00 2001 From: Martin Boisvert Date: Tue, 22 Dec 2020 15:56:02 -0500 Subject: [PATCH] fix: Generate gRPC files for long-running operations (#13) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #12 🦕 (My automatic whitespace formatter removed some trailing whitespace, is this an issue?) Note that I'm not entirely sure how to work with synthtool, and so I couldn't figure out how to get the license header and formatting fixed before committing the files generated by `nox -s generate_protos`. Someone else is going to have to do that part for me 🙂 Still, the generated grpc file looks good. --- google/longrunning/operations_grpc_pb2.py | 48 +--- google/longrunning/operations_pb2_grpc.py | 282 +++++++++++++++++++++ google/longrunning/operations_proto_pb2.py | 33 ++- noxfile.py | 20 +- 4 files changed, 335 insertions(+), 48 deletions(-) create mode 100644 google/longrunning/operations_pb2_grpc.py diff --git a/google/longrunning/operations_grpc_pb2.py b/google/longrunning/operations_grpc_pb2.py index f3b880c..e2dbf60 100644 --- a/google/longrunning/operations_grpc_pb2.py +++ b/google/longrunning/operations_grpc_pb2.py @@ -1,44 +1,6 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/longrunning/operations.proto -from google.longrunning.operations_proto_pb2 import * -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 - - -class OperationsStub(object): - """Manages long-running operations with an API service. +# This module is provided for backwards compatibility with +# googleapis-common-protos <= 1.52.0, where this import path contained +# all of the message and gRPC definitions. - When an API method normally takes long time to complete, it can be designed - to return [Operation][google.longrunning.Operation] to the client, and the client can use this - interface to receive the real response asynchronously by polling the - operation resource, or pass the operation resource to another API (such as - Google Cloud Pub/Sub API) to receive the response. Any API service that - returns long-running operations should implement the `Operations` interface - so developers can have a consistent client experience. - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetOperation = channel.unary_unary( - "/google.longrunning.Operations/GetOperation", - request_serializer=GetOperationRequest.SerializeToString, - response_deserializer=Operation.FromString, - ) - self.ListOperations = channel.unary_unary( - "/google.longrunning.Operations/ListOperations", - request_serializer=ListOperationsRequest.SerializeToString, - response_deserializer=ListOperationsResponse.FromString, - ) - self.CancelOperation = channel.unary_unary( - "/google.longrunning.Operations/CancelOperation", - request_serializer=CancelOperationRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.DeleteOperation = channel.unary_unary( - "/google.longrunning.Operations/DeleteOperation", - request_serializer=DeleteOperationRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) +from google.longrunning.operations_proto_pb2 import * +from google.longrunning.operations_pb2_grpc import * diff --git a/google/longrunning/operations_pb2_grpc.py b/google/longrunning/operations_pb2_grpc.py new file mode 100644 index 0000000..6d06584 --- /dev/null +++ b/google/longrunning/operations_pb2_grpc.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from google.longrunning import ( + operations_proto_pb2 as google_dot_longrunning_dot_operations__pb2, +) +from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 + + +class OperationsStub(object): + """Manages long-running operations with an API service. + + When an API method normally takes long time to complete, it can be designed + to return [Operation][google.longrunning.Operation] to the client, and the client can use this + interface to receive the real response asynchronously by polling the + operation resource, or pass the operation resource to another API (such as + Google Cloud Pub/Sub API) to receive the response. Any API service that + returns long-running operations should implement the `Operations` interface + so developers can have a consistent client experience. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.ListOperations = channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=google_dot_longrunning_dot_operations__pb2.ListOperationsRequest.SerializeToString, + response_deserializer=google_dot_longrunning_dot_operations__pb2.ListOperationsResponse.FromString, + ) + self.GetOperation = channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=google_dot_longrunning_dot_operations__pb2.GetOperationRequest.SerializeToString, + response_deserializer=google_dot_longrunning_dot_operations__pb2.Operation.FromString, + ) + self.DeleteOperation = channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=google_dot_longrunning_dot_operations__pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + ) + self.CancelOperation = channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=google_dot_longrunning_dot_operations__pb2.CancelOperationRequest.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + ) + + +class OperationsServicer(object): + """Manages long-running operations with an API service. + + When an API method normally takes long time to complete, it can be designed + to return [Operation][google.longrunning.Operation] to the client, and the client can use this + interface to receive the real response asynchronously by polling the + operation resource, or pass the operation resource to another API (such as + Google Cloud Pub/Sub API) to receive the response. Any API service that + returns long-running operations should implement the `Operations` interface + so developers can have a consistent client experience. + """ + + def ListOperations(self, request, context): + """Lists operations that match the specified filter in the request. If the + server doesn't support this method, it returns `UNIMPLEMENTED`. + + NOTE: the `name` binding below allows API services to override the binding + to use different resource name schemes, such as `users/*/operations`. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def GetOperation(self, request, context): + """Gets the latest state of a long-running operation. Clients can use this + method to poll the operation result at intervals as recommended by the API + service. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def DeleteOperation(self, request, context): + """Deletes a long-running operation. This method indicates that the client is + no longer interested in the operation result. It does not cancel the + operation. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def CancelOperation(self, request, context): + """Starts asynchronous cancellation on a long-running operation. The server + makes a best effort to cancel the operation, but success is not + guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. Clients can use + [Operations.GetOperation][google.longrunning.Operations.GetOperation] or + other methods to check whether the cancellation succeeded or whether the + operation completed despite cancellation. On successful cancellation, + the operation is not deleted; instead, it becomes an operation with + an [Operation.error][google.longrunning.Operation.error] value with a [google.rpc.Status.code][google.rpc.Status.code] of 1, + corresponding to `Code.CANCELLED`. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + +def add_OperationsServicer_to_server(servicer, server): + rpc_method_handlers = { + "ListOperations": grpc.unary_unary_rpc_method_handler( + servicer.ListOperations, + request_deserializer=google_dot_longrunning_dot_operations__pb2.ListOperationsRequest.FromString, + response_serializer=google_dot_longrunning_dot_operations__pb2.ListOperationsResponse.SerializeToString, + ), + "GetOperation": grpc.unary_unary_rpc_method_handler( + servicer.GetOperation, + request_deserializer=google_dot_longrunning_dot_operations__pb2.GetOperationRequest.FromString, + response_serializer=google_dot_longrunning_dot_operations__pb2.Operation.SerializeToString, + ), + "DeleteOperation": grpc.unary_unary_rpc_method_handler( + servicer.DeleteOperation, + request_deserializer=google_dot_longrunning_dot_operations__pb2.DeleteOperationRequest.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), + "CancelOperation": grpc.unary_unary_rpc_method_handler( + servicer.CancelOperation, + request_deserializer=google_dot_longrunning_dot_operations__pb2.CancelOperationRequest.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + "google.longrunning.Operations", rpc_method_handlers + ) + server.add_generic_rpc_handlers((generic_handler,)) + + +# This class is part of an EXPERIMENTAL API. +class Operations(object): + """Manages long-running operations with an API service. + + When an API method normally takes long time to complete, it can be designed + to return [Operation][google.longrunning.Operation] to the client, and the client can use this + interface to receive the real response asynchronously by polling the + operation resource, or pass the operation resource to another API (such as + Google Cloud Pub/Sub API) to receive the response. Any API service that + returns long-running operations should implement the `Operations` interface + so developers can have a consistent client experience. + """ + + @staticmethod + def ListOperations( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.longrunning.Operations/ListOperations", + google_dot_longrunning_dot_operations__pb2.ListOperationsRequest.SerializeToString, + google_dot_longrunning_dot_operations__pb2.ListOperationsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetOperation( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.longrunning.Operations/GetOperation", + google_dot_longrunning_dot_operations__pb2.GetOperationRequest.SerializeToString, + google_dot_longrunning_dot_operations__pb2.Operation.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DeleteOperation( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.longrunning.Operations/DeleteOperation", + google_dot_longrunning_dot_operations__pb2.DeleteOperationRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def CancelOperation( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.longrunning.Operations/CancelOperation", + google_dot_longrunning_dot_operations__pb2.CancelOperationRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/google/longrunning/operations_proto_pb2.py b/google/longrunning/operations_proto_pb2.py index cdb1f94..080038f 100644 --- a/google/longrunning/operations_proto_pb2.py +++ b/google/longrunning/operations_proto_pb2.py @@ -16,7 +16,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/longrunning/operations.proto - +"""Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -39,6 +39,7 @@ package="google.longrunning", syntax="proto3", serialized_options=b"\n\026com.google.longrunningB\017OperationsProtoP\001Z=google.golang.org/genproto/googleapis/longrunning;longrunning\252\002\022Google.LongRunning\312\002\022Google\\LongRunning", + create_key=_descriptor._internal_create_key, serialized_pb=b'\n#google/longrunning/operations.proto\x12\x12google.longrunning\x1a\x1cgoogle/api/annotations.proto\x1a\x19google/protobuf/any.proto\x1a google/protobuf/descriptor.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x17google/rpc/status.proto"\xa8\x01\n\tOperation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x08metadata\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any\x12\x0c\n\x04\x64one\x18\x03 \x01(\x08\x12#\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x12.google.rpc.StatusH\x00\x12(\n\x08response\x18\x05 \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x42\x08\n\x06result"#\n\x13GetOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"\\\n\x15ListOperationsRequest\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x01 \x01(\t\x12\x11\n\tpage_size\x18\x02 \x01(\x05\x12\x12\n\npage_token\x18\x03 \x01(\t"d\n\x16ListOperationsResponse\x12\x31\n\noperations\x18\x01 \x03(\x0b\x32\x1d.google.longrunning.Operation\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t"&\n\x16\x43\x61ncelOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"&\n\x16\x44\x65leteOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"=\n\rOperationInfo\x12\x15\n\rresponse_type\x18\x01 \x01(\t\x12\x15\n\rmetadata_type\x18\x02 \x01(\t2\x8c\x04\n\nOperations\x12\x86\x01\n\x0eListOperations\x12).google.longrunning.ListOperationsRequest\x1a*.google.longrunning.ListOperationsResponse"\x1d\x82\xd3\xe4\x93\x02\x17\x12\x15/v1/{name=operations}\x12x\n\x0cGetOperation\x12\'.google.longrunning.GetOperationRequest\x1a\x1d.google.longrunning.Operation" \x82\xd3\xe4\x93\x02\x1a\x12\x18/v1/{name=operations/**}\x12w\n\x0f\x44\x65leteOperation\x12*.google.longrunning.DeleteOperationRequest\x1a\x16.google.protobuf.Empty" \x82\xd3\xe4\x93\x02\x1a*\x18/v1/{name=operations/**}\x12\x81\x01\n\x0f\x43\x61ncelOperation\x12*.google.longrunning.CancelOperationRequest\x1a\x16.google.protobuf.Empty"*\x82\xd3\xe4\x93\x02$"\x1f/v1/{name=operations/**}:cancel:\x01*:Z\n\x0eoperation_info\x12\x1e.google.protobuf.MethodOptions\x18\x99\x08 \x01(\x0b\x32!.google.longrunning.OperationInfoB\x94\x01\n\x16\x63om.google.longrunningB\x0fOperationsProtoP\x01Z=google.golang.org/genproto/googleapis/longrunning;longrunning\xaa\x02\x12Google.LongRunning\xca\x02\x12Google\\LongRunningb\x06proto3', dependencies=[ google_dot_api_dot_annotations__pb2.DESCRIPTOR, @@ -68,6 +69,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ) @@ -77,6 +79,7 @@ filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name="name", @@ -95,6 +98,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), _descriptor.FieldDescriptor( name="metadata", @@ -113,6 +117,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), _descriptor.FieldDescriptor( name="done", @@ -131,6 +136,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), _descriptor.FieldDescriptor( name="error", @@ -149,6 +155,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), _descriptor.FieldDescriptor( name="response", @@ -167,6 +174,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), ], extensions=[], @@ -182,6 +190,7 @@ full_name="google.longrunning.Operation.result", index=0, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[], ) ], @@ -196,6 +205,7 @@ filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name="name", @@ -214,6 +224,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ) ], extensions=[], @@ -235,6 +246,7 @@ filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name="name", @@ -253,6 +265,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), _descriptor.FieldDescriptor( name="filter", @@ -271,6 +284,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), _descriptor.FieldDescriptor( name="page_size", @@ -289,6 +303,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), _descriptor.FieldDescriptor( name="page_token", @@ -307,6 +322,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), ], extensions=[], @@ -328,6 +344,7 @@ filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name="operations", @@ -346,6 +363,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), _descriptor.FieldDescriptor( name="next_page_token", @@ -364,6 +382,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), ], extensions=[], @@ -385,6 +404,7 @@ filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name="name", @@ -403,6 +423,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ) ], extensions=[], @@ -424,6 +445,7 @@ filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name="name", @@ -442,6 +464,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ) ], extensions=[], @@ -463,6 +486,7 @@ filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name="response_type", @@ -481,6 +505,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), _descriptor.FieldDescriptor( name="metadata_type", @@ -499,6 +524,7 @@ extension_scope=None, serialized_options=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, ), ], extensions=[], @@ -627,6 +653,7 @@ file=DESCRIPTOR, index=0, serialized_options=None, + create_key=_descriptor._internal_create_key, serialized_start=752, serialized_end=1276, methods=[ @@ -638,6 +665,7 @@ input_type=_LISTOPERATIONSREQUEST, output_type=_LISTOPERATIONSRESPONSE, serialized_options=b"\202\323\344\223\002\027\022\025/v1/{name=operations}", + create_key=_descriptor._internal_create_key, ), _descriptor.MethodDescriptor( name="GetOperation", @@ -647,6 +675,7 @@ input_type=_GETOPERATIONREQUEST, output_type=_OPERATION, serialized_options=b"\202\323\344\223\002\032\022\030/v1/{name=operations/**}", + create_key=_descriptor._internal_create_key, ), _descriptor.MethodDescriptor( name="DeleteOperation", @@ -656,6 +685,7 @@ input_type=_DELETEOPERATIONREQUEST, output_type=google_dot_protobuf_dot_empty__pb2._EMPTY, serialized_options=b"\202\323\344\223\002\032*\030/v1/{name=operations/**}", + create_key=_descriptor._internal_create_key, ), _descriptor.MethodDescriptor( name="CancelOperation", @@ -665,6 +695,7 @@ input_type=_CANCELOPERATIONREQUEST, output_type=google_dot_protobuf_dot_empty__pb2._EMPTY, serialized_options=b'\202\323\344\223\002$"\037/v1/{name=operations/**}:cancel:\001*', + create_key=_descriptor._internal_create_key, ), ], ) diff --git a/noxfile.py b/noxfile.py index 3db30ee..956ffb1 100644 --- a/noxfile.py +++ b/noxfile.py @@ -114,7 +114,7 @@ def test(session, library): To verify that any changes we make here will not break downstream libraries, clone a few and run their unit and system tests. - NOTE: The unit and system test functions above are copied from the templates. + NOTE: The unit and system test functions above are copied from the templates. They will need to be updated when the templates change. * Pub/Sub: GAPIC with handwritten layer. @@ -148,12 +148,12 @@ def generate_protos(session): """Generates the protos using protoc. This session but be last to avoid overwriting the protos used in CI runs. - + Some notes on the `google` directory: - 1. The `_pb2.py` files are produced by protoc. + 1. The `_pb2.py` files are produced by protoc. 2. The .proto files are non-functional but are left in the repository to make it easier to understand diffs. - 3. The `google` directory also has `__init__.py` files to create proper modules. + 3. The `google` directory also has `__init__.py` files to create proper modules. If a new subdirectory is added, you will need to create more `__init__.py` files. """ @@ -171,6 +171,18 @@ def generate_protos(session): "python", "-m", "grpc_tools.protoc", "--proto_path=.", "--python_out=.", *protos ) + # Some files contain service definitions for which `_pb2_grpc.py` files must be generated. + service_protos = ["google/longrunning/operations.proto"] + session.run( + "python", "-m", "grpc_tools.protoc", "--proto_path=.", "--grpc_python_out=.", *service_protos + ) + + # More LRO non-standard fixes: rename the file and fix the import statement + operations_grpc_py = Path("google/longrunning/operations_pb2_grpc.py") + file_contents = operations_grpc_py.read_text() + file_contents = file_contents.replace("operations_pb2", "operations_proto_pb2") + operations_grpc_py.write_text(file_contents) + # Clean up LRO directory os.replace( "google/longrunning/operations_pb2.py",