diff --git a/packages/google-cloud-run/google/cloud/run_v2/__init__.py b/packages/google-cloud-run/google/cloud/run_v2/__init__.py index a0d9033bd70f..f97f75814ca8 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/__init__.py +++ b/packages/google-cloud-run/google/cloud/run_v2/__init__.py @@ -25,9 +25,13 @@ from .types.k8s_min import ContainerPort from .types.k8s_min import EnvVar from .types.k8s_min import EnvVarSource +from .types.k8s_min import HTTPGetAction +from .types.k8s_min import HTTPHeader +from .types.k8s_min import Probe from .types.k8s_min import ResourceRequirements from .types.k8s_min import SecretKeySelector from .types.k8s_min import SecretVolumeSource +from .types.k8s_min import TCPSocketAction from .types.k8s_min import VersionToPath from .types.k8s_min import Volume from .types.k8s_min import VolumeMount @@ -69,11 +73,14 @@ "ExecutionEnvironment", "GetRevisionRequest", "GetServiceRequest", + "HTTPGetAction", + "HTTPHeader", "IngressTraffic", "ListRevisionsRequest", "ListRevisionsResponse", "ListServicesRequest", "ListServicesResponse", + "Probe", "ResourceRequirements", "Revision", "RevisionScaling", @@ -83,6 +90,7 @@ "SecretVolumeSource", "Service", "ServicesClient", + "TCPSocketAction", "TrafficTarget", "TrafficTargetAllocationType", "TrafficTargetStatus", diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/async_client.py b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/async_client.py index b00d9a371ec8..c5321620e799 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/async_client.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/async_client.py @@ -34,11 +34,13 @@ from google.api import launch_stage_pb2 # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.cloud.run_v2.services.revisions import pagers from google.cloud.run_v2.types import condition from google.cloud.run_v2.types import k8s_min from google.cloud.run_v2.types import revision from google.cloud.run_v2.types import vendor_settings +from google.longrunning import operations_pb2 from google.protobuf import duration_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore from .transports.base import RevisionsTransport, DEFAULT_CLIENT_INFO @@ -559,6 +561,169 @@ async def sample_delete_revision(): # Done; return the response. return response + async def list_operations( + self, + request: operations_pb2.ListOperationsRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: operations_pb2.GetOperationRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_operation( + self, + request: operations_pb2.DeleteOperationRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""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`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.delete_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + async def __aenter__(self): return self diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/client.py b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/client.py index 2ed4c32ae917..750c91213820 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/client.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/client.py @@ -37,11 +37,13 @@ from google.api import launch_stage_pb2 # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.cloud.run_v2.services.revisions import pagers from google.cloud.run_v2.types import condition from google.cloud.run_v2.types import k8s_min from google.cloud.run_v2.types import revision from google.cloud.run_v2.types import vendor_settings +from google.longrunning import operations_pb2 from google.protobuf import duration_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore from .transports.base import RevisionsTransport, DEFAULT_CLIENT_INFO @@ -929,6 +931,169 @@ def __exit__(self, type, value, traceback): """ self.transport.close() + def list_operations( + self, + request: operations_pb2.ListOperationsRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_operation( + self, + request: operations_pb2.GetOperationRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_operation( + self, + request: operations_pb2.DeleteOperationRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""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`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.delete_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/base.py b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/base.py index 6ee1fcbc3e39..020720edd01f 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/base.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/base.py @@ -26,7 +26,9 @@ from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.cloud.run_v2.types import revision +from google.longrunning import operations_pb2 from google.longrunning import operations_pb2 # type: ignore try: @@ -189,6 +191,33 @@ def delete_revision( ]: raise NotImplementedError() + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None,]: + raise NotImplementedError() + @property def kind(self) -> str: raise NotImplementedError() diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/grpc.py b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/grpc.py index ee2217cf5a57..7683b0e22ae9 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/grpc.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/grpc.py @@ -25,7 +25,9 @@ import grpc # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.cloud.run_v2.types import revision +from google.longrunning import operations_pb2 from google.longrunning import operations_pb2 # type: ignore from .base import RevisionsTransport, DEFAULT_CLIENT_INFO @@ -328,6 +330,59 @@ def delete_revision( def close(self): self.grpc_channel.close() + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + @property def kind(self) -> str: return "grpc" diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/grpc_asyncio.py b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/grpc_asyncio.py index cafd1589f908..060df613ab94 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/grpc_asyncio.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/grpc_asyncio.py @@ -25,7 +25,9 @@ import grpc # type: ignore from grpc.experimental import aio # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.cloud.run_v2.types import revision +from google.longrunning import operations_pb2 from google.longrunning import operations_pb2 # type: ignore from .base import RevisionsTransport, DEFAULT_CLIENT_INFO from .grpc import RevisionsGrpcTransport @@ -337,5 +339,58 @@ def delete_revision( def close(self): return self.grpc_channel.close() + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + __all__ = ("RevisionsGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/rest.py b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/rest.py index 6472f7230fee..d63d4ab46a60 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/rest.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/revisions/transports/rest.py @@ -28,6 +28,8 @@ from google.protobuf import json_format from google.api_core import operations_v1 +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 from requests import __version__ as requests_version import dataclasses import re @@ -160,6 +162,75 @@ def post_list_revisions( """ return response + def pre_delete_operation( + self, + request: operations_pb2.DeleteOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> None: + """Pre-rpc interceptor for delete_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Revisions server. + """ + return request, metadata + + def post_delete_operation( + self, response: operations_pb2.DeleteOperationRequest + ) -> None: + """Post-rpc interceptor for delete_operation + + Override in a subclass to manipulate the response + after it is returned by the Revisions server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> operations_pb2.Operation: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Revisions server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.GetOperationRequest + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the Revisions server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> operations_pb2.ListOperationsResponse: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the Revisions server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsRequest + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the Revisions server but before + it is returned to user code. + """ + return response + @dataclasses.dataclass class RevisionsRestStub: @@ -603,6 +674,203 @@ def list_revisions( # In C++ this would require a dynamic_cast return self._ListRevisions(self._session, self._host, self._interceptor) # type: ignore + @property + def delete_operation(self): + return self._DeleteOperation(self._session, self._host, self._interceptor) # type: ignore + + class _DeleteOperation(RevisionsRestStub): + def __call__( + self, + request: operations_pb2.DeleteOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + + r"""Call the delete operation method over HTTP. + + Args: + request (operations_pb2.DeleteOperationRequest): + The request object for DeleteOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2/{name=projects/*/locations/*/operations/*}", + }, + ] + + request, metadata = self._interceptor.pre_delete_operation( + request, metadata + ) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_delete_operation(None) + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(RevisionsRestStub): + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/operations/*}", + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(RevisionsRestStub): + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*}/operations", + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + @property def kind(self) -> str: return "rest" diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/services/async_client.py b/packages/google-cloud-run/google/cloud/run_v2/services/services/async_client.py index d79f71663563..37cbf5660ff3 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/services/async_client.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/services/async_client.py @@ -34,6 +34,7 @@ from google.api import launch_stage_pb2 # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.cloud.run_v2.services.services import pagers from google.cloud.run_v2.types import condition from google.cloud.run_v2.types import revision_template @@ -43,6 +44,7 @@ from google.cloud.run_v2.types import vendor_settings from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 from google.protobuf import timestamp_pb2 # type: ignore from .transports.base import ServicesTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import ServicesGrpcAsyncIOTransport @@ -265,10 +267,11 @@ async def sample_create_service(): The request object. Request message for creating a Service. parent (:class:`str`): - Required. The location and project in - which this service should be created. - Format: - projects/{projectnumber}/locations/{location} + The location and project in which + this service should be created. Format: + projects/{project}/locations/{location} + Only lowercase characters, digits, and + hyphens. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -281,9 +284,10 @@ async def sample_create_service(): on the ``request`` instance; if ``request`` is provided, this should not be set. service_id (:class:`str`): - Required. The unique identifier for the Service. The - name of the service becomes - {parent}/services/{service_id}. + Required. The unique identifier for the Service. It must + begin with letter, and may not end with hyphen; must + contain fewer than 50 characters. The name of the + service becomes {parent}/services/{service_id}. This corresponds to the ``service_id`` field on the ``request`` instance; if ``request`` is provided, this @@ -405,7 +409,7 @@ async def sample_get_service(): name (:class:`str`): Required. The full name of the Service. Format: - projects/{projectnumber}/locations/{location}/services/{service} + projects/{project}/locations/{location}/services/{service} This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -527,7 +531,7 @@ async def sample_list_services(): list resources on. Location must be a valid GCP region, and may not be the "-" wildcard. Format: - projects/{projectnumber}/locations/{location} + projects/{project}/locations/{location} This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -777,7 +781,7 @@ async def sample_delete_service(): name (:class:`str`): Required. The full name of the Service. Format: - projects/{projectnumber}/locations/{location}/services/{service} + projects/{project}/locations/{location}/services/{service} This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1226,6 +1230,169 @@ async def sample_test_iam_permissions(): # Done; return the response. return response + async def list_operations( + self, + request: operations_pb2.ListOperationsRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: operations_pb2.GetOperationRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_operation( + self, + request: operations_pb2.DeleteOperationRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""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`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.delete_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + async def __aenter__(self): return self diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/services/client.py b/packages/google-cloud-run/google/cloud/run_v2/services/services/client.py index 0ad702c0dc44..dc85114b656f 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/services/client.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/services/client.py @@ -37,6 +37,7 @@ from google.api import launch_stage_pb2 # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.cloud.run_v2.services.services import pagers from google.cloud.run_v2.types import condition from google.cloud.run_v2.types import revision_template @@ -46,6 +47,7 @@ from google.cloud.run_v2.types import vendor_settings from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 from google.protobuf import timestamp_pb2 # type: ignore from .transports.base import ServicesTransport, DEFAULT_CLIENT_INFO from .transports.grpc import ServicesGrpcTransport @@ -600,10 +602,11 @@ def sample_create_service(): The request object. Request message for creating a Service. parent (str): - Required. The location and project in - which this service should be created. - Format: - projects/{projectnumber}/locations/{location} + The location and project in which + this service should be created. Format: + projects/{project}/locations/{location} + Only lowercase characters, digits, and + hyphens. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -616,9 +619,10 @@ def sample_create_service(): on the ``request`` instance; if ``request`` is provided, this should not be set. service_id (str): - Required. The unique identifier for the Service. The - name of the service becomes - {parent}/services/{service_id}. + Required. The unique identifier for the Service. It must + begin with letter, and may not end with hyphen; must + contain fewer than 50 characters. The name of the + service becomes {parent}/services/{service_id}. This corresponds to the ``service_id`` field on the ``request`` instance; if ``request`` is provided, this @@ -748,7 +752,7 @@ def sample_get_service(): name (str): Required. The full name of the Service. Format: - projects/{projectnumber}/locations/{location}/services/{service} + projects/{project}/locations/{location}/services/{service} This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -869,7 +873,7 @@ def sample_list_services(): list resources on. Location must be a valid GCP region, and may not be the "-" wildcard. Format: - projects/{projectnumber}/locations/{location} + projects/{project}/locations/{location} This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -1124,7 +1128,7 @@ def sample_delete_service(): name (str): Required. The full name of the Service. Format: - projects/{projectnumber}/locations/{location}/services/{service} + projects/{project}/locations/{location}/services/{service} This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1591,6 +1595,169 @@ def __exit__(self, type, value, traceback): """ self.transport.close() + def list_operations( + self, + request: operations_pb2.ListOperationsRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_operation( + self, + request: operations_pb2.GetOperationRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_operation( + self, + request: operations_pb2.DeleteOperationRequest = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""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`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.delete_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/base.py b/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/base.py index 6c0c1c6aae4d..3863ad98bc60 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/base.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/base.py @@ -26,10 +26,12 @@ from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.cloud.run_v2.types import service from google.cloud.run_v2.types import service as gcr_service from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 from google.longrunning import operations_pb2 # type: ignore try: @@ -280,6 +282,33 @@ def test_iam_permissions( ]: raise NotImplementedError() + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None,]: + raise NotImplementedError() + @property def kind(self) -> str: raise NotImplementedError() diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/grpc.py b/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/grpc.py index 622a46b36746..fd8da9afa7fc 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/grpc.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/grpc.py @@ -25,10 +25,12 @@ import grpc # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.cloud.run_v2.types import service from google.cloud.run_v2.types import service as gcr_service from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 from google.longrunning import operations_pb2 # type: ignore from .base import ServicesTransport, DEFAULT_CLIENT_INFO @@ -470,6 +472,59 @@ def test_iam_permissions( def close(self): self.grpc_channel.close() + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + @property def kind(self) -> str: return "grpc" diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/grpc_asyncio.py b/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/grpc_asyncio.py index 538fe94f9f50..25d1266fca71 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/grpc_asyncio.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/grpc_asyncio.py @@ -25,10 +25,12 @@ import grpc # type: ignore from grpc.experimental import aio # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.cloud.run_v2.types import service from google.cloud.run_v2.types import service as gcr_service from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 from google.longrunning import operations_pb2 # type: ignore from .base import ServicesTransport, DEFAULT_CLIENT_INFO from .grpc import ServicesGrpcTransport @@ -483,5 +485,58 @@ def test_iam_permissions( def close(self): return self.grpc_channel.close() + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + __all__ = ("ServicesGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/rest.py b/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/rest.py index 1eb89e6b0dd5..0769b338b59d 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/rest.py +++ b/packages/google-cloud-run/google/cloud/run_v2/services/services/transports/rest.py @@ -28,6 +28,8 @@ from google.protobuf import json_format from google.api_core import operations_v1 +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 from requests import __version__ as requests_version import dataclasses import re @@ -305,6 +307,75 @@ def post_update_service( """ return response + def pre_delete_operation( + self, + request: operations_pb2.DeleteOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> None: + """Pre-rpc interceptor for delete_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Services server. + """ + return request, metadata + + def post_delete_operation( + self, response: operations_pb2.DeleteOperationRequest + ) -> None: + """Post-rpc interceptor for delete_operation + + Override in a subclass to manipulate the response + after it is returned by the Services server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> operations_pb2.Operation: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Services server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.GetOperationRequest + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the Services server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> operations_pb2.ListOperationsResponse: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the Services server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsRequest + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the Services server but before + it is returned to user code. + """ + return response + @dataclasses.dataclass class ServicesRestStub: @@ -1404,6 +1475,203 @@ def update_service( # In C++ this would require a dynamic_cast return self._UpdateService(self._session, self._host, self._interceptor) # type: ignore + @property + def delete_operation(self): + return self._DeleteOperation(self._session, self._host, self._interceptor) # type: ignore + + class _DeleteOperation(ServicesRestStub): + def __call__( + self, + request: operations_pb2.DeleteOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + + r"""Call the delete operation method over HTTP. + + Args: + request (operations_pb2.DeleteOperationRequest): + The request object for DeleteOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2/{name=projects/*/locations/*/operations/*}", + }, + ] + + request, metadata = self._interceptor.pre_delete_operation( + request, metadata + ) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_delete_operation(None) + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ServicesRestStub): + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/operations/*}", + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ServicesRestStub): + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*}/operations", + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + @property def kind(self) -> str: return "rest" diff --git a/packages/google-cloud-run/google/cloud/run_v2/types/__init__.py b/packages/google-cloud-run/google/cloud/run_v2/types/__init__.py index 5a6b804f2b4e..8d97aa020f5f 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/types/__init__.py +++ b/packages/google-cloud-run/google/cloud/run_v2/types/__init__.py @@ -22,9 +22,13 @@ ContainerPort, EnvVar, EnvVarSource, + HTTPGetAction, + HTTPHeader, + Probe, ResourceRequirements, SecretKeySelector, SecretVolumeSource, + TCPSocketAction, VersionToPath, Volume, VolumeMount, @@ -68,9 +72,13 @@ "ContainerPort", "EnvVar", "EnvVarSource", + "HTTPGetAction", + "HTTPHeader", + "Probe", "ResourceRequirements", "SecretKeySelector", "SecretVolumeSource", + "TCPSocketAction", "VersionToPath", "Volume", "VolumeMount", diff --git a/packages/google-cloud-run/google/cloud/run_v2/types/condition.py b/packages/google-cloud-run/google/cloud/run_v2/types/condition.py index 9ded5b5adcb5..43c44b7dabda 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/types/condition.py +++ b/packages/google-cloud-run/google/cloud/run_v2/types/condition.py @@ -123,6 +123,7 @@ class ExecutionReason(proto.Enum): EXECUTION_REASON_UNDEFINED = 0 JOB_STATUS_SERVICE_POLLING_ERROR = 1 NON_ZERO_EXIT_CODE = 2 + CANCELLED = 3 type_ = proto.Field( proto.STRING, diff --git a/packages/google-cloud-run/google/cloud/run_v2/types/k8s_min.py b/packages/google-cloud-run/google/cloud/run_v2/types/k8s_min.py index 966361f861fb..c5c03b60c63d 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/types/k8s_min.py +++ b/packages/google-cloud-run/google/cloud/run_v2/types/k8s_min.py @@ -30,6 +30,10 @@ "SecretVolumeSource", "VersionToPath", "CloudSqlInstance", + "Probe", + "HTTPGetAction", + "HTTPHeader", + "TCPSocketAction", }, ) @@ -89,6 +93,24 @@ class Container(proto.Message): volume_mounts (Sequence[google.cloud.run_v2.types.VolumeMount]): Volume to mount into the container's filesystem. + working_dir (str): + Container's working directory. + If not specified, the container runtime's + default will be used, which might be configured + in the container image. + liveness_probe (google.cloud.run_v2.types.Probe): + Periodic probe of container liveness. + Container will be restarted if the probe fails. + More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + startup_probe (google.cloud.run_v2.types.Probe): + Startup probe of application within the + container. All other probes are disabled if a + startup probe is provided, until it succeeds. + Container will not be added to service endpoints + if the probe fails. + More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes """ name = proto.Field( @@ -127,6 +149,20 @@ class Container(proto.Message): number=8, message="VolumeMount", ) + working_dir = proto.Field( + proto.STRING, + number=9, + ) + liveness_probe = proto.Field( + proto.MESSAGE, + number=10, + message="Probe", + ) + startup_probe = proto.Field( + proto.MESSAGE, + number=11, + message="Probe", + ) class ResourceRequirements(proto.Message): @@ -369,7 +405,7 @@ class SecretVolumeSource(proto.Message): default_mode (int): Integer representation of mode bits to use on created files by default. Must be a value between 0000 and 0777 (octal), - defaulting to 0644. Directories within the path are not + defaulting to 0444. Directories within the path are not affected by this setting. Notes @@ -475,4 +511,142 @@ class CloudSqlInstance(proto.Message): ) +class Probe(proto.Message): + r"""Probe describes a health check to be performed against a + container to determine whether it is alive or ready to receive + traffic. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + initial_delay_seconds (int): + Number of seconds after the container has + started before the probe is initiated. + Defaults to 0 seconds. Minimum value is 0. + Maximum value for liveness probe is 3600. + Maximum value for startup probe is 240. More + info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + timeout_seconds (int): + Number of seconds after which the probe times out. Defaults + to 1 second. Minimum value is 1. Maximum value is 3600. Must + be smaller than period_seconds. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + period_seconds (int): + How often (in seconds) to perform the probe. Default to 10 + seconds. Minimum value is 1. Maximum value for liveness + probe is 3600. Maximum value for startup probe is 240. Must + be greater or equal than timeout_seconds. + failure_threshold (int): + Minimum consecutive failures for the probe to + be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + http_get (google.cloud.run_v2.types.HTTPGetAction): + HTTPGet specifies the http request to + perform. Exactly one of HTTPGet or TCPSocket + must be specified. + + This field is a member of `oneof`_ ``probe_type``. + tcp_socket (google.cloud.run_v2.types.TCPSocketAction): + TCPSocket specifies an action involving a TCP + port. Exactly one of HTTPGet or TCPSocket must + be specified. + + This field is a member of `oneof`_ ``probe_type``. + """ + + initial_delay_seconds = proto.Field( + proto.INT32, + number=1, + ) + timeout_seconds = proto.Field( + proto.INT32, + number=2, + ) + period_seconds = proto.Field( + proto.INT32, + number=3, + ) + failure_threshold = proto.Field( + proto.INT32, + number=4, + ) + http_get = proto.Field( + proto.MESSAGE, + number=5, + oneof="probe_type", + message="HTTPGetAction", + ) + tcp_socket = proto.Field( + proto.MESSAGE, + number=6, + oneof="probe_type", + message="TCPSocketAction", + ) + + +class HTTPGetAction(proto.Message): + r"""HTTPGetAction describes an action based on HTTP Get requests. + + Attributes: + path (str): + Path to access on the HTTP server. Defaults + to '/'. + http_headers (Sequence[google.cloud.run_v2.types.HTTPHeader]): + Custom headers to set in the request. HTTP + allows repeated headers. + """ + + path = proto.Field( + proto.STRING, + number=1, + ) + http_headers = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="HTTPHeader", + ) + + +class HTTPHeader(proto.Message): + r"""HTTPHeader describes a custom header to be used in HTTP + probes + + Attributes: + name (str): + Required. The header field name + value (str): + The header field value + """ + + name = proto.Field( + proto.STRING, + number=1, + ) + value = proto.Field( + proto.STRING, + number=2, + ) + + +class TCPSocketAction(proto.Message): + r"""TCPSocketAction describes an action based on opening a socket + + Attributes: + port (int): + Port number to access on the container. Must + be in the range 1 to 65535. + """ + + port = proto.Field( + proto.INT32, + number=1, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-run/google/cloud/run_v2/types/service.py b/packages/google-cloud-run/google/cloud/run_v2/types/service.py index 9c993fc3fb97..6213111cb0ce 100644 --- a/packages/google-cloud-run/google/cloud/run_v2/types/service.py +++ b/packages/google-cloud-run/google/cloud/run_v2/types/service.py @@ -42,14 +42,17 @@ class CreateServiceRequest(proto.Message): Attributes: parent (str): - Required. The location and project in which - this service should be created. Format: - projects/{projectnumber}/locations/{location} + The location and project in which this + service should be created. Format: + projects/{project}/locations/{location} Only + lowercase characters, digits, and hyphens. service (google.cloud.run_v2.types.Service): Required. The Service instance to create. service_id (str): - Required. The unique identifier for the Service. The name of - the service becomes {parent}/services/{service_id}. + Required. The unique identifier for the Service. It must + begin with letter, and may not end with hyphen; must contain + fewer than 50 characters. The name of the service becomes + {parent}/services/{service_id}. validate_only (bool): Indicates that the request should be validated and default values populated, without @@ -117,7 +120,7 @@ class ListServicesRequest(proto.Message): Required. The location and project to list resources on. Location must be a valid GCP region, and may not be the "-" wildcard. Format: - projects/{projectnumber}/locations/{location} + projects/{project}/locations/{location} page_size (int): Maximum number of Services to return in this call. @@ -180,7 +183,7 @@ class GetServiceRequest(proto.Message): name (str): Required. The full name of the Service. Format: - projects/{projectnumber}/locations/{location}/services/{service} + projects/{project}/locations/{location}/services/{service} """ name = proto.Field( @@ -196,7 +199,7 @@ class DeleteServiceRequest(proto.Message): name (str): Required. The full name of the Service. Format: - projects/{projectnumber}/locations/{location}/services/{service} + projects/{project}/locations/{location}/services/{service} validate_only (bool): Indicates that the request should be validated without actually deleting any diff --git a/packages/google-cloud-run/samples/generated_samples/snippet_metadata_run_v2.json b/packages/google-cloud-run/samples/generated_samples/snippet_metadata_run_v2.json index 635f79093b04..3eb853c4c952 100644 --- a/packages/google-cloud-run/samples/generated_samples/snippet_metadata_run_v2.json +++ b/packages/google-cloud-run/samples/generated_samples/snippet_metadata_run_v2.json @@ -133,7 +133,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", + "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -169,7 +169,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" + "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" }, { "canonical": true, @@ -213,7 +213,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", + "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -249,7 +249,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" + "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" }, { "canonical": true, @@ -374,7 +374,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", + "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -410,7 +410,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" + "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" }, { "canonical": true, @@ -454,7 +454,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", + "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -490,7 +490,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" + "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" }, { "canonical": true, @@ -615,7 +615,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", + "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -651,7 +651,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" + "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" }, { "canonical": true, @@ -695,7 +695,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", + "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -731,7 +731,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" + "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" }, { "canonical": true, @@ -872,7 +872,7 @@ "shortName": "create_service" }, "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync_8031b824.py", + "file": "run_v2_generated_services_create_service_sync_3c405c33.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_CreateService_sync", @@ -908,7 +908,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_create_service_sync_8031b824.py" + "title": "run_v2_generated_services_create_service_sync_3c405c33.py" }, { "canonical": true, @@ -960,7 +960,7 @@ "shortName": "create_service" }, "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync_3c405c33.py", + "file": "run_v2_generated_services_create_service_sync_8031b824.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_CreateService_sync", @@ -996,7 +996,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_create_service_sync_3c405c33.py" + "title": "run_v2_generated_services_create_service_sync_8031b824.py" }, { "canonical": true, @@ -1121,7 +1121,7 @@ "shortName": "delete_service" }, "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync_9c99d0a2.py", + "file": "run_v2_generated_services_delete_service_sync_91d4ca21.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_DeleteService_sync", @@ -1157,7 +1157,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_delete_service_sync_9c99d0a2.py" + "title": "run_v2_generated_services_delete_service_sync_91d4ca21.py" }, { "canonical": true, @@ -1201,7 +1201,7 @@ "shortName": "delete_service" }, "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync_91d4ca21.py", + "file": "run_v2_generated_services_delete_service_sync_9c99d0a2.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_DeleteService_sync", @@ -1237,7 +1237,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_delete_service_sync_91d4ca21.py" + "title": "run_v2_generated_services_delete_service_sync_9c99d0a2.py" }, { "canonical": true, @@ -1354,7 +1354,7 @@ "shortName": "get_iam_policy" }, "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py", + "file": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", @@ -1390,7 +1390,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py" + "title": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py" }, { "canonical": true, @@ -1430,7 +1430,7 @@ "shortName": "get_iam_policy" }, "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py", + "file": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", @@ -1466,7 +1466,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py" + "title": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py" }, { "canonical": true, @@ -1591,7 +1591,7 @@ "shortName": "get_service" }, "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync_18284d02.py", + "file": "run_v2_generated_services_get_service_sync_1c3ef02e.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetService_sync", @@ -1627,7 +1627,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_service_sync_18284d02.py" + "title": "run_v2_generated_services_get_service_sync_1c3ef02e.py" }, { "canonical": true, @@ -1671,7 +1671,7 @@ "shortName": "get_service" }, "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync_1c3ef02e.py", + "file": "run_v2_generated_services_get_service_sync_18284d02.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetService_sync", @@ -1707,7 +1707,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_service_sync_1c3ef02e.py" + "title": "run_v2_generated_services_get_service_sync_18284d02.py" }, { "canonical": true, @@ -1832,7 +1832,7 @@ "shortName": "list_services" }, "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync_7dbaf490.py", + "file": "run_v2_generated_services_list_services_sync_c5743712.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_ListServices_sync", @@ -1868,7 +1868,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync_7dbaf490.py" + "title": "run_v2_generated_services_list_services_sync_c5743712.py" }, { "canonical": true, @@ -1912,7 +1912,7 @@ "shortName": "list_services" }, "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync_c5743712.py", + "file": "run_v2_generated_services_list_services_sync_7dbaf490.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_ListServices_sync", @@ -1948,7 +1948,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync_c5743712.py" + "title": "run_v2_generated_services_list_services_sync_7dbaf490.py" }, { "canonical": true, @@ -2065,7 +2065,7 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py", + "file": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", @@ -2101,7 +2101,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py" + "title": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py" }, { "canonical": true, @@ -2141,7 +2141,7 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py", + "file": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", @@ -2177,7 +2177,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py" + "title": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py" }, { "canonical": true, @@ -2294,7 +2294,7 @@ "shortName": "test_iam_permissions" }, "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py", + "file": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", @@ -2330,7 +2330,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py" + "title": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py" }, { "canonical": true, @@ -2370,7 +2370,7 @@ "shortName": "test_iam_permissions" }, "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py", + "file": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", @@ -2406,7 +2406,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py" + "title": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py" }, { "canonical": true, @@ -2531,7 +2531,7 @@ "shortName": "update_service" }, "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync_2652a462.py", + "file": "run_v2_generated_services_update_service_sync_9076a854.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_UpdateService_sync", @@ -2567,7 +2567,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_update_service_sync_2652a462.py" + "title": "run_v2_generated_services_update_service_sync_9076a854.py" }, { "canonical": true, @@ -2611,7 +2611,7 @@ "shortName": "update_service" }, "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync_9076a854.py", + "file": "run_v2_generated_services_update_service_sync_2652a462.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_UpdateService_sync", @@ -2647,7 +2647,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_update_service_sync_9076a854.py" + "title": "run_v2_generated_services_update_service_sync_2652a462.py" } ] } diff --git a/packages/google-cloud-run/tests/unit/gapic/run_v2/test_revisions.py b/packages/google-cloud-run/tests/unit/gapic/run_v2/test_revisions.py index c08163342d6f..4561506c0538 100644 --- a/packages/google-cloud-run/tests/unit/gapic/run_v2/test_revisions.py +++ b/packages/google-cloud-run/tests/unit/gapic/run_v2/test_revisions.py @@ -49,6 +49,7 @@ from google.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 from google.cloud.run_v2.services.revisions import RevisionsAsyncClient from google.cloud.run_v2.services.revisions import RevisionsClient from google.cloud.run_v2.services.revisions import pagers @@ -2565,6 +2566,9 @@ def test_revisions_base_transport(): "get_revision", "list_revisions", "delete_revision", + "get_operation", + "delete_operation", + "list_operations", ) for method in methods: with pytest.raises(NotImplementedError): @@ -3302,6 +3306,609 @@ async def test_transport_close_async(): close.assert_called_once() +def test_delete_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.DeleteOperationRequest +): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.DeleteOperationRequest, + dict, + ], +) +def test_delete_operation_rest(request_type): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2/operations/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "{}" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_get_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.GetOperationRequest +): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2/operations/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.ListOperationsRequest +): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_delete_operation(transport: str = "grpc"): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_operation_async(transport: str = "grpc"): + client = RevisionsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_field_headers(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = None + + client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_operation_field_headers_async(): + client = RevisionsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_delete_operation_from_dict(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_delete_operation_from_dict_async(): + client = RevisionsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_operation(transport: str = "grpc"): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = RevisionsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = RevisionsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = RevisionsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = RevisionsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = RevisionsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = RevisionsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + def test_transport_close(): transports = { "rest": "_session", diff --git a/packages/google-cloud-run/tests/unit/gapic/run_v2/test_services.py b/packages/google-cloud-run/tests/unit/gapic/run_v2/test_services.py index 910dae20974f..ecd2f7fb7216 100644 --- a/packages/google-cloud-run/tests/unit/gapic/run_v2/test_services.py +++ b/packages/google-cloud-run/tests/unit/gapic/run_v2/test_services.py @@ -49,6 +49,7 @@ from google.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 from google.cloud.run_v2.services.services import ServicesAsyncClient from google.cloud.run_v2.services.services import ServicesClient from google.cloud.run_v2.services.services import pagers @@ -2504,6 +2505,21 @@ def test_create_service_rest(request_type): "volume_mounts": [ {"name": "name_value", "mount_path": "mount_path_value"} ], + "working_dir": "working_dir_value", + "liveness_probe": { + "initial_delay_seconds": 2214, + "timeout_seconds": 1621, + "period_seconds": 1489, + "failure_threshold": 1812, + "http_get": { + "path": "path_value", + "http_headers": [ + {"name": "name_value", "value": "value_value"} + ], + }, + "tcp_socket": {"port": 453}, + }, + "startup_probe": {}, } ], "volumes": [ @@ -2821,6 +2837,21 @@ def test_create_service_rest_bad_request( "volume_mounts": [ {"name": "name_value", "mount_path": "mount_path_value"} ], + "working_dir": "working_dir_value", + "liveness_probe": { + "initial_delay_seconds": 2214, + "timeout_seconds": 1621, + "period_seconds": 1489, + "failure_threshold": 1812, + "http_get": { + "path": "path_value", + "http_headers": [ + {"name": "name_value", "value": "value_value"} + ], + }, + "tcp_socket": {"port": 453}, + }, + "startup_probe": {}, } ], "volumes": [ @@ -3650,6 +3681,21 @@ def test_update_service_rest(request_type): "volume_mounts": [ {"name": "name_value", "mount_path": "mount_path_value"} ], + "working_dir": "working_dir_value", + "liveness_probe": { + "initial_delay_seconds": 2214, + "timeout_seconds": 1621, + "period_seconds": 1489, + "failure_threshold": 1812, + "http_get": { + "path": "path_value", + "http_headers": [ + {"name": "name_value", "value": "value_value"} + ], + }, + "tcp_socket": {"port": 453}, + }, + "startup_probe": {}, } ], "volumes": [ @@ -3946,6 +3992,21 @@ def test_update_service_rest_bad_request( "volume_mounts": [ {"name": "name_value", "mount_path": "mount_path_value"} ], + "working_dir": "working_dir_value", + "liveness_probe": { + "initial_delay_seconds": 2214, + "timeout_seconds": 1621, + "period_seconds": 1489, + "failure_threshold": 1812, + "http_get": { + "path": "path_value", + "http_headers": [ + {"name": "name_value", "value": "value_value"} + ], + }, + "tcp_socket": {"port": 453}, + }, + "startup_probe": {}, } ], "volumes": [ @@ -5149,6 +5210,9 @@ def test_services_base_transport(): "get_iam_policy", "set_iam_policy", "test_iam_permissions", + "get_operation", + "delete_operation", + "list_operations", ) for method in methods: with pytest.raises(NotImplementedError): @@ -5901,6 +5965,609 @@ async def test_transport_close_async(): close.assert_called_once() +def test_delete_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.DeleteOperationRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.DeleteOperationRequest, + dict, + ], +) +def test_delete_operation_rest(request_type): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2/operations/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "{}" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_get_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.GetOperationRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2/operations/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.ListOperationsRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_delete_operation(transport: str = "grpc"): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_operation_async(transport: str = "grpc"): + client = ServicesAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_field_headers(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = None + + client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_operation_field_headers_async(): + client = ServicesAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_delete_operation_from_dict(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_delete_operation_from_dict_async(): + client = ServicesAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_operation(transport: str = "grpc"): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ServicesAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ServicesAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ServicesAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ServicesAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ServicesAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ServicesAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + def test_transport_close(): transports = { "rest": "_session",