diff --git a/google/cloud/tasks_v2/services/cloud_tasks/async_client.py b/google/cloud/tasks_v2/services/cloud_tasks/async_client.py index 89a8205..5eb51a2 100644 --- a/google/cloud/tasks_v2/services/cloud_tasks/async_client.py +++ b/google/cloud/tasks_v2/services/cloud_tasks/async_client.py @@ -42,6 +42,7 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object] # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore @@ -282,7 +283,7 @@ async def sample_list_queues(): Returns: google.cloud.tasks_v2.services.cloud_tasks.pagers.ListQueuesAsyncPager: Response message for - [ListQueues][google.cloud.tasks.v2.CloudTasks.ListQueues]. + [ListQueues][google.cloud.tasks.v2.CloudTasks.ListQueues]. Iterating over this object will yield results and resolve additional pages automatically. @@ -317,9 +318,9 @@ async def sample_list_queues(): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -442,9 +443,9 @@ async def sample_get_queue(): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -577,7 +578,7 @@ async def sample_create_queue(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.create_queue, - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -715,7 +716,7 @@ async def sample_update_queue(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.update_queue, - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -829,9 +830,9 @@ async def sample_delete_queue(): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -939,7 +940,7 @@ async def sample_purge_queue(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.purge_queue, - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -1052,7 +1053,7 @@ async def sample_pause_queue(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.pause_queue, - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -1172,7 +1173,7 @@ async def sample_resume_queue(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.resume_queue, - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -1353,9 +1354,9 @@ async def sample_get_iam_policy(): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -1532,7 +1533,7 @@ async def sample_set_iam_policy(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.set_iam_policy, - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -1664,9 +1665,9 @@ async def sample_test_iam_permissions(): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -1754,7 +1755,7 @@ async def sample_list_tasks(): Returns: google.cloud.tasks_v2.services.cloud_tasks.pagers.ListTasksAsyncPager: Response message for listing tasks using - [ListTasks][google.cloud.tasks.v2.CloudTasks.ListTasks]. + [ListTasks][google.cloud.tasks.v2.CloudTasks.ListTasks]. Iterating over this object will yield results and resolve additional pages automatically. @@ -1789,9 +1790,9 @@ async def sample_list_tasks(): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -1908,9 +1909,9 @@ async def sample_get_task(): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -2066,7 +2067,7 @@ async def sample_create_task(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.create_task, - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -2170,9 +2171,9 @@ async def sample_delete_task(): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=DEFAULT_CLIENT_INFO, ) @@ -2295,7 +2296,115 @@ async def sample_run_task(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.run_task, - default_timeout=10.0, + default_timeout=20.0, + 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_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` 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: + ~.location_pb2.Location: + Location 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 = locations_pb2.GetLocationRequest(**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_location, + 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 list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` 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: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` 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 = locations_pb2.ListLocationsRequest(**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_locations, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) diff --git a/google/cloud/tasks_v2/services/cloud_tasks/client.py b/google/cloud/tasks_v2/services/cloud_tasks/client.py index 948d8b2..9f13247 100644 --- a/google/cloud/tasks_v2/services/cloud_tasks/client.py +++ b/google/cloud/tasks_v2/services/cloud_tasks/client.py @@ -46,6 +46,7 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object] # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore @@ -537,7 +538,7 @@ def sample_list_queues(): Returns: google.cloud.tasks_v2.services.cloud_tasks.pagers.ListQueuesPager: Response message for - [ListQueues][google.cloud.tasks.v2.CloudTasks.ListQueues]. + [ListQueues][google.cloud.tasks.v2.CloudTasks.ListQueues]. Iterating over this object will yield results and resolve additional pages automatically. @@ -1951,7 +1952,7 @@ def sample_list_tasks(): Returns: google.cloud.tasks_v2.services.cloud_tasks.pagers.ListTasksPager: Response message for listing tasks using - [ListTasks][google.cloud.tasks.v2.CloudTasks.ListTasks]. + [ListTasks][google.cloud.tasks.v2.CloudTasks.ListTasks]. Iterating over this object will yield results and resolve additional pages automatically. @@ -2496,6 +2497,114 @@ def __exit__(self, type, value, traceback): """ self.transport.close() + def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` 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: + ~.location_pb2.Location: + Location 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 = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_location, + 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 list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` 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: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` 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 = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_locations, + 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 + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=package_version.__version__ diff --git a/google/cloud/tasks_v2/services/cloud_tasks/transports/base.py b/google/cloud/tasks_v2/services/cloud_tasks/transports/base.py index 896330b..b62af84 100644 --- a/google/cloud/tasks_v2/services/cloud_tasks/transports/base.py +++ b/google/cloud/tasks_v2/services/cloud_tasks/transports/base.py @@ -22,6 +22,7 @@ from google.api_core import retry as retries import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.oauth2 import service_account # type: ignore @@ -139,9 +140,9 @@ def _prep_wrapped_messages(self, client_info): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.get_queue: gapic_v1.method.wrap_method( @@ -154,19 +155,19 @@ def _prep_wrapped_messages(self, client_info): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.create_queue: gapic_v1.method.wrap_method( self.create_queue, - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.update_queue: gapic_v1.method.wrap_method( self.update_queue, - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.delete_queue: gapic_v1.method.wrap_method( @@ -179,24 +180,24 @@ def _prep_wrapped_messages(self, client_info): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.purge_queue: gapic_v1.method.wrap_method( self.purge_queue, - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.pause_queue: gapic_v1.method.wrap_method( self.pause_queue, - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.resume_queue: gapic_v1.method.wrap_method( self.resume_queue, - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.get_iam_policy: gapic_v1.method.wrap_method( @@ -209,14 +210,14 @@ def _prep_wrapped_messages(self, client_info): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.set_iam_policy: gapic_v1.method.wrap_method( self.set_iam_policy, - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.test_iam_permissions: gapic_v1.method.wrap_method( @@ -229,9 +230,9 @@ def _prep_wrapped_messages(self, client_info): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.list_tasks: gapic_v1.method.wrap_method( @@ -244,9 +245,9 @@ def _prep_wrapped_messages(self, client_info): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.get_task: gapic_v1.method.wrap_method( @@ -259,14 +260,14 @@ def _prep_wrapped_messages(self, client_info): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.create_task: gapic_v1.method.wrap_method( self.create_task, - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.delete_task: gapic_v1.method.wrap_method( @@ -279,14 +280,14 @@ def _prep_wrapped_messages(self, client_info): core_exceptions.DeadlineExceeded, core_exceptions.ServiceUnavailable, ), - deadline=10.0, + deadline=20.0, ), - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), self.run_task: gapic_v1.method.wrap_method( self.run_task, - default_timeout=10.0, + default_timeout=20.0, client_info=client_info, ), } @@ -436,6 +437,27 @@ def run_task( ) -> Callable[[cloudtasks.RunTaskRequest], Union[task.Task, Awaitable[task.Task]]]: raise NotImplementedError() + @property + def get_location( + self, + ) -> Callable[ + [locations_pb2.GetLocationRequest], + Union[locations_pb2.Location, Awaitable[locations_pb2.Location]], + ]: + raise NotImplementedError() + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], + Union[ + locations_pb2.ListLocationsResponse, + Awaitable[locations_pb2.ListLocationsResponse], + ], + ]: + raise NotImplementedError() + @property def kind(self) -> str: raise NotImplementedError() diff --git a/google/cloud/tasks_v2/services/cloud_tasks/transports/grpc.py b/google/cloud/tasks_v2/services/cloud_tasks/transports/grpc.py index ad6bca1..897e980 100644 --- a/google/cloud/tasks_v2/services/cloud_tasks/transports/grpc.py +++ b/google/cloud/tasks_v2/services/cloud_tasks/transports/grpc.py @@ -20,6 +20,7 @@ import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore @@ -774,6 +775,42 @@ def run_task(self) -> Callable[[cloudtasks.RunTaskRequest], task.Task]: def close(self): self.grpc_channel.close() + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations 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_locations" not in self._stubs: + self._stubs["list_locations"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations 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_location" not in self._stubs: + self._stubs["get_location"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + @property def kind(self) -> str: return "grpc" diff --git a/google/cloud/tasks_v2/services/cloud_tasks/transports/grpc_asyncio.py b/google/cloud/tasks_v2/services/cloud_tasks/transports/grpc_asyncio.py index 09249db..6e0fc44 100644 --- a/google/cloud/tasks_v2/services/cloud_tasks/transports/grpc_asyncio.py +++ b/google/cloud/tasks_v2/services/cloud_tasks/transports/grpc_asyncio.py @@ -19,6 +19,7 @@ from google.api_core import gapic_v1, grpc_helpers_async from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore @@ -793,5 +794,41 @@ def run_task(self) -> Callable[[cloudtasks.RunTaskRequest], Awaitable[task.Task] def close(self): return self.grpc_channel.close() + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations 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_locations" not in self._stubs: + self._stubs["list_locations"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations 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_location" not in self._stubs: + self._stubs["get_location"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + __all__ = ("CloudTasksGrpcAsyncIOTransport",) diff --git a/google/cloud/tasks_v2/services/cloud_tasks/transports/rest.py b/google/cloud/tasks_v2/services/cloud_tasks/transports/rest.py index f3054de..0e4f7ce 100644 --- a/google/cloud/tasks_v2/services/cloud_tasks/transports/rest.py +++ b/google/cloud/tasks_v2/services/cloud_tasks/transports/rest.py @@ -26,6 +26,7 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.protobuf import json_format import grpc # type: ignore from requests import __version__ as requests_version @@ -503,6 +504,52 @@ def post_update_queue(self, response: gct_queue.Queue) -> gct_queue.Queue: """ return response + def pre_get_location( + self, + request: locations_pb2.GetLocationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[locations_pb2.GetLocationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_location + + Override in a subclass to manipulate the request or metadata + before they are sent to the CloudTasks server. + """ + return request, metadata + + def post_get_location( + self, response: locations_pb2.Location + ) -> locations_pb2.Location: + """Post-rpc interceptor for get_location + + Override in a subclass to manipulate the response + after it is returned by the CloudTasks server but before + it is returned to user code. + """ + return response + + def pre_list_locations( + self, + request: locations_pb2.ListLocationsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[locations_pb2.ListLocationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_locations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CloudTasks server. + """ + return request, metadata + + def post_list_locations( + self, response: locations_pb2.ListLocationsResponse + ) -> locations_pb2.ListLocationsResponse: + """Post-rpc interceptor for list_locations + + Override in a subclass to manipulate the response + after it is returned by the CloudTasks server but before + it is returned to user code. + """ + return response + @dataclasses.dataclass class CloudTasksRestStub: @@ -2363,6 +2410,140 @@ def update_queue( # In C++ this would require a dynamic_cast return self._UpdateQueue(self._session, self._host, self._interceptor) # type: ignore + @property + def get_location(self): + return self._GetLocation(self._session, self._host, self._interceptor) # type: ignore + + class _GetLocation(CloudTasksRestStub): + def __call__( + self, + request: locations_pb2.GetLocationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + + r"""Call the get location method over HTTP. + + Args: + request (locations_pb2.GetLocationRequest): + The request object for GetLocation 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: + locations_pb2.Location: Response from GetLocation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*}", + }, + ] + + request, metadata = self._interceptor.pre_get_location(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 = locations_pb2.Location() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_location(resp) + return resp + + @property + def list_locations(self): + return self._ListLocations(self._session, self._host, self._interceptor) # type: ignore + + class _ListLocations(CloudTasksRestStub): + def __call__( + self, + request: locations_pb2.ListLocationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + + r"""Call the list locations method over HTTP. + + Args: + request (locations_pb2.ListLocationsRequest): + The request object for ListLocations 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: + locations_pb2.ListLocationsResponse: Response from ListLocations method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=projects/*}/locations", + }, + ] + + request, metadata = self._interceptor.pre_list_locations(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 = locations_pb2.ListLocationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_locations(resp) + return resp + @property def kind(self) -> str: return "rest" diff --git a/google/cloud/tasks_v2/types/queue.py b/google/cloud/tasks_v2/types/queue.py index dc7da62..e6533ac 100644 --- a/google/cloud/tasks_v2/types/queue.py +++ b/google/cloud/tasks_v2/types/queue.py @@ -123,7 +123,7 @@ class Queue(proto.Message): state (google.cloud.tasks_v2.types.Queue.State): Output only. The state of the queue. - ``state`` can only be changed by called + ``state`` can only be changed by calling [PauseQueue][google.cloud.tasks.v2.CloudTasks.PauseQueue], [ResumeQueue][google.cloud.tasks.v2.CloudTasks.ResumeQueue], or uploading @@ -399,7 +399,7 @@ class RetryConfig(proto.Message): A task's retry interval starts at [min_backoff][google.cloud.tasks.v2.RetryConfig.min_backoff], then doubles ``max_doublings`` times, then increases - linearly, and finally retries retries at intervals of + linearly, and finally retries at intervals of [max_backoff][google.cloud.tasks.v2.RetryConfig.max_backoff] up to [max_attempts][google.cloud.tasks.v2.RetryConfig.max_attempts] diff --git a/google/cloud/tasks_v2/types/target.py b/google/cloud/tasks_v2/types/target.py index effa731..c170b84 100644 --- a/google/cloud/tasks_v2/types/target.py +++ b/google/cloud/tasks_v2/types/target.py @@ -250,10 +250,10 @@ class AppEngineHttpRequest(proto.Message): queue-level or task-level: - If [app_engine_routing_override is set on the - queue][Queue.app_engine_routing_override], this value is used for - all tasks in the queue, no matter what the setting is for the - [task-level - app_engine_routing][AppEngineHttpRequest.app_engine_routing]. + queue][google.cloud.tasks.v2.Queue.app_engine_routing_override], + this value is used for all tasks in the queue, no matter what the + setting is for the [task-level + app_engine_routing][google.cloud.tasks.v2.AppEngineHttpRequest.app_engine_routing]. The ``url`` that the task will be sent to is: @@ -289,20 +289,20 @@ class AppEngineHttpRequest(proto.Message): The app's request handler for the task's target URL must be able to handle HTTP requests with this http_method, - otherwise the task attempt will fail with error code 405 - (Method Not Allowed). See `Writing a push task request + otherwise the task attempt fails with error code 405 (Method + Not Allowed). See `Writing a push task request handler `__ - and the documentation for the request handlers in the - language your app is written in e.g. `Python Request - Handler `__. + and the App Engine documentation for your runtime on `How + Requests are + Handled `__. app_engine_routing (google.cloud.tasks_v2.types.AppEngineRouting): Task-level setting for App Engine routing. - If [app_engine_routing_override is set on the - queue][Queue.app_engine_routing_override], this value is - used for all tasks in the queue, no matter what the - setting is for the [task-level - app_engine_routing][AppEngineHttpRequest.app_engine_routing]. + queue][google.cloud.tasks.v2.Queue.app_engine_routing_override], + this value is used for all tasks in the queue, no matter + what the setting is for the [task-level + app_engine_routing][google.cloud.tasks.v2.AppEngineHttpRequest.app_engine_routing]. relative_uri (str): The relative URI. The relative URI must begin with "/" and must be diff --git a/google/cloud/tasks_v2/types/task.py b/google/cloud/tasks_v2/types/task.py index ed1541c..bdb4726 100644 --- a/google/cloud/tasks_v2/types/task.py +++ b/google/cloud/tasks_v2/types/task.py @@ -103,9 +103,9 @@ class Task(proto.Message): [RetryConfig][google.cloud.tasks.v2.RetryConfig]. Note that when the request is cancelled, Cloud Tasks will - stop listing for the response, but whether the worker stops - processing depends on the worker. For example, if the worker - is stuck, it may not react to cancelled requests. + stop listening for the response, but whether the worker + stops processing depends on the worker. For example, if the + worker is stuck, it may not react to cancelled requests. The default and maximum values depend on the type of request: diff --git a/google/cloud/tasks_v2beta2/__init__.py b/google/cloud/tasks_v2beta2/__init__.py index 7cc39e1..fe776d9 100644 --- a/google/cloud/tasks_v2beta2/__init__.py +++ b/google/cloud/tasks_v2beta2/__init__.py @@ -21,6 +21,8 @@ from .services.cloud_tasks import CloudTasksAsyncClient, CloudTasksClient from .types.cloudtasks import ( AcknowledgeTaskRequest, + BufferTaskRequest, + BufferTaskResponse, CancelLeaseRequest, CreateQueueRequest, CreateTaskRequest, @@ -40,6 +42,7 @@ ResumeQueueRequest, RunTaskRequest, UpdateQueueRequest, + UploadQueueYamlRequest, ) from .types.queue import Queue, QueueStats, RateLimits, RetryConfig from .types.target import ( @@ -47,8 +50,15 @@ AppEngineHttpTarget, AppEngineRouting, HttpMethod, + HttpRequest, + HttpTarget, + OAuthToken, + OidcToken, + PathOverride, PullMessage, PullTarget, + QueryOverride, + UriOverride, ) from .types.task import AttemptStatus, Task, TaskStatus @@ -59,6 +69,8 @@ "AppEngineHttpTarget", "AppEngineRouting", "AttemptStatus", + "BufferTaskRequest", + "BufferTaskResponse", "CancelLeaseRequest", "CloudTasksClient", "CreateQueueRequest", @@ -68,16 +80,22 @@ "GetQueueRequest", "GetTaskRequest", "HttpMethod", + "HttpRequest", + "HttpTarget", "LeaseTasksRequest", "LeaseTasksResponse", "ListQueuesRequest", "ListQueuesResponse", "ListTasksRequest", "ListTasksResponse", + "OAuthToken", + "OidcToken", + "PathOverride", "PauseQueueRequest", "PullMessage", "PullTarget", "PurgeQueueRequest", + "QueryOverride", "Queue", "QueueStats", "RateLimits", @@ -88,4 +106,6 @@ "Task", "TaskStatus", "UpdateQueueRequest", + "UploadQueueYamlRequest", + "UriOverride", ) diff --git a/google/cloud/tasks_v2beta2/gapic_metadata.json b/google/cloud/tasks_v2beta2/gapic_metadata.json index 57d46ab..7ea03b3 100644 --- a/google/cloud/tasks_v2beta2/gapic_metadata.json +++ b/google/cloud/tasks_v2beta2/gapic_metadata.json @@ -15,6 +15,11 @@ "acknowledge_task" ] }, + "BufferTask": { + "methods": [ + "buffer_task" + ] + }, "CancelLease": { "methods": [ "cancel_lease" @@ -109,6 +114,11 @@ "methods": [ "update_queue" ] + }, + "UploadQueueYaml": { + "methods": [ + "upload_queue_yaml" + ] } } }, @@ -120,6 +130,11 @@ "acknowledge_task" ] }, + "BufferTask": { + "methods": [ + "buffer_task" + ] + }, "CancelLease": { "methods": [ "cancel_lease" @@ -214,6 +229,11 @@ "methods": [ "update_queue" ] + }, + "UploadQueueYaml": { + "methods": [ + "upload_queue_yaml" + ] } } }, @@ -225,6 +245,11 @@ "acknowledge_task" ] }, + "BufferTask": { + "methods": [ + "buffer_task" + ] + }, "CancelLease": { "methods": [ "cancel_lease" @@ -319,6 +344,11 @@ "methods": [ "update_queue" ] + }, + "UploadQueueYaml": { + "methods": [ + "upload_queue_yaml" + ] } } } diff --git a/google/cloud/tasks_v2beta2/services/cloud_tasks/async_client.py b/google/cloud/tasks_v2beta2/services/cloud_tasks/async_client.py index eff698c..2e3f605 100644 --- a/google/cloud/tasks_v2beta2/services/cloud_tasks/async_client.py +++ b/google/cloud/tasks_v2beta2/services/cloud_tasks/async_client.py @@ -42,6 +42,8 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object] # type: ignore +from google.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore @@ -1194,6 +1196,72 @@ async def sample_resume_queue(): # Done; return the response. return response + async def upload_queue_yaml( + self, + request: Optional[Union[cloudtasks.UploadQueueYamlRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Update queue list by uploading a queue.yaml file. + The queue.yaml file is supplied in the request body as a + YAML encoded string. This method was added to support + gcloud clients versions before 322.0.0. New clients + should use CreateQueue instead of this method. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import tasks_v2beta2 + + async def sample_upload_queue_yaml(): + # Create a client + client = tasks_v2beta2.CloudTasksAsyncClient() + + # Initialize request argument(s) + request = tasks_v2beta2.UploadQueueYamlRequest( + app_id="app_id_value", + ) + + # Make the request + await client.upload_queue_yaml(request=request) + + Args: + request (Optional[Union[google.cloud.tasks_v2beta2.types.UploadQueueYamlRequest, dict]]): + The request object. Request message for + [UploadQueueYaml][google.cloud.tasks.v2beta2.CloudTasks.UploadQueueYaml]. + 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. + """ + # Create or coerce a protobuf request object. + request = cloudtasks.UploadQueueYamlRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.upload_queue_yaml, + default_timeout=20.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + async def get_iam_policy( self, request: Optional[Union[iam_policy_pb2.GetIamPolicyRequest, dict]] = None, @@ -2016,11 +2084,11 @@ async def sample_create_task(): recently then the call will fail with [ALREADY_EXISTS][google.rpc.Code.ALREADY_EXISTS]. If the task's queue was created using Cloud Tasks, then another - task with the same name can't be created for ~1hour + task with the same name can't be created for ~1 hour after the original task was deleted or completed. If the task's queue was created using queue.yaml or queue.xml, then another task with the same name can't be created - for ~9days after the original task was deleted or + for ~9 days after the original task was deleted or completed. Because there is an extra lookup cost to identify @@ -2865,6 +2933,257 @@ async def sample_run_task(): # Done; return the response. return response + async def buffer_task( + self, + request: Optional[Union[cloudtasks.BufferTaskRequest, dict]] = None, + *, + queue: Optional[str] = None, + task_id: Optional[str] = None, + body: Optional[httpbody_pb2.HttpBody] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> cloudtasks.BufferTaskResponse: + r"""Creates and buffers a new task without the need to explicitly + define a Task message. The queue must have [HTTP + target][google.cloud.tasks.v2beta2.HttpTarget]. To create the + task with a custom ID, use the following format and set TASK_ID + to your desired ID: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID:buffer + To create the task with an automatically generated ID, use the + following format: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks:buffer. + Note: This feature is in its experimental stage. You must + request access to the API through the `Cloud Tasks BufferTask + Experiment Signup form `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import tasks_v2beta2 + + async def sample_buffer_task(): + # Create a client + client = tasks_v2beta2.CloudTasksAsyncClient() + + # Initialize request argument(s) + request = tasks_v2beta2.BufferTaskRequest( + queue="queue_value", + ) + + # Make the request + response = await client.buffer_task(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.tasks_v2beta2.types.BufferTaskRequest, dict]]): + The request object. LINT.IfChange Request message for + [BufferTask][google.cloud.tasks.v2beta2.CloudTasks.BufferTask]. + queue (:class:`str`): + Required. The parent queue name. For example: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID\` + + The queue must already exist. + + This corresponds to the ``queue`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + task_id (:class:`str`): + Optional. Task ID for the task being + created. If not provided, a random task + ID is assigned to the task. + + This corresponds to the ``task_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + body (:class:`google.api.httpbody_pb2.HttpBody`): + Optional. Body of the HTTP request. + + The body can take any generic value. The value is + written to the [HttpRequest][payload] of the [Task]. + + This corresponds to the ``body`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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: + google.cloud.tasks_v2beta2.types.BufferTaskResponse: + Response message for + [BufferTask][google.cloud.tasks.v2beta2.CloudTasks.BufferTask]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([queue, task_id, body]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = cloudtasks.BufferTaskRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if queue is not None: + request.queue = queue + if task_id is not None: + request.task_id = task_id + if body is not None: + request.body = body + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.buffer_task, + default_timeout=20.0, + 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( + ( + ("queue", request.queue), + ("task_id", request.task_id), + ) + ), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` 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: + ~.location_pb2.Location: + Location 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 = locations_pb2.GetLocationRequest(**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_location, + 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 list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` 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: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` 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 = locations_pb2.ListLocationsRequest(**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_locations, + 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 __aenter__(self) -> "CloudTasksAsyncClient": return self diff --git a/google/cloud/tasks_v2beta2/services/cloud_tasks/client.py b/google/cloud/tasks_v2beta2/services/cloud_tasks/client.py index 020414e..12188aa 100644 --- a/google/cloud/tasks_v2beta2/services/cloud_tasks/client.py +++ b/google/cloud/tasks_v2beta2/services/cloud_tasks/client.py @@ -46,6 +46,8 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object] # type: ignore +from google.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore @@ -1419,6 +1421,73 @@ def sample_resume_queue(): # Done; return the response. return response + def upload_queue_yaml( + self, + request: Optional[Union[cloudtasks.UploadQueueYamlRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Update queue list by uploading a queue.yaml file. + The queue.yaml file is supplied in the request body as a + YAML encoded string. This method was added to support + gcloud clients versions before 322.0.0. New clients + should use CreateQueue instead of this method. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import tasks_v2beta2 + + def sample_upload_queue_yaml(): + # Create a client + client = tasks_v2beta2.CloudTasksClient() + + # Initialize request argument(s) + request = tasks_v2beta2.UploadQueueYamlRequest( + app_id="app_id_value", + ) + + # Make the request + client.upload_queue_yaml(request=request) + + Args: + request (Union[google.cloud.tasks_v2beta2.types.UploadQueueYamlRequest, dict]): + The request object. Request message for + [UploadQueueYaml][google.cloud.tasks.v2beta2.CloudTasks.UploadQueueYaml]. + 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. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a cloudtasks.UploadQueueYamlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloudtasks.UploadQueueYamlRequest): + request = cloudtasks.UploadQueueYamlRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.upload_queue_yaml] + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + def get_iam_policy( self, request: Optional[Union[iam_policy_pb2.GetIamPolicyRequest, dict]] = None, @@ -2193,11 +2262,11 @@ def sample_create_task(): recently then the call will fail with [ALREADY_EXISTS][google.rpc.Code.ALREADY_EXISTS]. If the task's queue was created using Cloud Tasks, then another - task with the same name can't be created for ~1hour + task with the same name can't be created for ~1 hour after the original task was deleted or completed. If the task's queue was created using queue.yaml or queue.xml, then another task with the same name can't be created - for ~9days after the original task was deleted or + for ~9 days after the original task was deleted or completed. Because there is an extra lookup cost to identify @@ -3032,6 +3101,149 @@ def sample_run_task(): # Done; return the response. return response + def buffer_task( + self, + request: Optional[Union[cloudtasks.BufferTaskRequest, dict]] = None, + *, + queue: Optional[str] = None, + task_id: Optional[str] = None, + body: Optional[httpbody_pb2.HttpBody] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> cloudtasks.BufferTaskResponse: + r"""Creates and buffers a new task without the need to explicitly + define a Task message. The queue must have [HTTP + target][google.cloud.tasks.v2beta2.HttpTarget]. To create the + task with a custom ID, use the following format and set TASK_ID + to your desired ID: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID:buffer + To create the task with an automatically generated ID, use the + following format: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks:buffer. + Note: This feature is in its experimental stage. You must + request access to the API through the `Cloud Tasks BufferTask + Experiment Signup form `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import tasks_v2beta2 + + def sample_buffer_task(): + # Create a client + client = tasks_v2beta2.CloudTasksClient() + + # Initialize request argument(s) + request = tasks_v2beta2.BufferTaskRequest( + queue="queue_value", + ) + + # Make the request + response = client.buffer_task(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.tasks_v2beta2.types.BufferTaskRequest, dict]): + The request object. LINT.IfChange Request message for + [BufferTask][google.cloud.tasks.v2beta2.CloudTasks.BufferTask]. + queue (str): + Required. The parent queue name. For example: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID\` + + The queue must already exist. + + This corresponds to the ``queue`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + task_id (str): + Optional. Task ID for the task being + created. If not provided, a random task + ID is assigned to the task. + + This corresponds to the ``task_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + body (google.api.httpbody_pb2.HttpBody): + Optional. Body of the HTTP request. + + The body can take any generic value. The value is + written to the [HttpRequest][payload] of the [Task]. + + This corresponds to the ``body`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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: + google.cloud.tasks_v2beta2.types.BufferTaskResponse: + Response message for + [BufferTask][google.cloud.tasks.v2beta2.CloudTasks.BufferTask]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([queue, task_id, body]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a cloudtasks.BufferTaskRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloudtasks.BufferTaskRequest): + request = cloudtasks.BufferTaskRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if queue is not None: + request.queue = queue + if task_id is not None: + request.task_id = task_id + if body is not None: + request.body = body + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.buffer_task] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ("queue", request.queue), + ("task_id", request.task_id), + ) + ), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "CloudTasksClient": return self @@ -3045,6 +3257,114 @@ def __exit__(self, type, value, traceback): """ self.transport.close() + def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` 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: + ~.location_pb2.Location: + Location 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 = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_location, + 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 list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` 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: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` 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 = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_locations, + 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 + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=package_version.__version__ diff --git a/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/base.py b/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/base.py index ee888a4..f1f8bd0 100644 --- a/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/base.py +++ b/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/base.py @@ -22,6 +22,7 @@ from google.api_core import retry as retries import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.oauth2 import service_account # type: ignore @@ -199,6 +200,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=20.0, client_info=client_info, ), + self.upload_queue_yaml: gapic_v1.method.wrap_method( + self.upload_queue_yaml, + default_timeout=20.0, + client_info=client_info, + ), self.get_iam_policy: gapic_v1.method.wrap_method( self.get_iam_policy, default_retry=retries.Retry( @@ -309,6 +315,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=20.0, client_info=client_info, ), + self.buffer_task: gapic_v1.method.wrap_method( + self.buffer_task, + default_timeout=20.0, + client_info=client_info, + ), } def close(self): @@ -388,6 +399,15 @@ def resume_queue( ]: raise NotImplementedError() + @property + def upload_queue_yaml( + self, + ) -> Callable[ + [cloudtasks.UploadQueueYamlRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + @property def get_iam_policy( self, @@ -490,6 +510,36 @@ def run_task( ) -> Callable[[cloudtasks.RunTaskRequest], Union[task.Task, Awaitable[task.Task]]]: raise NotImplementedError() + @property + def buffer_task( + self, + ) -> Callable[ + [cloudtasks.BufferTaskRequest], + Union[cloudtasks.BufferTaskResponse, Awaitable[cloudtasks.BufferTaskResponse]], + ]: + raise NotImplementedError() + + @property + def get_location( + self, + ) -> Callable[ + [locations_pb2.GetLocationRequest], + Union[locations_pb2.Location, Awaitable[locations_pb2.Location]], + ]: + raise NotImplementedError() + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], + Union[ + locations_pb2.ListLocationsResponse, + Awaitable[locations_pb2.ListLocationsResponse], + ], + ]: + raise NotImplementedError() + @property def kind(self) -> str: raise NotImplementedError() diff --git a/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/grpc.py b/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/grpc.py index 97ff5eb..34f9481 100644 --- a/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/grpc.py +++ b/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/grpc.py @@ -20,6 +20,7 @@ import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore @@ -497,6 +498,36 @@ def resume_queue(self) -> Callable[[cloudtasks.ResumeQueueRequest], queue.Queue] ) return self._stubs["resume_queue"] + @property + def upload_queue_yaml( + self, + ) -> Callable[[cloudtasks.UploadQueueYamlRequest], empty_pb2.Empty]: + r"""Return a callable for the upload queue yaml method over gRPC. + + Update queue list by uploading a queue.yaml file. + The queue.yaml file is supplied in the request body as a + YAML encoded string. This method was added to support + gcloud clients versions before 322.0.0. New clients + should use CreateQueue instead of this method. + + Returns: + Callable[[~.UploadQueueYamlRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # 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 "upload_queue_yaml" not in self._stubs: + self._stubs["upload_queue_yaml"] = self.grpc_channel.unary_unary( + "/google.cloud.tasks.v2beta2.CloudTasks/UploadQueueYaml", + request_serializer=cloudtasks.UploadQueueYamlRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["upload_queue_yaml"] + @property def get_iam_policy( self, @@ -930,9 +961,82 @@ def run_task(self) -> Callable[[cloudtasks.RunTaskRequest], task.Task]: ) return self._stubs["run_task"] + @property + def buffer_task( + self, + ) -> Callable[[cloudtasks.BufferTaskRequest], cloudtasks.BufferTaskResponse]: + r"""Return a callable for the buffer task method over gRPC. + + Creates and buffers a new task without the need to explicitly + define a Task message. The queue must have [HTTP + target][google.cloud.tasks.v2beta2.HttpTarget]. To create the + task with a custom ID, use the following format and set TASK_ID + to your desired ID: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID:buffer + To create the task with an automatically generated ID, use the + following format: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks:buffer. + Note: This feature is in its experimental stage. You must + request access to the API through the `Cloud Tasks BufferTask + Experiment Signup form `__. + + Returns: + Callable[[~.BufferTaskRequest], + ~.BufferTaskResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # 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 "buffer_task" not in self._stubs: + self._stubs["buffer_task"] = self.grpc_channel.unary_unary( + "/google.cloud.tasks.v2beta2.CloudTasks/BufferTask", + request_serializer=cloudtasks.BufferTaskRequest.serialize, + response_deserializer=cloudtasks.BufferTaskResponse.deserialize, + ) + return self._stubs["buffer_task"] + def close(self): self.grpc_channel.close() + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations 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_locations" not in self._stubs: + self._stubs["list_locations"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations 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_location" not in self._stubs: + self._stubs["get_location"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + @property def kind(self) -> str: return "grpc" diff --git a/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/grpc_asyncio.py b/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/grpc_asyncio.py index 125d692..a8b6004 100644 --- a/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/grpc_asyncio.py +++ b/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/grpc_asyncio.py @@ -19,6 +19,7 @@ from google.api_core import gapic_v1, grpc_helpers_async from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore @@ -510,6 +511,36 @@ def resume_queue( ) return self._stubs["resume_queue"] + @property + def upload_queue_yaml( + self, + ) -> Callable[[cloudtasks.UploadQueueYamlRequest], Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the upload queue yaml method over gRPC. + + Update queue list by uploading a queue.yaml file. + The queue.yaml file is supplied in the request body as a + YAML encoded string. This method was added to support + gcloud clients versions before 322.0.0. New clients + should use CreateQueue instead of this method. + + Returns: + Callable[[~.UploadQueueYamlRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # 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 "upload_queue_yaml" not in self._stubs: + self._stubs["upload_queue_yaml"] = self.grpc_channel.unary_unary( + "/google.cloud.tasks.v2beta2.CloudTasks/UploadQueueYaml", + request_serializer=cloudtasks.UploadQueueYamlRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["upload_queue_yaml"] + @property def get_iam_policy( self, @@ -955,8 +986,83 @@ def run_task(self) -> Callable[[cloudtasks.RunTaskRequest], Awaitable[task.Task] ) return self._stubs["run_task"] + @property + def buffer_task( + self, + ) -> Callable[ + [cloudtasks.BufferTaskRequest], Awaitable[cloudtasks.BufferTaskResponse] + ]: + r"""Return a callable for the buffer task method over gRPC. + + Creates and buffers a new task without the need to explicitly + define a Task message. The queue must have [HTTP + target][google.cloud.tasks.v2beta2.HttpTarget]. To create the + task with a custom ID, use the following format and set TASK_ID + to your desired ID: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID:buffer + To create the task with an automatically generated ID, use the + following format: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks:buffer. + Note: This feature is in its experimental stage. You must + request access to the API through the `Cloud Tasks BufferTask + Experiment Signup form `__. + + Returns: + Callable[[~.BufferTaskRequest], + Awaitable[~.BufferTaskResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # 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 "buffer_task" not in self._stubs: + self._stubs["buffer_task"] = self.grpc_channel.unary_unary( + "/google.cloud.tasks.v2beta2.CloudTasks/BufferTask", + request_serializer=cloudtasks.BufferTaskRequest.serialize, + response_deserializer=cloudtasks.BufferTaskResponse.deserialize, + ) + return self._stubs["buffer_task"] + def close(self): return self.grpc_channel.close() + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations 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_locations" not in self._stubs: + self._stubs["list_locations"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations 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_location" not in self._stubs: + self._stubs["get_location"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + __all__ = ("CloudTasksGrpcAsyncIOTransport",) diff --git a/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/rest.py b/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/rest.py index aaedeb5..6b4265f 100644 --- a/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/rest.py +++ b/google/cloud/tasks_v2beta2/services/cloud_tasks/transports/rest.py @@ -26,6 +26,7 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.protobuf import json_format import grpc # type: ignore from requests import __version__ as requests_version @@ -75,6 +76,14 @@ def pre_acknowledge_task(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata + def pre_buffer_task(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_buffer_task(self, response): + logging.log(f"Received response: {response}") + return response + def pre_cancel_lease(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -219,6 +228,10 @@ def post_update_queue(self, response): logging.log(f"Received response: {response}") return response + def pre_upload_queue_yaml(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + transport = CloudTasksRestTransport(interceptor=MyCustomCloudTasksInterceptor()) client = CloudTasksClient(transport=transport) @@ -237,6 +250,27 @@ def pre_acknowledge_task( """ return request, metadata + def pre_buffer_task( + self, request: cloudtasks.BufferTaskRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[cloudtasks.BufferTaskRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for buffer_task + + Override in a subclass to manipulate the request or metadata + before they are sent to the CloudTasks server. + """ + return request, metadata + + def post_buffer_task( + self, response: cloudtasks.BufferTaskResponse + ) -> cloudtasks.BufferTaskResponse: + """Post-rpc interceptor for buffer_task + + Override in a subclass to manipulate the response + after it is returned by the CloudTasks server but before + it is returned to user code. + """ + return response + def pre_cancel_lease( self, request: cloudtasks.CancelLeaseRequest, @@ -604,6 +638,52 @@ def post_update_queue(self, response: gct_queue.Queue) -> gct_queue.Queue: """ return response + def pre_get_location( + self, + request: locations_pb2.GetLocationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[locations_pb2.GetLocationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_location + + Override in a subclass to manipulate the request or metadata + before they are sent to the CloudTasks server. + """ + return request, metadata + + def post_get_location( + self, response: locations_pb2.Location + ) -> locations_pb2.Location: + """Post-rpc interceptor for get_location + + Override in a subclass to manipulate the response + after it is returned by the CloudTasks server but before + it is returned to user code. + """ + return response + + def pre_list_locations( + self, + request: locations_pb2.ListLocationsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[locations_pb2.ListLocationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_locations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CloudTasks server. + """ + return request, metadata + + def post_list_locations( + self, response: locations_pb2.ListLocationsResponse + ) -> locations_pb2.ListLocationsResponse: + """Post-rpc interceptor for list_locations + + Override in a subclass to manipulate the response + after it is returned by the CloudTasks server but before + it is returned to user code. + """ + return response + @dataclasses.dataclass class CloudTasksRestStub: @@ -788,6 +868,104 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) + class _BufferTask(CloudTasksRestStub): + def __hash__(self): + return hash("BufferTask") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: cloudtasks.BufferTaskRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> cloudtasks.BufferTaskResponse: + r"""Call the buffer task method over HTTP. + + Args: + request (~.cloudtasks.BufferTaskRequest): + The request object. LINT.IfChange Request message for + [BufferTask][google.cloud.tasks.v2beta2.CloudTasks.BufferTask]. + 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: + ~.cloudtasks.BufferTaskResponse: + Response message for + [BufferTask][google.cloud.tasks.v2beta2.CloudTasks.BufferTask]. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2beta2/{queue=projects/*/locations/*/queues/*}/tasks/{task_id}:buffer", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_buffer_task(request, metadata) + pb_request = cloudtasks.BufferTaskRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # 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, strict=True), + data=body, + ) + + # 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 the response + resp = cloudtasks.BufferTaskResponse() + pb_resp = cloudtasks.BufferTaskResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_buffer_task(resp) + return resp + class _CancelLease(CloudTasksRestStub): def __hash__(self): return hash("CancelLease") @@ -2725,6 +2903,22 @@ def __call__( resp = self._interceptor.post_update_queue(resp) return resp + class _UploadQueueYaml(CloudTasksRestStub): + def __hash__(self): + return hash("UploadQueueYaml") + + def __call__( + self, + request: cloudtasks.UploadQueueYamlRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ): + raise NotImplementedError( + "Method UploadQueueYaml is not available over REST transport" + ) + @property def acknowledge_task( self, @@ -2733,6 +2927,14 @@ def acknowledge_task( # In C++ this would require a dynamic_cast return self._AcknowledgeTask(self._session, self._host, self._interceptor) # type: ignore + @property + def buffer_task( + self, + ) -> Callable[[cloudtasks.BufferTaskRequest], cloudtasks.BufferTaskResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BufferTask(self._session, self._host, self._interceptor) # type: ignore + @property def cancel_lease(self) -> Callable[[cloudtasks.CancelLeaseRequest], task.Task]: # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. @@ -2868,6 +3070,148 @@ def update_queue( # In C++ this would require a dynamic_cast return self._UpdateQueue(self._session, self._host, self._interceptor) # type: ignore + @property + def upload_queue_yaml( + self, + ) -> Callable[[cloudtasks.UploadQueueYamlRequest], empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UploadQueueYaml(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_location(self): + return self._GetLocation(self._session, self._host, self._interceptor) # type: ignore + + class _GetLocation(CloudTasksRestStub): + def __call__( + self, + request: locations_pb2.GetLocationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + + r"""Call the get location method over HTTP. + + Args: + request (locations_pb2.GetLocationRequest): + The request object for GetLocation 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: + locations_pb2.Location: Response from GetLocation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta2/{name=projects/*/locations/*}", + }, + ] + + request, metadata = self._interceptor.pre_get_location(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 = locations_pb2.Location() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_location(resp) + return resp + + @property + def list_locations(self): + return self._ListLocations(self._session, self._host, self._interceptor) # type: ignore + + class _ListLocations(CloudTasksRestStub): + def __call__( + self, + request: locations_pb2.ListLocationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + + r"""Call the list locations method over HTTP. + + Args: + request (locations_pb2.ListLocationsRequest): + The request object for ListLocations 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: + locations_pb2.ListLocationsResponse: Response from ListLocations method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta2/{name=projects/*}/locations", + }, + ] + + request, metadata = self._interceptor.pre_list_locations(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 = locations_pb2.ListLocationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_locations(resp) + return resp + @property def kind(self) -> str: return "rest" diff --git a/google/cloud/tasks_v2beta2/types/__init__.py b/google/cloud/tasks_v2beta2/types/__init__.py index e398f2c..1c68ddb 100644 --- a/google/cloud/tasks_v2beta2/types/__init__.py +++ b/google/cloud/tasks_v2beta2/types/__init__.py @@ -15,6 +15,8 @@ # from .cloudtasks import ( AcknowledgeTaskRequest, + BufferTaskRequest, + BufferTaskResponse, CancelLeaseRequest, CreateQueueRequest, CreateTaskRequest, @@ -34,6 +36,7 @@ ResumeQueueRequest, RunTaskRequest, UpdateQueueRequest, + UploadQueueYamlRequest, ) from .queue import Queue, QueueStats, RateLimits, RetryConfig from .target import ( @@ -41,13 +44,22 @@ AppEngineHttpTarget, AppEngineRouting, HttpMethod, + HttpRequest, + HttpTarget, + OAuthToken, + OidcToken, + PathOverride, PullMessage, PullTarget, + QueryOverride, + UriOverride, ) from .task import AttemptStatus, Task, TaskStatus __all__ = ( "AcknowledgeTaskRequest", + "BufferTaskRequest", + "BufferTaskResponse", "CancelLeaseRequest", "CreateQueueRequest", "CreateTaskRequest", @@ -67,6 +79,7 @@ "ResumeQueueRequest", "RunTaskRequest", "UpdateQueueRequest", + "UploadQueueYamlRequest", "Queue", "QueueStats", "RateLimits", @@ -74,8 +87,15 @@ "AppEngineHttpRequest", "AppEngineHttpTarget", "AppEngineRouting", + "HttpRequest", + "HttpTarget", + "OAuthToken", + "OidcToken", + "PathOverride", "PullMessage", "PullTarget", + "QueryOverride", + "UriOverride", "HttpMethod", "AttemptStatus", "Task", diff --git a/google/cloud/tasks_v2beta2/types/cloudtasks.py b/google/cloud/tasks_v2beta2/types/cloudtasks.py index b584d57..8a2a692 100644 --- a/google/cloud/tasks_v2beta2/types/cloudtasks.py +++ b/google/cloud/tasks_v2beta2/types/cloudtasks.py @@ -17,6 +17,7 @@ from typing import MutableMapping, MutableSequence +from google.api import httpbody_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore @@ -37,6 +38,7 @@ "PurgeQueueRequest", "PauseQueueRequest", "ResumeQueueRequest", + "UploadQueueYamlRequest", "ListTasksRequest", "ListTasksResponse", "GetTaskRequest", @@ -48,6 +50,8 @@ "RenewLeaseRequest", "CancelLeaseRequest", "RunTaskRequest", + "BufferTaskRequest", + "BufferTaskResponse", }, ) @@ -311,6 +315,39 @@ class ResumeQueueRequest(proto.Message): ) +class UploadQueueYamlRequest(proto.Message): + r"""Request message for + [UploadQueueYaml][google.cloud.tasks.v2beta2.CloudTasks.UploadQueueYaml]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + app_id (str): + Required. The App ID is supplied as an HTTP + parameter. Unlike internal usage of App ID, it + does not include a region prefix. Rather, the + App ID represents the Project ID against which + to make the request. + http_body (google.api.httpbody_pb2.HttpBody): + The http body contains the queue.yaml file + which used to update queue lists + + This field is a member of `oneof`_ ``_http_body``. + """ + + app_id: str = proto.Field( + proto.STRING, + number=1, + ) + http_body: httpbody_pb2.HttpBody = proto.Field( + proto.MESSAGE, + number=2, + optional=True, + message=httpbody_pb2.HttpBody, + ) + + class ListTasksRequest(proto.Message): r"""Request message for listing tasks using [ListTasks][google.cloud.tasks.v2beta2.CloudTasks.ListTasks]. @@ -482,10 +519,10 @@ class CreateTaskRequest(proto.Message): will fail with [ALREADY_EXISTS][google.rpc.Code.ALREADY_EXISTS]. If the task's queue was created using Cloud Tasks, then another - task with the same name can't be created for ~1hour after + task with the same name can't be created for ~1 hour after the original task was deleted or completed. If the task's queue was created using queue.yaml or queue.xml, then - another task with the same name can't be created for ~9days + another task with the same name can't be created for ~9 days after the original task was deleted or completed. Because there is an extra lookup cost to identify duplicate @@ -869,4 +906,56 @@ class RunTaskRequest(proto.Message): ) +class BufferTaskRequest(proto.Message): + r"""LINT.IfChange Request message for + [BufferTask][google.cloud.tasks.v2beta2.CloudTasks.BufferTask]. + + Attributes: + queue (str): + Required. The parent queue name. For example: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID\` + + The queue must already exist. + task_id (str): + Optional. Task ID for the task being created. + If not provided, a random task ID is assigned to + the task. + body (google.api.httpbody_pb2.HttpBody): + Optional. Body of the HTTP request. + + The body can take any generic value. The value is written to + the [HttpRequest][payload] of the [Task]. + """ + + queue: str = proto.Field( + proto.STRING, + number=1, + ) + task_id: str = proto.Field( + proto.STRING, + number=2, + ) + body: httpbody_pb2.HttpBody = proto.Field( + proto.MESSAGE, + number=3, + message=httpbody_pb2.HttpBody, + ) + + +class BufferTaskResponse(proto.Message): + r"""Response message for + [BufferTask][google.cloud.tasks.v2beta2.CloudTasks.BufferTask]. + + Attributes: + task (google.cloud.tasks_v2beta2.types.Task): + The created task. + """ + + task: gct_task.Task = proto.Field( + proto.MESSAGE, + number=1, + message=gct_task.Task, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/tasks_v2beta2/types/old_target.py b/google/cloud/tasks_v2beta2/types/old_target.py new file mode 100644 index 0000000..38179d1 --- /dev/null +++ b/google/cloud/tasks_v2beta2/types/old_target.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.tasks.v2beta2", + manifest={}, +) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/tasks_v2beta2/types/queue.py b/google/cloud/tasks_v2beta2/types/queue.py index 3ad17da..db6db09 100644 --- a/google/cloud/tasks_v2beta2/types/queue.py +++ b/google/cloud/tasks_v2beta2/types/queue.py @@ -84,6 +84,11 @@ class Queue(proto.Message): A pull queue is a queue that has a [PullTarget][google.cloud.tasks.v2beta2.PullTarget]. + This field is a member of `oneof`_ ``target_type``. + http_target (google.cloud.tasks_v2beta2.types.HttpTarget): + An http_target is used to override the target values for + HTTP tasks. + This field is a member of `oneof`_ ``target_type``. rate_limits (google.cloud.tasks_v2beta2.types.RateLimits): Rate limits for task dispatches. @@ -120,7 +125,7 @@ class Queue(proto.Message): state (google.cloud.tasks_v2beta2.types.Queue.State): Output only. The state of the queue. - ``state`` can only be changed by calling + ``state`` can only be changed by called [PauseQueue][google.cloud.tasks.v2beta2.CloudTasks.PauseQueue], [ResumeQueue][google.cloud.tasks.v2beta2.CloudTasks.ResumeQueue], or uploading @@ -239,6 +244,12 @@ class State(proto.Enum): oneof="target_type", message=target.PullTarget, ) + http_target: target.HttpTarget = proto.Field( + proto.MESSAGE, + number=17, + oneof="target_type", + message=target.HttpTarget, + ) rate_limits: "RateLimits" = proto.Field( proto.MESSAGE, number=5, diff --git a/google/cloud/tasks_v2beta2/types/target.py b/google/cloud/tasks_v2beta2/types/target.py index 0703c6b..faba695 100644 --- a/google/cloud/tasks_v2beta2/types/target.py +++ b/google/cloud/tasks_v2beta2/types/target.py @@ -28,6 +28,13 @@ "AppEngineHttpTarget", "AppEngineHttpRequest", "AppEngineRouting", + "HttpRequest", + "PathOverride", + "QueryOverride", + "UriOverride", + "HttpTarget", + "OAuthToken", + "OidcToken", }, ) @@ -48,6 +55,10 @@ class HttpMethod(proto.Enum): HTTP PUT DELETE (5): HTTP DELETE + PATCH (6): + HTTP PATCH + OPTIONS (7): + HTTP OPTIONS """ HTTP_METHOD_UNSPECIFIED = 0 POST = 1 @@ -55,6 +66,8 @@ class HttpMethod(proto.Enum): HEAD = 3 PUT = 4 DELETE = 5 + PATCH = 6 + OPTIONS = 7 class PullTarget(proto.Message): @@ -502,4 +515,505 @@ class AppEngineRouting(proto.Message): ) +class HttpRequest(proto.Message): + r"""HTTP request. + The task will be pushed to the worker as an HTTP request. An + HTTP request embodies a url, an http method, headers, body and + authorization for the http task. + + 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: + url (str): + Required. The full url path that the request will be sent + to. + + This string must begin with either "http://" or "https://". + Some examples are: ``http://acme.com`` and + ``https://acme.com/sales:8080``. Cloud Tasks will encode + some characters for safety and compatibility. The maximum + allowed URL length is 2083 characters after encoding. + + The ``Location`` header response from a redirect response + [``300`` - ``399``] may be followed. The redirect is not + counted as a separate attempt. + http_method (google.cloud.tasks_v2beta2.types.HttpMethod): + The HTTP method to use for the request. The + default is POST. + headers (MutableMapping[str, str]): + HTTP request headers. + + This map contains the header field names and values. Headers + can be set when running the [task is + created][google.cloud.tasks.v2beta2.CloudTasks.CreateTask] + or [task is + created][google.cloud.tasks.v2beta2.CloudTasks.BufferTask]. + + These headers represent a subset of the headers that will + accompany the task's HTTP request. Some HTTP request headers + will be ignored or replaced. + + A partial list of headers that will be ignored or replaced + is: + + - Any header that is prefixed with "X-CloudTasks-" will be + treated as service header. Service headers define + properties of the task and are predefined in CloudTask. + - Host: This will be computed by Cloud Tasks and derived + from + [HttpRequest.url][google.cloud.tasks.v2beta2.HttpRequest.url]. + - Content-Length: This will be computed by Cloud Tasks. + - User-Agent: This will be set to ``"Google-Cloud-Tasks"``. + - ``X-Google-*``: Google use only. + - ``X-AppEngine-*``: Google use only. + + ``Content-Type`` won't be set by Cloud Tasks. You can + explicitly set ``Content-Type`` to a media type when the + [task is + created][google.cloud.tasks.v2beta3.CloudTasks.CreateTask]. + For example, ``Content-Type`` can be set to + ``"application/octet-stream"`` or ``"application/json"``. + + Headers which can have multiple values (according to + RFC2616) can be specified using comma-separated values. + + The size of the headers must be less than 80KB. + body (bytes): + HTTP request body. + + A request body is allowed only if the [HTTP + method][google.cloud.tasks.v2beta2.HttpRequest.http_method] + is POST, PUT, or PATCH. It is an error to set body on a task + with an incompatible + [HttpMethod][google.cloud.tasks.v2beta2.HttpMethod]. + oauth_token (google.cloud.tasks_v2beta2.types.OAuthToken): + If specified, an `OAuth + token `__ + will be generated and attached as an ``Authorization`` + header in the HTTP request. + + This type of authorization should generally only be used + when calling Google APIs hosted on \*.googleapis.com. + + This field is a member of `oneof`_ ``authorization_header``. + oidc_token (google.cloud.tasks_v2beta2.types.OidcToken): + If specified, an + `OIDC `__ + token will be generated and attached as an ``Authorization`` + header in the HTTP request. + + This type of authorization can be used for many scenarios, + including calling Cloud Run, or endpoints where you intend + to validate the token yourself. + + This field is a member of `oneof`_ ``authorization_header``. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + http_method: "HttpMethod" = proto.Field( + proto.ENUM, + number=2, + enum="HttpMethod", + ) + headers: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=3, + ) + body: bytes = proto.Field( + proto.BYTES, + number=4, + ) + oauth_token: "OAuthToken" = proto.Field( + proto.MESSAGE, + number=5, + oneof="authorization_header", + message="OAuthToken", + ) + oidc_token: "OidcToken" = proto.Field( + proto.MESSAGE, + number=6, + oneof="authorization_header", + message="OidcToken", + ) + + +class PathOverride(proto.Message): + r"""PathOverride. + Path message defines path override for HTTP targets. + + Attributes: + path (str): + The URI path (e.g., /users/1234). Default is + an empty string. + """ + + path: str = proto.Field( + proto.STRING, + number=1, + ) + + +class QueryOverride(proto.Message): + r"""QueryOverride. + Query message defines query override for HTTP targets. + + Attributes: + query_params (str): + The query parameters (e.g., + qparam1=123&qparam2=456). Default is an empty + string. + """ + + query_params: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UriOverride(proto.Message): + r"""Uri Override. + When specified, all the HTTP tasks inside the queue will be + partially or fully overridden depending on the configured + values. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + scheme (google.cloud.tasks_v2beta2.types.UriOverride.Scheme): + Scheme override. + When specified, the task URI scheme is replaced + by the provided value (HTTP or HTTPS). + + This field is a member of `oneof`_ ``_scheme``. + host (str): + Host override. + + When specified, replaces the host part of the task URL. For + example, if the task URL is "https://www.google.com," and + host value is set to "example.net", the overridden URI will + be changed to "https://example.net." Host value cannot be an + empty string (INVALID_ARGUMENT). + + This field is a member of `oneof`_ ``_host``. + port (int): + Port override. + When specified, replaces the port part of the + task URI. For instance, for a URI + http://www.google.com/foo and port=123, the + overridden URI becomes + http://www.google.com:123/foo. Note that the + port value must be a positive integer. Setting + the port to 0 (Zero) clears the URI port. + + This field is a member of `oneof`_ ``_port``. + path_override (google.cloud.tasks_v2beta2.types.PathOverride): + URI path. + When specified, replaces the existing path of + the task URL. Setting the path value to an empty + string clears the URI path segment. + query_override (google.cloud.tasks_v2beta2.types.QueryOverride): + URI Query. + When specified, replaces the query part of the + task URI. Setting the query value to an empty + string clears the URI query segment. + uri_override_enforce_mode (google.cloud.tasks_v2beta2.types.UriOverride.UriOverrideEnforceMode): + URI Override Enforce Mode + When specified, determines the Target + UriOverride mode. If not specified, it defaults + to ALWAYS. + """ + + class Scheme(proto.Enum): + r"""The Scheme for an HTTP request. By default, it is HTTPS. + + Values: + SCHEME_UNSPECIFIED (0): + Scheme unspecified. Defaults to HTTPS. + HTTP (1): + Convert the scheme to HTTP, e.g., + https://www.google.ca will change to + http://www.google.ca. + HTTPS (2): + Convert the scheme to HTTPS, e.g., + http://www.google.ca will change to + https://www.google.ca. + """ + SCHEME_UNSPECIFIED = 0 + HTTP = 1 + HTTPS = 2 + + class UriOverrideEnforceMode(proto.Enum): + r"""UriOverrideEnforceMode mode is to define enforcing mode for + the override modes. + + Values: + URI_OVERRIDE_ENFORCE_MODE_UNSPECIFIED (0): + OverrideMode Unspecified. Defaults to ALWAYS. + IF_NOT_EXISTS (1): + In the IF_NOT_EXISTS mode, queue-level configuration is only + applied where task-level configuration does not exist. + ALWAYS (2): + In the ALWAYS mode, queue-level configuration + overrides all task-level configuration + """ + URI_OVERRIDE_ENFORCE_MODE_UNSPECIFIED = 0 + IF_NOT_EXISTS = 1 + ALWAYS = 2 + + scheme: Scheme = proto.Field( + proto.ENUM, + number=1, + optional=True, + enum=Scheme, + ) + host: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + port: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + path_override: "PathOverride" = proto.Field( + proto.MESSAGE, + number=4, + message="PathOverride", + ) + query_override: "QueryOverride" = proto.Field( + proto.MESSAGE, + number=5, + message="QueryOverride", + ) + uri_override_enforce_mode: UriOverrideEnforceMode = proto.Field( + proto.ENUM, + number=6, + enum=UriOverrideEnforceMode, + ) + + +class HttpTarget(proto.Message): + r"""HTTP target. + + When specified as a [Queue][target_type], all the tasks with + [HttpRequest] will be overridden according to the target. + + 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: + uri_override (google.cloud.tasks_v2beta2.types.UriOverride): + Uri override. + When specified, overrides the execution Uri for + all the tasks in the queue. + http_method (google.cloud.tasks_v2beta2.types.HttpMethod): + The HTTP method to use for the request. + + When specified, it overrides + [HttpRequest][google.cloud.tasks.v2beta2.HttpTarget.http_method] + for the task. Note that if the value is set to + [HttpMethod][GET] the [HttpRequest][body] of the task will + be ignored at execution time. + header_overrides (MutableSequence[google.cloud.tasks_v2beta2.types.HttpTarget.HeaderOverride]): + HTTP target headers. + + This map contains the header field names and values. Headers + will be set when running the [task is + created][google.cloud.tasks.v2beta2.CloudTasks.CreateTask] + and/or [task is + created][google.cloud.tasks.v2beta2.CloudTasks.BufferTask]. + + These headers represent a subset of the headers that will + accompany the task's HTTP request. Some HTTP request headers + will be ignored or replaced. + + A partial list of headers that will be ignored or replaced + is: + + - Any header that is prefixed with "X-CloudTasks-" will be + treated as service header. Service headers define + properties of the task and are predefined in CloudTask. + - Host: This will be computed by Cloud Tasks and derived + from + [HttpRequest.url][google.cloud.tasks.v2beta2.HttpRequest.url]. + - Content-Length: This will be computed by Cloud Tasks. + - User-Agent: This will be set to ``"Google-CloudTasks"``. + - ``X-Google-*``: Google use only. + - ``X-AppEngine-*``: Google use only. + + ``Content-Type`` won't be set by Cloud Tasks. You can + explicitly set ``Content-Type`` to a media type when the + [task is + created][google.cloud.tasks.v2beta3.CloudTasks.CreateTask]. + For example, ``Content-Type`` can be set to + ``"application/octet-stream"`` or ``"application/json"``. + + Headers which can have multiple values (according to + RFC2616) can be specified using comma-separated values. + + The size of the headers must be less than 80KB. Queue-level + headers to override headers of all the tasks in the queue. + oauth_token (google.cloud.tasks_v2beta2.types.OAuthToken): + If specified, an `OAuth + token `__ + will be generated and attached as an ``Authorization`` + header in the HTTP request. + + This type of authorization should generally only be used + when calling Google APIs hosted on \*.googleapis.com. + + This field is a member of `oneof`_ ``authorization_header``. + oidc_token (google.cloud.tasks_v2beta2.types.OidcToken): + If specified, an + `OIDC `__ + token will be generated and attached as an ``Authorization`` + header in the HTTP request. + + This type of authorization can be used for many scenarios, + including calling Cloud Run, or endpoints where you intend + to validate the token yourself. + + This field is a member of `oneof`_ ``authorization_header``. + """ + + class Header(proto.Message): + r"""Defines a header message. A header can have a key and a + value. + + Attributes: + key (str): + The key of the header. + value (str): + The value of the header. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + class HeaderOverride(proto.Message): + r"""Wraps the Header object. + + Attributes: + header (google.cloud.tasks_v2beta2.types.HttpTarget.Header): + header embodying a key and a value. + """ + + header: "HttpTarget.Header" = proto.Field( + proto.MESSAGE, + number=1, + message="HttpTarget.Header", + ) + + uri_override: "UriOverride" = proto.Field( + proto.MESSAGE, + number=1, + message="UriOverride", + ) + http_method: "HttpMethod" = proto.Field( + proto.ENUM, + number=2, + enum="HttpMethod", + ) + header_overrides: MutableSequence[HeaderOverride] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=HeaderOverride, + ) + oauth_token: "OAuthToken" = proto.Field( + proto.MESSAGE, + number=5, + oneof="authorization_header", + message="OAuthToken", + ) + oidc_token: "OidcToken" = proto.Field( + proto.MESSAGE, + number=6, + oneof="authorization_header", + message="OidcToken", + ) + + +class OAuthToken(proto.Message): + r"""Contains information needed for generating an `OAuth + token `__. + This type of authorization should generally only be used when + calling Google APIs hosted on \*.googleapis.com. + + Attributes: + service_account_email (str): + `Service account + email `__ + to be used for generating OAuth token. The service account + must be within the same project as the queue. The caller + must have iam.serviceAccounts.actAs permission for the + service account. + scope (str): + OAuth scope to be used for generating OAuth + access token. If not specified, + "https://www.googleapis.com/auth/cloud-platform" + will be used. + """ + + service_account_email: str = proto.Field( + proto.STRING, + number=1, + ) + scope: str = proto.Field( + proto.STRING, + number=2, + ) + + +class OidcToken(proto.Message): + r"""Contains information needed for generating an `OpenID Connect + token `__. + This type of authorization can be used for many scenarios, including + calling Cloud Run, or endpoints where you intend to validate the + token yourself. + + Attributes: + service_account_email (str): + `Service account + email `__ + to be used for generating OIDC token. The service account + must be within the same project as the queue. The caller + must have iam.serviceAccounts.actAs permission for the + service account. + audience (str): + Audience to be used when generating OIDC + token. If not specified, the URI specified in + target will be used. + """ + + service_account_email: str = proto.Field( + proto.STRING, + number=1, + ) + audience: str = proto.Field( + proto.STRING, + number=2, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/tasks_v2beta2/types/task.py b/google/cloud/tasks_v2beta2/types/task.py index 34cd7c7..3fce5b7 100644 --- a/google/cloud/tasks_v2beta2/types/task.py +++ b/google/cloud/tasks_v2beta2/types/task.py @@ -89,6 +89,13 @@ class Task(proto.Message): A pull task is a task that has [PullMessage][google.cloud.tasks.v2beta2.PullMessage] set. + This field is a member of `oneof`_ ``payload_type``. + http_request (google.cloud.tasks_v2beta2.types.HttpRequest): + HTTP request that is sent to the task's target. + + An HTTP task is a task that has + [HttpRequest][google.cloud.tasks.v2beta2.HttpRequest] set. + This field is a member of `oneof`_ ``payload_type``. schedule_time (google.protobuf.timestamp_pb2.Timestamp): The time when the task is scheduled to be attempted. @@ -167,6 +174,12 @@ class View(proto.Enum): oneof="payload_type", message=target.PullMessage, ) + http_request: target.HttpRequest = proto.Field( + proto.MESSAGE, + number=13, + oneof="payload_type", + message=target.HttpRequest, + ) schedule_time: timestamp_pb2.Timestamp = proto.Field( proto.MESSAGE, number=5, diff --git a/google/cloud/tasks_v2beta3/__init__.py b/google/cloud/tasks_v2beta3/__init__.py index 017da4e..d66d7b5 100644 --- a/google/cloud/tasks_v2beta3/__init__.py +++ b/google/cloud/tasks_v2beta3/__init__.py @@ -20,6 +20,8 @@ from .services.cloud_tasks import CloudTasksAsyncClient, CloudTasksClient from .types.cloudtasks import ( + BufferTaskRequest, + BufferTaskResponse, CreateQueueRequest, CreateTaskRequest, DeleteQueueRequest, @@ -49,9 +51,13 @@ AppEngineRouting, HttpMethod, HttpRequest, + HttpTarget, OAuthToken, OidcToken, + PathOverride, PullMessage, + QueryOverride, + UriOverride, ) from .types.task import Attempt, Task @@ -61,6 +67,8 @@ "AppEngineHttpRequest", "AppEngineRouting", "Attempt", + "BufferTaskRequest", + "BufferTaskResponse", "CloudTasksClient", "CreateQueueRequest", "CreateTaskRequest", @@ -70,15 +78,18 @@ "GetTaskRequest", "HttpMethod", "HttpRequest", + "HttpTarget", "ListQueuesRequest", "ListQueuesResponse", "ListTasksRequest", "ListTasksResponse", "OAuthToken", "OidcToken", + "PathOverride", "PauseQueueRequest", "PullMessage", "PurgeQueueRequest", + "QueryOverride", "Queue", "QueueStats", "RateLimits", @@ -88,4 +99,5 @@ "StackdriverLoggingConfig", "Task", "UpdateQueueRequest", + "UriOverride", ) diff --git a/google/cloud/tasks_v2beta3/gapic_metadata.json b/google/cloud/tasks_v2beta3/gapic_metadata.json index c4ba140..13303a8 100644 --- a/google/cloud/tasks_v2beta3/gapic_metadata.json +++ b/google/cloud/tasks_v2beta3/gapic_metadata.json @@ -10,6 +10,11 @@ "grpc": { "libraryClient": "CloudTasksClient", "rpcs": { + "BufferTask": { + "methods": [ + "buffer_task" + ] + }, "CreateQueue": { "methods": [ "create_queue" @@ -95,6 +100,11 @@ "grpc-async": { "libraryClient": "CloudTasksAsyncClient", "rpcs": { + "BufferTask": { + "methods": [ + "buffer_task" + ] + }, "CreateQueue": { "methods": [ "create_queue" @@ -180,6 +190,11 @@ "rest": { "libraryClient": "CloudTasksClient", "rpcs": { + "BufferTask": { + "methods": [ + "buffer_task" + ] + }, "CreateQueue": { "methods": [ "create_queue" diff --git a/google/cloud/tasks_v2beta3/services/cloud_tasks/async_client.py b/google/cloud/tasks_v2beta3/services/cloud_tasks/async_client.py index 2f1dad4..c36c5de 100644 --- a/google/cloud/tasks_v2beta3/services/cloud_tasks/async_client.py +++ b/google/cloud/tasks_v2beta3/services/cloud_tasks/async_client.py @@ -42,6 +42,8 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object] # type: ignore +from google.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore @@ -282,7 +284,7 @@ async def sample_list_queues(): Returns: google.cloud.tasks_v2beta3.services.cloud_tasks.pagers.ListQueuesAsyncPager: Response message for - [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues]. + [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues]. Iterating over this object will yield results and resolve additional pages automatically. @@ -1755,7 +1757,7 @@ async def sample_list_tasks(): Returns: google.cloud.tasks_v2beta3.services.cloud_tasks.pagers.ListTasksAsyncPager: Response message for listing tasks using - [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks]. + [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks]. Iterating over this object will yield results and resolve additional pages automatically. @@ -2012,11 +2014,11 @@ async def sample_create_task(): recently then the call will fail with [ALREADY_EXISTS][google.rpc.Code.ALREADY_EXISTS]. If the task's queue was created using Cloud Tasks, then another - task with the same name can't be created for ~1hour + task with the same name can't be created for ~1 hour after the original task was deleted or executed. If the task's queue was created using queue.yaml or queue.xml, then another task with the same name can't be created - for ~9days after the original task was deleted or + for ~9 days after the original task was deleted or executed. Because there is an extra lookup cost to identify @@ -2318,6 +2320,257 @@ async def sample_run_task(): # Done; return the response. return response + async def buffer_task( + self, + request: Optional[Union[cloudtasks.BufferTaskRequest, dict]] = None, + *, + queue: Optional[str] = None, + task_id: Optional[str] = None, + body: Optional[httpbody_pb2.HttpBody] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> cloudtasks.BufferTaskResponse: + r"""Creates and buffers a new task without the need to explicitly + define a Task message. The queue must have [HTTP + target][google.cloud.tasks.v2beta3.HttpTarget]. To create the + task with a custom ID, use the following format and set TASK_ID + to your desired ID: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID:buffer + To create the task with an automatically generated ID, use the + following format: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks:buffer. + Note: This feature is in its experimental stage. You must + request access to the API through the `Cloud Tasks BufferTask + Experiment Signup form `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import tasks_v2beta3 + + async def sample_buffer_task(): + # Create a client + client = tasks_v2beta3.CloudTasksAsyncClient() + + # Initialize request argument(s) + request = tasks_v2beta3.BufferTaskRequest( + queue="queue_value", + ) + + # Make the request + response = await client.buffer_task(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.tasks_v2beta3.types.BufferTaskRequest, dict]]): + The request object. Request message for + [BufferTask][google.cloud.tasks.v2beta3.CloudTasks.BufferTask]. + queue (:class:`str`): + Required. The parent queue name. For example: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID\` + + The queue must already exist. + + This corresponds to the ``queue`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + task_id (:class:`str`): + Optional. Task ID for the task being + created. If not provided, a random task + ID is assigned to the task. + + This corresponds to the ``task_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + body (:class:`google.api.httpbody_pb2.HttpBody`): + Optional. Body of the HTTP request. + + The body can take any generic value. The value is + written to the [HttpRequest][payload] of the [Task]. + + This corresponds to the ``body`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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: + google.cloud.tasks_v2beta3.types.BufferTaskResponse: + Response message for + [BufferTask][google.cloud.tasks.v2beta3.CloudTasks.BufferTask]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([queue, task_id, body]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = cloudtasks.BufferTaskRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if queue is not None: + request.queue = queue + if task_id is not None: + request.task_id = task_id + if body is not None: + request.body = body + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.buffer_task, + default_timeout=20.0, + 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( + ( + ("queue", request.queue), + ("task_id", request.task_id), + ) + ), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` 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: + ~.location_pb2.Location: + Location 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 = locations_pb2.GetLocationRequest(**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_location, + 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 list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` 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: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` 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 = locations_pb2.ListLocationsRequest(**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_locations, + 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 __aenter__(self) -> "CloudTasksAsyncClient": return self diff --git a/google/cloud/tasks_v2beta3/services/cloud_tasks/client.py b/google/cloud/tasks_v2beta3/services/cloud_tasks/client.py index 0cef18f..3342c5a 100644 --- a/google/cloud/tasks_v2beta3/services/cloud_tasks/client.py +++ b/google/cloud/tasks_v2beta3/services/cloud_tasks/client.py @@ -46,6 +46,8 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object] # type: ignore +from google.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore @@ -537,7 +539,7 @@ def sample_list_queues(): Returns: google.cloud.tasks_v2beta3.services.cloud_tasks.pagers.ListQueuesPager: Response message for - [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues]. + [ListQueues][google.cloud.tasks.v2beta3.CloudTasks.ListQueues]. Iterating over this object will yield results and resolve additional pages automatically. @@ -1952,7 +1954,7 @@ def sample_list_tasks(): Returns: google.cloud.tasks_v2beta3.services.cloud_tasks.pagers.ListTasksPager: Response message for listing tasks using - [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks]. + [ListTasks][google.cloud.tasks.v2beta3.CloudTasks.ListTasks]. Iterating over this object will yield results and resolve additional pages automatically. @@ -2189,11 +2191,11 @@ def sample_create_task(): recently then the call will fail with [ALREADY_EXISTS][google.rpc.Code.ALREADY_EXISTS]. If the task's queue was created using Cloud Tasks, then another - task with the same name can't be created for ~1hour + task with the same name can't be created for ~1 hour after the original task was deleted or executed. If the task's queue was created using queue.yaml or queue.xml, then another task with the same name can't be created - for ~9days after the original task was deleted or + for ~9 days after the original task was deleted or executed. Because there is an extra lookup cost to identify @@ -2485,6 +2487,149 @@ def sample_run_task(): # Done; return the response. return response + def buffer_task( + self, + request: Optional[Union[cloudtasks.BufferTaskRequest, dict]] = None, + *, + queue: Optional[str] = None, + task_id: Optional[str] = None, + body: Optional[httpbody_pb2.HttpBody] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> cloudtasks.BufferTaskResponse: + r"""Creates and buffers a new task without the need to explicitly + define a Task message. The queue must have [HTTP + target][google.cloud.tasks.v2beta3.HttpTarget]. To create the + task with a custom ID, use the following format and set TASK_ID + to your desired ID: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID:buffer + To create the task with an automatically generated ID, use the + following format: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks:buffer. + Note: This feature is in its experimental stage. You must + request access to the API through the `Cloud Tasks BufferTask + Experiment Signup form `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import tasks_v2beta3 + + def sample_buffer_task(): + # Create a client + client = tasks_v2beta3.CloudTasksClient() + + # Initialize request argument(s) + request = tasks_v2beta3.BufferTaskRequest( + queue="queue_value", + ) + + # Make the request + response = client.buffer_task(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.tasks_v2beta3.types.BufferTaskRequest, dict]): + The request object. Request message for + [BufferTask][google.cloud.tasks.v2beta3.CloudTasks.BufferTask]. + queue (str): + Required. The parent queue name. For example: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID\` + + The queue must already exist. + + This corresponds to the ``queue`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + task_id (str): + Optional. Task ID for the task being + created. If not provided, a random task + ID is assigned to the task. + + This corresponds to the ``task_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + body (google.api.httpbody_pb2.HttpBody): + Optional. Body of the HTTP request. + + The body can take any generic value. The value is + written to the [HttpRequest][payload] of the [Task]. + + This corresponds to the ``body`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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: + google.cloud.tasks_v2beta3.types.BufferTaskResponse: + Response message for + [BufferTask][google.cloud.tasks.v2beta3.CloudTasks.BufferTask]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([queue, task_id, body]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a cloudtasks.BufferTaskRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, cloudtasks.BufferTaskRequest): + request = cloudtasks.BufferTaskRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if queue is not None: + request.queue = queue + if task_id is not None: + request.task_id = task_id + if body is not None: + request.body = body + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.buffer_task] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ("queue", request.queue), + ("task_id", request.task_id), + ) + ), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "CloudTasksClient": return self @@ -2498,6 +2643,114 @@ def __exit__(self, type, value, traceback): """ self.transport.close() + def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` 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: + ~.location_pb2.Location: + Location 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 = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_location, + 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 list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` 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: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` 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 = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_locations, + 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 + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=package_version.__version__ diff --git a/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/base.py b/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/base.py index 8d14313..cd7b0f6 100644 --- a/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/base.py +++ b/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/base.py @@ -22,6 +22,7 @@ from google.api_core import retry as retries import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.oauth2 import service_account # type: ignore @@ -289,6 +290,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=20.0, client_info=client_info, ), + self.buffer_task: gapic_v1.method.wrap_method( + self.buffer_task, + default_timeout=20.0, + client_info=client_info, + ), } def close(self): @@ -436,6 +442,36 @@ def run_task( ) -> Callable[[cloudtasks.RunTaskRequest], Union[task.Task, Awaitable[task.Task]]]: raise NotImplementedError() + @property + def buffer_task( + self, + ) -> Callable[ + [cloudtasks.BufferTaskRequest], + Union[cloudtasks.BufferTaskResponse, Awaitable[cloudtasks.BufferTaskResponse]], + ]: + raise NotImplementedError() + + @property + def get_location( + self, + ) -> Callable[ + [locations_pb2.GetLocationRequest], + Union[locations_pb2.Location, Awaitable[locations_pb2.Location]], + ]: + raise NotImplementedError() + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], + Union[ + locations_pb2.ListLocationsResponse, + Awaitable[locations_pb2.ListLocationsResponse], + ], + ]: + raise NotImplementedError() + @property def kind(self) -> str: raise NotImplementedError() diff --git a/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/grpc.py b/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/grpc.py index 29e7d37..d7ec378 100644 --- a/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/grpc.py +++ b/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/grpc.py @@ -20,6 +20,7 @@ import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore @@ -772,9 +773,82 @@ def run_task(self) -> Callable[[cloudtasks.RunTaskRequest], task.Task]: ) return self._stubs["run_task"] + @property + def buffer_task( + self, + ) -> Callable[[cloudtasks.BufferTaskRequest], cloudtasks.BufferTaskResponse]: + r"""Return a callable for the buffer task method over gRPC. + + Creates and buffers a new task without the need to explicitly + define a Task message. The queue must have [HTTP + target][google.cloud.tasks.v2beta3.HttpTarget]. To create the + task with a custom ID, use the following format and set TASK_ID + to your desired ID: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID:buffer + To create the task with an automatically generated ID, use the + following format: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks:buffer. + Note: This feature is in its experimental stage. You must + request access to the API through the `Cloud Tasks BufferTask + Experiment Signup form `__. + + Returns: + Callable[[~.BufferTaskRequest], + ~.BufferTaskResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # 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 "buffer_task" not in self._stubs: + self._stubs["buffer_task"] = self.grpc_channel.unary_unary( + "/google.cloud.tasks.v2beta3.CloudTasks/BufferTask", + request_serializer=cloudtasks.BufferTaskRequest.serialize, + response_deserializer=cloudtasks.BufferTaskResponse.deserialize, + ) + return self._stubs["buffer_task"] + def close(self): self.grpc_channel.close() + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations 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_locations" not in self._stubs: + self._stubs["list_locations"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations 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_location" not in self._stubs: + self._stubs["get_location"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + @property def kind(self) -> str: return "grpc" diff --git a/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/grpc_asyncio.py b/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/grpc_asyncio.py index 022928d..cd48cac 100644 --- a/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/grpc_asyncio.py +++ b/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/grpc_asyncio.py @@ -19,6 +19,7 @@ from google.api_core import gapic_v1, grpc_helpers_async from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore @@ -791,8 +792,83 @@ def run_task(self) -> Callable[[cloudtasks.RunTaskRequest], Awaitable[task.Task] ) return self._stubs["run_task"] + @property + def buffer_task( + self, + ) -> Callable[ + [cloudtasks.BufferTaskRequest], Awaitable[cloudtasks.BufferTaskResponse] + ]: + r"""Return a callable for the buffer task method over gRPC. + + Creates and buffers a new task without the need to explicitly + define a Task message. The queue must have [HTTP + target][google.cloud.tasks.v2beta3.HttpTarget]. To create the + task with a custom ID, use the following format and set TASK_ID + to your desired ID: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID:buffer + To create the task with an automatically generated ID, use the + following format: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks:buffer. + Note: This feature is in its experimental stage. You must + request access to the API through the `Cloud Tasks BufferTask + Experiment Signup form `__. + + Returns: + Callable[[~.BufferTaskRequest], + Awaitable[~.BufferTaskResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # 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 "buffer_task" not in self._stubs: + self._stubs["buffer_task"] = self.grpc_channel.unary_unary( + "/google.cloud.tasks.v2beta3.CloudTasks/BufferTask", + request_serializer=cloudtasks.BufferTaskRequest.serialize, + response_deserializer=cloudtasks.BufferTaskResponse.deserialize, + ) + return self._stubs["buffer_task"] + def close(self): return self.grpc_channel.close() + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations 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_locations" not in self._stubs: + self._stubs["list_locations"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations 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_location" not in self._stubs: + self._stubs["get_location"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + __all__ = ("CloudTasksGrpcAsyncIOTransport",) diff --git a/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/rest.py b/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/rest.py index 1f4cc9e..78fe52b 100644 --- a/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/rest.py +++ b/google/cloud/tasks_v2beta3/services/cloud_tasks/transports/rest.py @@ -26,6 +26,7 @@ from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore from google.protobuf import json_format import grpc # type: ignore from requests import __version__ as requests_version @@ -71,6 +72,14 @@ class CloudTasksRestInterceptor: .. code-block:: python class MyCustomCloudTasksInterceptor(CloudTasksRestInterceptor): + def pre_buffer_task(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_buffer_task(self, response): + logging.log(f"Received response: {response}") + return response + def pre_create_queue(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -197,6 +206,27 @@ def post_update_queue(self, response): """ + def pre_buffer_task( + self, request: cloudtasks.BufferTaskRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[cloudtasks.BufferTaskRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for buffer_task + + Override in a subclass to manipulate the request or metadata + before they are sent to the CloudTasks server. + """ + return request, metadata + + def post_buffer_task( + self, response: cloudtasks.BufferTaskResponse + ) -> cloudtasks.BufferTaskResponse: + """Post-rpc interceptor for buffer_task + + Override in a subclass to manipulate the response + after it is returned by the CloudTasks server but before + it is returned to user code. + """ + return response + def pre_create_queue( self, request: cloudtasks.CreateQueueRequest, @@ -503,6 +533,52 @@ def post_update_queue(self, response: gct_queue.Queue) -> gct_queue.Queue: """ return response + def pre_get_location( + self, + request: locations_pb2.GetLocationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[locations_pb2.GetLocationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_location + + Override in a subclass to manipulate the request or metadata + before they are sent to the CloudTasks server. + """ + return request, metadata + + def post_get_location( + self, response: locations_pb2.Location + ) -> locations_pb2.Location: + """Post-rpc interceptor for get_location + + Override in a subclass to manipulate the response + after it is returned by the CloudTasks server but before + it is returned to user code. + """ + return response + + def pre_list_locations( + self, + request: locations_pb2.ListLocationsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[locations_pb2.ListLocationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_locations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CloudTasks server. + """ + return request, metadata + + def post_list_locations( + self, response: locations_pb2.ListLocationsResponse + ) -> locations_pb2.ListLocationsResponse: + """Post-rpc interceptor for list_locations + + Override in a subclass to manipulate the response + after it is returned by the CloudTasks server but before + it is returned to user code. + """ + return response + @dataclasses.dataclass class CloudTasksRestStub: @@ -601,6 +677,104 @@ def __init__( self._interceptor = interceptor or CloudTasksRestInterceptor() self._prep_wrapped_messages(client_info) + class _BufferTask(CloudTasksRestStub): + def __hash__(self): + return hash("BufferTask") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: cloudtasks.BufferTaskRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> cloudtasks.BufferTaskResponse: + r"""Call the buffer task method over HTTP. + + Args: + request (~.cloudtasks.BufferTaskRequest): + The request object. Request message for + [BufferTask][google.cloud.tasks.v2beta3.CloudTasks.BufferTask]. + 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: + ~.cloudtasks.BufferTaskResponse: + Response message for + [BufferTask][google.cloud.tasks.v2beta3.CloudTasks.BufferTask]. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2beta3/{queue=projects/*/locations/*/queues/*}/tasks/{task_id}:buffer", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_buffer_task(request, metadata) + pb_request = cloudtasks.BufferTaskRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # 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, strict=True), + data=body, + ) + + # 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 the response + resp = cloudtasks.BufferTaskResponse() + pb_resp = cloudtasks.BufferTaskResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_buffer_task(resp) + return resp + class _CreateQueue(CloudTasksRestStub): def __hash__(self): return hash("CreateQueue") @@ -2248,6 +2422,14 @@ def __call__( resp = self._interceptor.post_update_queue(resp) return resp + @property + def buffer_task( + self, + ) -> Callable[[cloudtasks.BufferTaskRequest], cloudtasks.BufferTaskResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BufferTask(self._session, self._host, self._interceptor) # type: ignore + @property def create_queue( self, @@ -2363,6 +2545,140 @@ def update_queue( # In C++ this would require a dynamic_cast return self._UpdateQueue(self._session, self._host, self._interceptor) # type: ignore + @property + def get_location(self): + return self._GetLocation(self._session, self._host, self._interceptor) # type: ignore + + class _GetLocation(CloudTasksRestStub): + def __call__( + self, + request: locations_pb2.GetLocationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + + r"""Call the get location method over HTTP. + + Args: + request (locations_pb2.GetLocationRequest): + The request object for GetLocation 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: + locations_pb2.Location: Response from GetLocation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta3/{name=projects/*/locations/*}", + }, + ] + + request, metadata = self._interceptor.pre_get_location(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 = locations_pb2.Location() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_location(resp) + return resp + + @property + def list_locations(self): + return self._ListLocations(self._session, self._host, self._interceptor) # type: ignore + + class _ListLocations(CloudTasksRestStub): + def __call__( + self, + request: locations_pb2.ListLocationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + + r"""Call the list locations method over HTTP. + + Args: + request (locations_pb2.ListLocationsRequest): + The request object for ListLocations 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: + locations_pb2.ListLocationsResponse: Response from ListLocations method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta3/{name=projects/*}/locations", + }, + ] + + request, metadata = self._interceptor.pre_list_locations(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 = locations_pb2.ListLocationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_locations(resp) + return resp + @property def kind(self) -> str: return "rest" diff --git a/google/cloud/tasks_v2beta3/types/__init__.py b/google/cloud/tasks_v2beta3/types/__init__.py index bde999b..77d5ff3 100644 --- a/google/cloud/tasks_v2beta3/types/__init__.py +++ b/google/cloud/tasks_v2beta3/types/__init__.py @@ -14,6 +14,8 @@ # limitations under the License. # from .cloudtasks import ( + BufferTaskRequest, + BufferTaskResponse, CreateQueueRequest, CreateTaskRequest, DeleteQueueRequest, @@ -37,13 +39,19 @@ AppEngineRouting, HttpMethod, HttpRequest, + HttpTarget, OAuthToken, OidcToken, + PathOverride, PullMessage, + QueryOverride, + UriOverride, ) from .task import Attempt, Task __all__ = ( + "BufferTaskRequest", + "BufferTaskResponse", "CreateQueueRequest", "CreateTaskRequest", "DeleteQueueRequest", @@ -68,9 +76,13 @@ "AppEngineHttpRequest", "AppEngineRouting", "HttpRequest", + "HttpTarget", "OAuthToken", "OidcToken", + "PathOverride", "PullMessage", + "QueryOverride", + "UriOverride", "HttpMethod", "Attempt", "Task", diff --git a/google/cloud/tasks_v2beta3/types/cloudtasks.py b/google/cloud/tasks_v2beta3/types/cloudtasks.py index c03df5b..04169d1 100644 --- a/google/cloud/tasks_v2beta3/types/cloudtasks.py +++ b/google/cloud/tasks_v2beta3/types/cloudtasks.py @@ -17,6 +17,7 @@ from typing import MutableMapping, MutableSequence +from google.api import httpbody_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore import proto # type: ignore @@ -41,6 +42,8 @@ "CreateTaskRequest", "DeleteTaskRequest", "RunTaskRequest", + "BufferTaskRequest", + "BufferTaskResponse", }, ) @@ -475,10 +478,10 @@ class CreateTaskRequest(proto.Message): will fail with [ALREADY_EXISTS][google.rpc.Code.ALREADY_EXISTS]. If the task's queue was created using Cloud Tasks, then another - task with the same name can't be created for ~1hour after + task with the same name can't be created for ~1 hour after the original task was deleted or executed. If the task's queue was created using queue.yaml or queue.xml, then - another task with the same name can't be created for ~9days + another task with the same name can't be created for ~9 days after the original task was deleted or executed. Because there is an extra lookup cost to identify duplicate @@ -579,4 +582,56 @@ class RunTaskRequest(proto.Message): ) +class BufferTaskRequest(proto.Message): + r"""Request message for + [BufferTask][google.cloud.tasks.v2beta3.CloudTasks.BufferTask]. + + Attributes: + queue (str): + Required. The parent queue name. For example: + projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID\` + + The queue must already exist. + task_id (str): + Optional. Task ID for the task being created. + If not provided, a random task ID is assigned to + the task. + body (google.api.httpbody_pb2.HttpBody): + Optional. Body of the HTTP request. + + The body can take any generic value. The value is written to + the [HttpRequest][payload] of the [Task]. + """ + + queue: str = proto.Field( + proto.STRING, + number=1, + ) + task_id: str = proto.Field( + proto.STRING, + number=2, + ) + body: httpbody_pb2.HttpBody = proto.Field( + proto.MESSAGE, + number=3, + message=httpbody_pb2.HttpBody, + ) + + +class BufferTaskResponse(proto.Message): + r"""Response message for + [BufferTask][google.cloud.tasks.v2beta3.CloudTasks.BufferTask]. + + Attributes: + task (google.cloud.tasks_v2beta3.types.Task): + The created task. + """ + + task: gct_task.Task = proto.Field( + proto.MESSAGE, + number=1, + message=gct_task.Task, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/tasks_v2beta3/types/queue.py b/google/cloud/tasks_v2beta3/types/queue.py index fd8a9e4..9aa3eff 100644 --- a/google/cloud/tasks_v2beta3/types/queue.py +++ b/google/cloud/tasks_v2beta3/types/queue.py @@ -77,6 +77,8 @@ class Queue(proto.Message): affected by this proto. This field is a member of `oneof`_ ``queue_type``. + http_target (google.cloud.tasks_v2beta3.types.HttpTarget): + Modifies HTTP target for HTTP tasks. rate_limits (google.cloud.tasks_v2beta3.types.RateLimits): Rate limits for task dispatches. @@ -125,7 +127,7 @@ class Queue(proto.Message): state (google.cloud.tasks_v2beta3.types.Queue.State): Output only. The state of the queue. - ``state`` can only be changed by calling + ``state`` can only be changed by called [PauseQueue][google.cloud.tasks.v2beta3.CloudTasks.PauseQueue], [ResumeQueue][google.cloud.tasks.v2beta3.CloudTasks.ResumeQueue], or uploading @@ -258,6 +260,11 @@ class Type(proto.Enum): oneof="queue_type", message=target.AppEngineHttpQueue, ) + http_target: target.HttpTarget = proto.Field( + proto.MESSAGE, + number=13, + message=target.HttpTarget, + ) rate_limits: "RateLimits" = proto.Field( proto.MESSAGE, number=4, diff --git a/google/cloud/tasks_v2beta3/types/target.py b/google/cloud/tasks_v2beta3/types/target.py index 71d59ef..4850ed8 100644 --- a/google/cloud/tasks_v2beta3/types/target.py +++ b/google/cloud/tasks_v2beta3/types/target.py @@ -24,6 +24,10 @@ manifest={ "HttpMethod", "PullMessage", + "PathOverride", + "QueryOverride", + "UriOverride", + "HttpTarget", "HttpRequest", "AppEngineHttpQueue", "AppEngineHttpRequest", @@ -103,6 +107,314 @@ class PullMessage(proto.Message): ) +class PathOverride(proto.Message): + r"""PathOverride. + Path message defines path override for HTTP targets. + + Attributes: + path (str): + The URI path (e.g., /users/1234). Default is + an empty string. + """ + + path: str = proto.Field( + proto.STRING, + number=1, + ) + + +class QueryOverride(proto.Message): + r"""QueryOverride. + Query message defines query override for HTTP targets. + + Attributes: + query_params (str): + The query parameters (e.g., + qparam1=123&qparam2=456). Default is an empty + string. + """ + + query_params: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UriOverride(proto.Message): + r"""URI Override. + When specified, all the HTTP tasks inside the queue will be + partially or fully overridden depending on the configured + values. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + scheme (google.cloud.tasks_v2beta3.types.UriOverride.Scheme): + Scheme override. + When specified, the task URI scheme is replaced + by the provided value (HTTP or HTTPS). + + This field is a member of `oneof`_ ``_scheme``. + host (str): + Host override. + + When specified, replaces the host part of the task URL. For + example, if the task URL is "https://www.google.com," and + host value is set to "example.net", the overridden URI will + be changed to "https://example.net." Host value cannot be an + empty string (INVALID_ARGUMENT). + + This field is a member of `oneof`_ ``_host``. + port (int): + Port override. + When specified, replaces the port part of the + task URI. For instance, for a URI + http://www.google.com/foo and port=123, the + overridden URI becomes + http://www.google.com:123/foo. Note that the + port value must be a positive integer. Setting + the port to 0 (Zero) clears the URI port. + + This field is a member of `oneof`_ ``_port``. + path_override (google.cloud.tasks_v2beta3.types.PathOverride): + URI path. + When specified, replaces the existing path of + the task URL. Setting the path value to an empty + string clears the URI path segment. + query_override (google.cloud.tasks_v2beta3.types.QueryOverride): + URI Query. + When specified, replaces the query part of the + task URI. Setting the query value to an empty + string clears the URI query segment. + uri_override_enforce_mode (google.cloud.tasks_v2beta3.types.UriOverride.UriOverrideEnforceMode): + URI Override Enforce Mode + When specified, determines the Target + UriOverride mode. If not specified, it defaults + to ALWAYS. + """ + + class Scheme(proto.Enum): + r"""The Scheme for an HTTP request. By default, it is HTTPS. + + Values: + SCHEME_UNSPECIFIED (0): + Scheme unspecified. Defaults to HTTPS. + HTTP (1): + Convert the scheme to HTTP, e.g., + https://www.google.ca will change to + http://www.google.ca. + HTTPS (2): + Convert the scheme to HTTPS, e.g., + http://www.google.ca will change to + https://www.google.ca. + """ + SCHEME_UNSPECIFIED = 0 + HTTP = 1 + HTTPS = 2 + + class UriOverrideEnforceMode(proto.Enum): + r"""UriOverrideEnforceMode mode is to define enforcing mode for + the override modes. + + Values: + URI_OVERRIDE_ENFORCE_MODE_UNSPECIFIED (0): + OverrideMode Unspecified. Defaults to ALWAYS. + IF_NOT_EXISTS (1): + In the IF_NOT_EXISTS mode, queue-level configuration is only + applied where task-level configuration does not exist. + ALWAYS (2): + In the ALWAYS mode, queue-level configuration + overrides all task-level configuration + """ + URI_OVERRIDE_ENFORCE_MODE_UNSPECIFIED = 0 + IF_NOT_EXISTS = 1 + ALWAYS = 2 + + scheme: Scheme = proto.Field( + proto.ENUM, + number=1, + optional=True, + enum=Scheme, + ) + host: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + port: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + path_override: "PathOverride" = proto.Field( + proto.MESSAGE, + number=4, + message="PathOverride", + ) + query_override: "QueryOverride" = proto.Field( + proto.MESSAGE, + number=5, + message="QueryOverride", + ) + uri_override_enforce_mode: UriOverrideEnforceMode = proto.Field( + proto.ENUM, + number=6, + enum=UriOverrideEnforceMode, + ) + + +class HttpTarget(proto.Message): + r"""HTTP target. + + When specified as a [Queue][target_type], all the tasks with + [HttpRequest] will be overridden according to the target. + + 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: + uri_override (google.cloud.tasks_v2beta3.types.UriOverride): + URI override. + When specified, overrides the execution URI for + all the tasks in the queue. + http_method (google.cloud.tasks_v2beta3.types.HttpMethod): + The HTTP method to use for the request. + + When specified, it overrides + [HttpRequest][google.cloud.tasks.v2beta3.HttpTarget.http_method] + for the task. Note that if the value is set to + [HttpMethod][GET] the [HttpRequest][body] of the task will + be ignored at execution time. + header_overrides (MutableSequence[google.cloud.tasks_v2beta3.types.HttpTarget.HeaderOverride]): + HTTP target headers. + + This map contains the header field names and values. Headers + will be set when running the + [CreateTask][google.cloud.tasks.v2beta3.CloudTasks.CreateTask] + and/or + [BufferTask][google.cloud.tasks.v2beta3.CloudTasks.BufferTask]. + + These headers represent a subset of the headers that will be + configured for the task's HTTP request. Some HTTP request + headers will be ignored or replaced. + + A partial list of headers that will be ignored or replaced + is: + + - Several predefined headers, prefixed with + "X-CloudTasks-", can be used to define properties of the + task. + - Host: This will be computed by Cloud Tasks and derived + from + [HttpRequest.url][google.cloud.tasks.v2beta3.Target.HttpRequest.url]. + - Content-Length: This will be computed by Cloud Tasks. + + ``Content-Type`` won't be set by Cloud Tasks. You can + explicitly set ``Content-Type`` to a media type when the + [task is + created][google.cloud.tasks.v2beta3.CloudTasks.CreateTask]. + For example,\ ``Content-Type`` can be set to + ``"application/octet-stream"`` or ``"application/json"``. + The default value is set to ``"application/json"``. + + - User-Agent: This will be set to ``"Google-Cloud-Tasks"``. + + Headers which can have multiple values (according to + RFC2616) can be specified using comma-separated values. + + The size of the headers must be less than 80KB. Queue-level + headers to override headers of all the tasks in the queue. + oauth_token (google.cloud.tasks_v2beta3.types.OAuthToken): + If specified, an `OAuth + token `__ + will be generated and attached as the ``Authorization`` + header in the HTTP request. + + This type of authorization should generally only be used + when calling Google APIs hosted on \*.googleapis.com. + + This field is a member of `oneof`_ ``authorization_header``. + oidc_token (google.cloud.tasks_v2beta3.types.OidcToken): + If specified, an + `OIDC `__ + token will be generated and attached as an ``Authorization`` + header in the HTTP request. + + This type of authorization can be used for many scenarios, + including calling Cloud Run, or endpoints where you intend + to validate the token yourself. + + This field is a member of `oneof`_ ``authorization_header``. + """ + + class Header(proto.Message): + r"""Defines a header message. A header can have a key and a + value. + + Attributes: + key (str): + The Key of the header. + value (str): + The Value of the header. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + class HeaderOverride(proto.Message): + r"""Wraps the Header object. + + Attributes: + header (google.cloud.tasks_v2beta3.types.HttpTarget.Header): + header embodying a key and a value. + """ + + header: "HttpTarget.Header" = proto.Field( + proto.MESSAGE, + number=1, + message="HttpTarget.Header", + ) + + uri_override: "UriOverride" = proto.Field( + proto.MESSAGE, + number=1, + message="UriOverride", + ) + http_method: "HttpMethod" = proto.Field( + proto.ENUM, + number=2, + enum="HttpMethod", + ) + header_overrides: MutableSequence[HeaderOverride] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=HeaderOverride, + ) + oauth_token: "OAuthToken" = proto.Field( + proto.MESSAGE, + number=5, + oneof="authorization_header", + message="OAuthToken", + ) + oidc_token: "OidcToken" = proto.Field( + proto.MESSAGE, + number=6, + oneof="authorization_header", + message="OidcToken", + ) + + class HttpRequest(proto.Message): r"""HTTP request. @@ -177,6 +489,9 @@ class HttpRequest(proto.Message): A partial list of headers that will be ignored or replaced is: + - Any header that is prefixed with "X-CloudTasks-" will be + treated as service header. Service headers define + properties of the task and are predefined in CloudTask. - Host: This will be computed by Cloud Tasks and derived from [HttpRequest.url][google.cloud.tasks.v2beta3.HttpRequest.url]. diff --git a/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_buffer_task_async.py b/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_buffer_task_async.py new file mode 100644 index 0000000..1c86ed3 --- /dev/null +++ b/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_buffer_task_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BufferTask +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-tasks + + +# [START cloudtasks_v2beta2_generated_CloudTasks_BufferTask_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import tasks_v2beta2 + + +async def sample_buffer_task(): + # Create a client + client = tasks_v2beta2.CloudTasksAsyncClient() + + # Initialize request argument(s) + request = tasks_v2beta2.BufferTaskRequest( + queue="queue_value", + ) + + # Make the request + response = await client.buffer_task(request=request) + + # Handle the response + print(response) + +# [END cloudtasks_v2beta2_generated_CloudTasks_BufferTask_async] diff --git a/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_buffer_task_sync.py b/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_buffer_task_sync.py new file mode 100644 index 0000000..c6e1043 --- /dev/null +++ b/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_buffer_task_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BufferTask +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-tasks + + +# [START cloudtasks_v2beta2_generated_CloudTasks_BufferTask_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import tasks_v2beta2 + + +def sample_buffer_task(): + # Create a client + client = tasks_v2beta2.CloudTasksClient() + + # Initialize request argument(s) + request = tasks_v2beta2.BufferTaskRequest( + queue="queue_value", + ) + + # Make the request + response = client.buffer_task(request=request) + + # Handle the response + print(response) + +# [END cloudtasks_v2beta2_generated_CloudTasks_BufferTask_sync] diff --git a/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_upload_queue_yaml_async.py b/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_upload_queue_yaml_async.py new file mode 100644 index 0000000..d7f9650 --- /dev/null +++ b/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_upload_queue_yaml_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UploadQueueYaml +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-tasks + + +# [START cloudtasks_v2beta2_generated_CloudTasks_UploadQueueYaml_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import tasks_v2beta2 + + +async def sample_upload_queue_yaml(): + # Create a client + client = tasks_v2beta2.CloudTasksAsyncClient() + + # Initialize request argument(s) + request = tasks_v2beta2.UploadQueueYamlRequest( + app_id="app_id_value", + ) + + # Make the request + await client.upload_queue_yaml(request=request) + + +# [END cloudtasks_v2beta2_generated_CloudTasks_UploadQueueYaml_async] diff --git a/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_upload_queue_yaml_sync.py b/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_upload_queue_yaml_sync.py new file mode 100644 index 0000000..1e7e4a3 --- /dev/null +++ b/samples/generated_samples/cloudtasks_v2beta2_generated_cloud_tasks_upload_queue_yaml_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UploadQueueYaml +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-tasks + + +# [START cloudtasks_v2beta2_generated_CloudTasks_UploadQueueYaml_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import tasks_v2beta2 + + +def sample_upload_queue_yaml(): + # Create a client + client = tasks_v2beta2.CloudTasksClient() + + # Initialize request argument(s) + request = tasks_v2beta2.UploadQueueYamlRequest( + app_id="app_id_value", + ) + + # Make the request + client.upload_queue_yaml(request=request) + + +# [END cloudtasks_v2beta2_generated_CloudTasks_UploadQueueYaml_sync] diff --git a/samples/generated_samples/cloudtasks_v2beta3_generated_cloud_tasks_buffer_task_async.py b/samples/generated_samples/cloudtasks_v2beta3_generated_cloud_tasks_buffer_task_async.py new file mode 100644 index 0000000..2b57ea3 --- /dev/null +++ b/samples/generated_samples/cloudtasks_v2beta3_generated_cloud_tasks_buffer_task_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BufferTask +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-tasks + + +# [START cloudtasks_v2beta3_generated_CloudTasks_BufferTask_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import tasks_v2beta3 + + +async def sample_buffer_task(): + # Create a client + client = tasks_v2beta3.CloudTasksAsyncClient() + + # Initialize request argument(s) + request = tasks_v2beta3.BufferTaskRequest( + queue="queue_value", + ) + + # Make the request + response = await client.buffer_task(request=request) + + # Handle the response + print(response) + +# [END cloudtasks_v2beta3_generated_CloudTasks_BufferTask_async] diff --git a/samples/generated_samples/cloudtasks_v2beta3_generated_cloud_tasks_buffer_task_sync.py b/samples/generated_samples/cloudtasks_v2beta3_generated_cloud_tasks_buffer_task_sync.py new file mode 100644 index 0000000..246b167 --- /dev/null +++ b/samples/generated_samples/cloudtasks_v2beta3_generated_cloud_tasks_buffer_task_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BufferTask +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-tasks + + +# [START cloudtasks_v2beta3_generated_CloudTasks_BufferTask_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import tasks_v2beta3 + + +def sample_buffer_task(): + # Create a client + client = tasks_v2beta3.CloudTasksClient() + + # Initialize request argument(s) + request = tasks_v2beta3.BufferTaskRequest( + queue="queue_value", + ) + + # Make the request + response = client.buffer_task(request=request) + + # Handle the response + print(response) + +# [END cloudtasks_v2beta3_generated_CloudTasks_BufferTask_sync] diff --git a/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta2.json b/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta2.json index 006a84e..9f72991 100644 --- a/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta2.json +++ b/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta2.json @@ -174,6 +174,183 @@ ], "title": "cloudtasks_v2beta2_generated_cloud_tasks_acknowledge_task_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.tasks_v2beta2.CloudTasksAsyncClient", + "shortName": "CloudTasksAsyncClient" + }, + "fullName": "google.cloud.tasks_v2beta2.CloudTasksAsyncClient.buffer_task", + "method": { + "fullName": "google.cloud.tasks.v2beta2.CloudTasks.BufferTask", + "service": { + "fullName": "google.cloud.tasks.v2beta2.CloudTasks", + "shortName": "CloudTasks" + }, + "shortName": "BufferTask" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.tasks_v2beta2.types.BufferTaskRequest" + }, + { + "name": "queue", + "type": "str" + }, + { + "name": "task_id", + "type": "str" + }, + { + "name": "body", + "type": "google.api.httpbody_pb2.HttpBody" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.tasks_v2beta2.types.BufferTaskResponse", + "shortName": "buffer_task" + }, + "description": "Sample for BufferTask", + "file": "cloudtasks_v2beta2_generated_cloud_tasks_buffer_task_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudtasks_v2beta2_generated_CloudTasks_BufferTask_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudtasks_v2beta2_generated_cloud_tasks_buffer_task_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.tasks_v2beta2.CloudTasksClient", + "shortName": "CloudTasksClient" + }, + "fullName": "google.cloud.tasks_v2beta2.CloudTasksClient.buffer_task", + "method": { + "fullName": "google.cloud.tasks.v2beta2.CloudTasks.BufferTask", + "service": { + "fullName": "google.cloud.tasks.v2beta2.CloudTasks", + "shortName": "CloudTasks" + }, + "shortName": "BufferTask" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.tasks_v2beta2.types.BufferTaskRequest" + }, + { + "name": "queue", + "type": "str" + }, + { + "name": "task_id", + "type": "str" + }, + { + "name": "body", + "type": "google.api.httpbody_pb2.HttpBody" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.tasks_v2beta2.types.BufferTaskResponse", + "shortName": "buffer_task" + }, + "description": "Sample for BufferTask", + "file": "cloudtasks_v2beta2_generated_cloud_tasks_buffer_task_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudtasks_v2beta2_generated_CloudTasks_BufferTask_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudtasks_v2beta2_generated_cloud_tasks_buffer_task_sync.py" + }, { "canonical": true, "clientMethod": { @@ -3284,6 +3461,153 @@ } ], "title": "cloudtasks_v2beta2_generated_cloud_tasks_update_queue_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.tasks_v2beta2.CloudTasksAsyncClient", + "shortName": "CloudTasksAsyncClient" + }, + "fullName": "google.cloud.tasks_v2beta2.CloudTasksAsyncClient.upload_queue_yaml", + "method": { + "fullName": "google.cloud.tasks.v2beta2.CloudTasks.UploadQueueYaml", + "service": { + "fullName": "google.cloud.tasks.v2beta2.CloudTasks", + "shortName": "CloudTasks" + }, + "shortName": "UploadQueueYaml" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.tasks_v2beta2.types.UploadQueueYamlRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "upload_queue_yaml" + }, + "description": "Sample for UploadQueueYaml", + "file": "cloudtasks_v2beta2_generated_cloud_tasks_upload_queue_yaml_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudtasks_v2beta2_generated_CloudTasks_UploadQueueYaml_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudtasks_v2beta2_generated_cloud_tasks_upload_queue_yaml_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.tasks_v2beta2.CloudTasksClient", + "shortName": "CloudTasksClient" + }, + "fullName": "google.cloud.tasks_v2beta2.CloudTasksClient.upload_queue_yaml", + "method": { + "fullName": "google.cloud.tasks.v2beta2.CloudTasks.UploadQueueYaml", + "service": { + "fullName": "google.cloud.tasks.v2beta2.CloudTasks", + "shortName": "CloudTasks" + }, + "shortName": "UploadQueueYaml" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.tasks_v2beta2.types.UploadQueueYamlRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "upload_queue_yaml" + }, + "description": "Sample for UploadQueueYaml", + "file": "cloudtasks_v2beta2_generated_cloud_tasks_upload_queue_yaml_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudtasks_v2beta2_generated_CloudTasks_UploadQueueYaml_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudtasks_v2beta2_generated_cloud_tasks_upload_queue_yaml_sync.py" } ] } diff --git a/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta3.json b/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta3.json index 788516e..c5d7f81 100644 --- a/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta3.json +++ b/samples/generated_samples/snippet_metadata_google.cloud.tasks.v2beta3.json @@ -11,6 +11,183 @@ "version": "0.1.0" }, "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.tasks_v2beta3.CloudTasksAsyncClient", + "shortName": "CloudTasksAsyncClient" + }, + "fullName": "google.cloud.tasks_v2beta3.CloudTasksAsyncClient.buffer_task", + "method": { + "fullName": "google.cloud.tasks.v2beta3.CloudTasks.BufferTask", + "service": { + "fullName": "google.cloud.tasks.v2beta3.CloudTasks", + "shortName": "CloudTasks" + }, + "shortName": "BufferTask" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.tasks_v2beta3.types.BufferTaskRequest" + }, + { + "name": "queue", + "type": "str" + }, + { + "name": "task_id", + "type": "str" + }, + { + "name": "body", + "type": "google.api.httpbody_pb2.HttpBody" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.tasks_v2beta3.types.BufferTaskResponse", + "shortName": "buffer_task" + }, + "description": "Sample for BufferTask", + "file": "cloudtasks_v2beta3_generated_cloud_tasks_buffer_task_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudtasks_v2beta3_generated_CloudTasks_BufferTask_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudtasks_v2beta3_generated_cloud_tasks_buffer_task_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.tasks_v2beta3.CloudTasksClient", + "shortName": "CloudTasksClient" + }, + "fullName": "google.cloud.tasks_v2beta3.CloudTasksClient.buffer_task", + "method": { + "fullName": "google.cloud.tasks.v2beta3.CloudTasks.BufferTask", + "service": { + "fullName": "google.cloud.tasks.v2beta3.CloudTasks", + "shortName": "CloudTasks" + }, + "shortName": "BufferTask" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.tasks_v2beta3.types.BufferTaskRequest" + }, + { + "name": "queue", + "type": "str" + }, + { + "name": "task_id", + "type": "str" + }, + { + "name": "body", + "type": "google.api.httpbody_pb2.HttpBody" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.tasks_v2beta3.types.BufferTaskResponse", + "shortName": "buffer_task" + }, + "description": "Sample for BufferTask", + "file": "cloudtasks_v2beta3_generated_cloud_tasks_buffer_task_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudtasks_v2beta3_generated_CloudTasks_BufferTask_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudtasks_v2beta3_generated_cloud_tasks_buffer_task_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/scripts/fixup_tasks_v2beta2_keywords.py b/scripts/fixup_tasks_v2beta2_keywords.py index bf77a59..a585e51 100644 --- a/scripts/fixup_tasks_v2beta2_keywords.py +++ b/scripts/fixup_tasks_v2beta2_keywords.py @@ -40,6 +40,7 @@ class tasksCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { 'acknowledge_task': ('name', 'schedule_time', ), + 'buffer_task': ('queue', 'task_id', 'body', ), 'cancel_lease': ('name', 'schedule_time', 'response_view', ), 'create_queue': ('parent', 'queue', ), 'create_task': ('parent', 'task', 'response_view', ), @@ -59,6 +60,7 @@ class tasksCallTransformer(cst.CSTTransformer): 'set_iam_policy': ('resource', 'policy', 'update_mask', ), 'test_iam_permissions': ('resource', 'permissions', ), 'update_queue': ('queue', 'update_mask', ), + 'upload_queue_yaml': ('app_id', 'http_body', ), } def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: diff --git a/scripts/fixup_tasks_v2beta3_keywords.py b/scripts/fixup_tasks_v2beta3_keywords.py index 815c58e..d08dd32 100644 --- a/scripts/fixup_tasks_v2beta3_keywords.py +++ b/scripts/fixup_tasks_v2beta3_keywords.py @@ -39,6 +39,7 @@ def partition( class tasksCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'buffer_task': ('queue', 'task_id', 'body', ), 'create_queue': ('parent', 'queue', ), 'create_task': ('parent', 'task', 'response_view', ), 'delete_queue': ('name', ), diff --git a/tests/unit/gapic/tasks_v2/test_cloud_tasks.py b/tests/unit/gapic/tasks_v2/test_cloud_tasks.py index 06384b5..1a7a193 100644 --- a/tests/unit/gapic/tasks_v2/test_cloud_tasks.py +++ b/tests/unit/gapic/tasks_v2/test_cloud_tasks.py @@ -32,6 +32,7 @@ import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import options_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore @@ -9580,6 +9581,8 @@ def test_cloud_tasks_base_transport(): "create_task", "delete_task", "run_task", + "get_location", + "list_locations", ) for method in methods: with pytest.raises(NotImplementedError): @@ -10200,6 +10203,406 @@ async def test_transport_close_async(): close.assert_called_once() +def test_get_location_rest_bad_request( + transport: str = "rest", request_type=locations_pb2.GetLocationRequest +): + client = CloudTasksClient( + 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.get_location(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.GetLocationRequest, + dict, + ], +) +def test_get_location_rest(request_type): + client = CloudTasksClient( + 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 = locations_pb2.Location() + + # 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_location(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_list_locations_rest_bad_request( + transport: str = "rest", request_type=locations_pb2.ListLocationsRequest +): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({"name": "projects/sample1"}, 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_locations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.ListLocationsRequest, + dict, + ], +) +def test_list_locations_rest(request_type): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1"} + 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 = locations_pb2.ListLocationsResponse() + + # 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_locations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_list_locations(transport: str = "grpc"): + client = CloudTasksClient( + 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 = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + response = client.list_locations(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, locations_pb2.ListLocationsResponse) + + +@pytest.mark.asyncio +async def test_list_locations_async(transport: str = "grpc"): + client = CloudTasksAsyncClient( + 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 = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations(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, locations_pb2.ListLocationsResponse) + + +def test_list_locations_field_headers(): + client = CloudTasksClient( + 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 = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = locations_pb2.ListLocationsResponse() + + client.list_locations(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_locations_field_headers_async(): + client = CloudTasksAsyncClient( + 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 = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + await client.list_locations(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_locations_from_dict(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + + response = client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_locations_from_dict_async(): + client = CloudTasksAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_location(transport: str = "grpc"): + client = CloudTasksClient( + 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 = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + response = client.get_location(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, locations_pb2.Location) + + +@pytest.mark.asyncio +async def test_get_location_async(transport: str = "grpc_asyncio"): + client = CloudTasksAsyncClient( + 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 = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location(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, locations_pb2.Location) + + +def test_get_location_field_headers(): + client = CloudTasksClient(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 = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = locations_pb2.Location() + + client.get_location(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/abc", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_location_field_headers_async(): + client = CloudTasksAsyncClient(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 = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + await client.get_location(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/abc", + ) in kw["metadata"] + + +def test_get_location_from_dict(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + + response = client.get_location( + request={ + "name": "locations/abc", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_location_from_dict_async(): + client = CloudTasksAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location( + request={ + "name": "locations", + } + ) + call.assert_called() + + def test_transport_close(): transports = { "rest": "_session", diff --git a/tests/unit/gapic/tasks_v2beta2/test_cloud_tasks.py b/tests/unit/gapic/tasks_v2beta2/test_cloud_tasks.py index 2bbf629..c6dbddd 100644 --- a/tests/unit/gapic/tasks_v2beta2/test_cloud_tasks.py +++ b/tests/unit/gapic/tasks_v2beta2/test_cloud_tasks.py @@ -26,12 +26,14 @@ import json import math +from google.api import httpbody_pb2 # type: ignore from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template from google.api_core import client_options from google.api_core import exceptions as core_exceptions import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import options_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore @@ -2747,6 +2749,93 @@ async def test_resume_queue_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + cloudtasks.UploadQueueYamlRequest, + dict, + ], +) +def test_upload_queue_yaml(request_type, transport: str = "grpc"): + client = CloudTasksClient( + 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 = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.upload_queue_yaml), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.upload_queue_yaml(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == cloudtasks.UploadQueueYamlRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_upload_queue_yaml_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.upload_queue_yaml), "__call__" + ) as call: + client.upload_queue_yaml() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == cloudtasks.UploadQueueYamlRequest() + + +@pytest.mark.asyncio +async def test_upload_queue_yaml_async( + transport: str = "grpc_asyncio", request_type=cloudtasks.UploadQueueYamlRequest +): + client = CloudTasksAsyncClient( + 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 = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.upload_queue_yaml), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.upload_queue_yaml(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == cloudtasks.UploadQueueYamlRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_upload_queue_yaml_async_from_dict(): + await test_upload_queue_yaml_async(request_type=dict) + + @pytest.mark.parametrize( "request_type", [ @@ -5830,6 +5919,254 @@ async def test_run_task_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + cloudtasks.BufferTaskRequest, + dict, + ], +) +def test_buffer_task(request_type, transport: str = "grpc"): + client = CloudTasksClient( + 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 = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = cloudtasks.BufferTaskResponse() + response = client.buffer_task(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == cloudtasks.BufferTaskRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, cloudtasks.BufferTaskResponse) + + +def test_buffer_task_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + client.buffer_task() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == cloudtasks.BufferTaskRequest() + + +@pytest.mark.asyncio +async def test_buffer_task_async( + transport: str = "grpc_asyncio", request_type=cloudtasks.BufferTaskRequest +): + client = CloudTasksAsyncClient( + 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 = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloudtasks.BufferTaskResponse() + ) + response = await client.buffer_task(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == cloudtasks.BufferTaskRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, cloudtasks.BufferTaskResponse) + + +@pytest.mark.asyncio +async def test_buffer_task_async_from_dict(): + await test_buffer_task_async(request_type=dict) + + +def test_buffer_task_field_headers(): + client = CloudTasksClient( + 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 = cloudtasks.BufferTaskRequest() + + request.queue = "queue_value" + request.task_id = "task_id_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + call.return_value = cloudtasks.BufferTaskResponse() + client.buffer_task(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", + "queue=queue_value&task_id=task_id_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_buffer_task_field_headers_async(): + client = CloudTasksAsyncClient( + 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 = cloudtasks.BufferTaskRequest() + + request.queue = "queue_value" + request.task_id = "task_id_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloudtasks.BufferTaskResponse() + ) + await client.buffer_task(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, 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", + "queue=queue_value&task_id=task_id_value", + ) in kw["metadata"] + + +def test_buffer_task_flattened(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = cloudtasks.BufferTaskResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.buffer_task( + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].queue + mock_val = "queue_value" + assert arg == mock_val + arg = args[0].task_id + mock_val = "task_id_value" + assert arg == mock_val + arg = args[0].body + mock_val = httpbody_pb2.HttpBody(content_type="content_type_value") + assert arg == mock_val + + +def test_buffer_task_flattened_error(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.buffer_task( + cloudtasks.BufferTaskRequest(), + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + + +@pytest.mark.asyncio +async def test_buffer_task_flattened_async(): + client = CloudTasksAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = cloudtasks.BufferTaskResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloudtasks.BufferTaskResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.buffer_task( + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].queue + mock_val = "queue_value" + assert arg == mock_val + arg = args[0].task_id + mock_val = "task_id_value" + assert arg == mock_val + arg = args[0].body + mock_val = httpbody_pb2.HttpBody(content_type="content_type_value") + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_buffer_task_flattened_error_async(): + client = CloudTasksAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.buffer_task( + cloudtasks.BufferTaskRequest(), + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + + @pytest.mark.parametrize( "request_type", [ @@ -6460,6 +6797,28 @@ def test_create_queue_rest(request_type): } }, "pull_target": {}, + "http_target": { + "uri_override": { + "scheme": 1, + "host": "host_value", + "port": 453, + "path_override": {"path": "path_value"}, + "query_override": {"query_params": "query_params_value"}, + "uri_override_enforce_mode": 1, + }, + "http_method": 1, + "header_overrides": [ + {"header": {"key": "key_value", "value": "value_value"}} + ], + "oauth_token": { + "service_account_email": "service_account_email_value", + "scope": "scope_value", + }, + "oidc_token": { + "service_account_email": "service_account_email_value", + "audience": "audience_value", + }, + }, "rate_limits": { "max_tasks_dispatched_per_second": 0.32680000000000003, "max_burst_size": 1519, @@ -6678,6 +7037,28 @@ def test_create_queue_rest_bad_request( } }, "pull_target": {}, + "http_target": { + "uri_override": { + "scheme": 1, + "host": "host_value", + "port": 453, + "path_override": {"path": "path_value"}, + "query_override": {"query_params": "query_params_value"}, + "uri_override_enforce_mode": 1, + }, + "http_method": 1, + "header_overrides": [ + {"header": {"key": "key_value", "value": "value_value"}} + ], + "oauth_token": { + "service_account_email": "service_account_email_value", + "scope": "scope_value", + }, + "oidc_token": { + "service_account_email": "service_account_email_value", + "audience": "audience_value", + }, + }, "rate_limits": { "max_tasks_dispatched_per_second": 0.32680000000000003, "max_burst_size": 1519, @@ -6809,6 +7190,28 @@ def test_update_queue_rest(request_type): } }, "pull_target": {}, + "http_target": { + "uri_override": { + "scheme": 1, + "host": "host_value", + "port": 453, + "path_override": {"path": "path_value"}, + "query_override": {"query_params": "query_params_value"}, + "uri_override_enforce_mode": 1, + }, + "http_method": 1, + "header_overrides": [ + {"header": {"key": "key_value", "value": "value_value"}} + ], + "oauth_token": { + "service_account_email": "service_account_email_value", + "scope": "scope_value", + }, + "oidc_token": { + "service_account_email": "service_account_email_value", + "audience": "audience_value", + }, + }, "rate_limits": { "max_tasks_dispatched_per_second": 0.32680000000000003, "max_burst_size": 1519, @@ -7018,7 +7421,29 @@ def test_update_queue_rest_bad_request( } }, "pull_target": {}, - "rate_limits": { + "http_target": { + "uri_override": { + "scheme": 1, + "host": "host_value", + "port": 453, + "path_override": {"path": "path_value"}, + "query_override": {"query_params": "query_params_value"}, + "uri_override_enforce_mode": 1, + }, + "http_method": 1, + "header_overrides": [ + {"header": {"key": "key_value", "value": "value_value"}} + ], + "oauth_token": { + "service_account_email": "service_account_email_value", + "scope": "scope_value", + }, + "oidc_token": { + "service_account_email": "service_account_email_value", + "audience": "audience_value", + }, + }, + "rate_limits": { "max_tasks_dispatched_per_second": 0.32680000000000003, "max_burst_size": 1519, "max_concurrent_tasks": 2157, @@ -8167,6 +8592,16 @@ def test_resume_queue_rest_error(): ) +def test_upload_queue_yaml_rest_no_http_options(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = cloudtasks.UploadQueueYamlRequest() + with pytest.raises(RuntimeError): + client.upload_queue_yaml(request) + + @pytest.mark.parametrize( "request_type", [ @@ -11512,6 +11947,294 @@ def test_run_task_rest_error(): ) +@pytest.mark.parametrize( + "request_type", + [ + cloudtasks.BufferTaskRequest, + dict, + ], +) +def test_buffer_task_rest(request_type): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "queue": "projects/sample1/locations/sample2/queues/sample3", + "task_id": "sample4", + } + 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 = cloudtasks.BufferTaskResponse() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = cloudtasks.BufferTaskResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.buffer_task(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, cloudtasks.BufferTaskResponse) + + +def test_buffer_task_rest_required_fields(request_type=cloudtasks.BufferTaskRequest): + transport_class = transports.CloudTasksRestTransport + + request_init = {} + request_init["queue"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).buffer_task._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["queue"] = "queue_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).buffer_task._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "queue" in jsonified_request + assert jsonified_request["queue"] == "queue_value" + + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = cloudtasks.BufferTaskResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = cloudtasks.BufferTaskResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.buffer_task(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_buffer_task_rest_unset_required_fields(): + transport = transports.CloudTasksRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.buffer_task._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("queue",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_buffer_task_rest_interceptors(null_interceptor): + transport = transports.CloudTasksRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CloudTasksRestInterceptor(), + ) + client = CloudTasksClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CloudTasksRestInterceptor, "post_buffer_task" + ) as post, mock.patch.object( + transports.CloudTasksRestInterceptor, "pre_buffer_task" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = cloudtasks.BufferTaskRequest.pb(cloudtasks.BufferTaskRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = cloudtasks.BufferTaskResponse.to_json( + cloudtasks.BufferTaskResponse() + ) + + request = cloudtasks.BufferTaskRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = cloudtasks.BufferTaskResponse() + + client.buffer_task( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_buffer_task_rest_bad_request( + transport: str = "rest", request_type=cloudtasks.BufferTaskRequest +): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "queue": "projects/sample1/locations/sample2/queues/sample3", + "task_id": "sample4", + } + request = request_type(**request_init) + + # 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.buffer_task(request) + + +def test_buffer_task_rest_flattened(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # 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 = cloudtasks.BufferTaskResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "queue": "projects/sample1/locations/sample2/queues/sample3", + "task_id": "sample4", + } + + # get truthy value for each flattened field + mock_args = dict( + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = cloudtasks.BufferTaskResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.buffer_task(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta2/{queue=projects/*/locations/*/queues/*}/tasks/{task_id}:buffer" + % client.transport._host, + args[1], + ) + + +def test_buffer_task_rest_flattened_error(transport: str = "rest"): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.buffer_task( + cloudtasks.BufferTaskRequest(), + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + + +def test_buffer_task_rest_error(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +def test_upload_queue_yaml_rest_error(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # Since a `google.api.http` annotation is required for using a rest transport + # method, this should error. + with pytest.raises(NotImplementedError) as not_implemented_error: + client.upload_queue_yaml({}) + assert "Method UploadQueueYaml is not available over REST transport" in str( + not_implemented_error.value + ) + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.CloudTasksGrpcTransport( @@ -11659,6 +12382,7 @@ def test_cloud_tasks_base_transport(): "purge_queue", "pause_queue", "resume_queue", + "upload_queue_yaml", "get_iam_policy", "set_iam_policy", "test_iam_permissions", @@ -11671,6 +12395,9 @@ def test_cloud_tasks_base_transport(): "renew_lease", "cancel_lease", "run_task", + "buffer_task", + "get_location", + "list_locations", ) for method in methods: with pytest.raises(NotImplementedError): @@ -11950,6 +12677,9 @@ def test_cloud_tasks_client_transport_session_collision(transport_name): session1 = client1.transport.resume_queue._session session2 = client2.transport.resume_queue._session assert session1 != session2 + session1 = client1.transport.upload_queue_yaml._session + session2 = client2.transport.upload_queue_yaml._session + assert session1 != session2 session1 = client1.transport.get_iam_policy._session session2 = client2.transport.get_iam_policy._session assert session1 != session2 @@ -11986,6 +12716,9 @@ def test_cloud_tasks_client_transport_session_collision(transport_name): session1 = client1.transport.run_task._session session2 = client2.transport.run_task._session assert session1 != session2 + session1 = client1.transport.buffer_task._session + session2 = client2.transport.buffer_task._session + assert session1 != session2 def test_cloud_tasks_grpc_transport_channel(): @@ -12303,6 +13036,406 @@ async def test_transport_close_async(): close.assert_called_once() +def test_get_location_rest_bad_request( + transport: str = "rest", request_type=locations_pb2.GetLocationRequest +): + client = CloudTasksClient( + 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.get_location(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.GetLocationRequest, + dict, + ], +) +def test_get_location_rest(request_type): + client = CloudTasksClient( + 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 = locations_pb2.Location() + + # 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_location(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_list_locations_rest_bad_request( + transport: str = "rest", request_type=locations_pb2.ListLocationsRequest +): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({"name": "projects/sample1"}, 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_locations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.ListLocationsRequest, + dict, + ], +) +def test_list_locations_rest(request_type): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1"} + 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 = locations_pb2.ListLocationsResponse() + + # 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_locations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_list_locations(transport: str = "grpc"): + client = CloudTasksClient( + 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 = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + response = client.list_locations(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, locations_pb2.ListLocationsResponse) + + +@pytest.mark.asyncio +async def test_list_locations_async(transport: str = "grpc"): + client = CloudTasksAsyncClient( + 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 = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations(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, locations_pb2.ListLocationsResponse) + + +def test_list_locations_field_headers(): + client = CloudTasksClient( + 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 = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = locations_pb2.ListLocationsResponse() + + client.list_locations(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_locations_field_headers_async(): + client = CloudTasksAsyncClient( + 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 = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + await client.list_locations(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_locations_from_dict(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + + response = client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_locations_from_dict_async(): + client = CloudTasksAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_location(transport: str = "grpc"): + client = CloudTasksClient( + 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 = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + response = client.get_location(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, locations_pb2.Location) + + +@pytest.mark.asyncio +async def test_get_location_async(transport: str = "grpc_asyncio"): + client = CloudTasksAsyncClient( + 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 = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location(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, locations_pb2.Location) + + +def test_get_location_field_headers(): + client = CloudTasksClient(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 = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = locations_pb2.Location() + + client.get_location(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/abc", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_location_field_headers_async(): + client = CloudTasksAsyncClient(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 = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + await client.get_location(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/abc", + ) in kw["metadata"] + + +def test_get_location_from_dict(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + + response = client.get_location( + request={ + "name": "locations/abc", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_location_from_dict_async(): + client = CloudTasksAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location( + request={ + "name": "locations", + } + ) + call.assert_called() + + def test_transport_close(): transports = { "rest": "_session", diff --git a/tests/unit/gapic/tasks_v2beta3/test_cloud_tasks.py b/tests/unit/gapic/tasks_v2beta3/test_cloud_tasks.py index 17df92b..f0aa7de 100644 --- a/tests/unit/gapic/tasks_v2beta3/test_cloud_tasks.py +++ b/tests/unit/gapic/tasks_v2beta3/test_cloud_tasks.py @@ -26,12 +26,14 @@ import json import math +from google.api import httpbody_pb2 # type: ignore from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template from google.api_core import client_options from google.api_core import exceptions as core_exceptions import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 from google.iam.v1 import iam_policy_pb2 # type: ignore from google.iam.v1 import options_pb2 # type: ignore from google.iam.v1 import policy_pb2 # type: ignore @@ -4918,6 +4920,254 @@ async def test_run_task_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + cloudtasks.BufferTaskRequest, + dict, + ], +) +def test_buffer_task(request_type, transport: str = "grpc"): + client = CloudTasksClient( + 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 = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = cloudtasks.BufferTaskResponse() + response = client.buffer_task(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == cloudtasks.BufferTaskRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, cloudtasks.BufferTaskResponse) + + +def test_buffer_task_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + client.buffer_task() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == cloudtasks.BufferTaskRequest() + + +@pytest.mark.asyncio +async def test_buffer_task_async( + transport: str = "grpc_asyncio", request_type=cloudtasks.BufferTaskRequest +): + client = CloudTasksAsyncClient( + 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 = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloudtasks.BufferTaskResponse() + ) + response = await client.buffer_task(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == cloudtasks.BufferTaskRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, cloudtasks.BufferTaskResponse) + + +@pytest.mark.asyncio +async def test_buffer_task_async_from_dict(): + await test_buffer_task_async(request_type=dict) + + +def test_buffer_task_field_headers(): + client = CloudTasksClient( + 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 = cloudtasks.BufferTaskRequest() + + request.queue = "queue_value" + request.task_id = "task_id_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + call.return_value = cloudtasks.BufferTaskResponse() + client.buffer_task(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", + "queue=queue_value&task_id=task_id_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_buffer_task_field_headers_async(): + client = CloudTasksAsyncClient( + 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 = cloudtasks.BufferTaskRequest() + + request.queue = "queue_value" + request.task_id = "task_id_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloudtasks.BufferTaskResponse() + ) + await client.buffer_task(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, 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", + "queue=queue_value&task_id=task_id_value", + ) in kw["metadata"] + + +def test_buffer_task_flattened(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = cloudtasks.BufferTaskResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.buffer_task( + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].queue + mock_val = "queue_value" + assert arg == mock_val + arg = args[0].task_id + mock_val = "task_id_value" + assert arg == mock_val + arg = args[0].body + mock_val = httpbody_pb2.HttpBody(content_type="content_type_value") + assert arg == mock_val + + +def test_buffer_task_flattened_error(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.buffer_task( + cloudtasks.BufferTaskRequest(), + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + + +@pytest.mark.asyncio +async def test_buffer_task_flattened_async(): + client = CloudTasksAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.buffer_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = cloudtasks.BufferTaskResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cloudtasks.BufferTaskResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.buffer_task( + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].queue + mock_val = "queue_value" + assert arg == mock_val + arg = args[0].task_id + mock_val = "task_id_value" + assert arg == mock_val + arg = args[0].body + mock_val = httpbody_pb2.HttpBody(content_type="content_type_value") + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_buffer_task_flattened_error_async(): + client = CloudTasksAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.buffer_task( + cloudtasks.BufferTaskRequest(), + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + + @pytest.mark.parametrize( "request_type", [ @@ -5549,6 +5799,28 @@ def test_create_queue_rest(request_type): "host": "host_value", } }, + "http_target": { + "uri_override": { + "scheme": 1, + "host": "host_value", + "port": 453, + "path_override": {"path": "path_value"}, + "query_override": {"query_params": "query_params_value"}, + "uri_override_enforce_mode": 1, + }, + "http_method": 1, + "header_overrides": [ + {"header": {"key": "key_value", "value": "value_value"}} + ], + "oauth_token": { + "service_account_email": "service_account_email_value", + "scope": "scope_value", + }, + "oidc_token": { + "service_account_email": "service_account_email_value", + "audience": "audience_value", + }, + }, "rate_limits": { "max_dispatches_per_second": 0.26380000000000003, "max_burst_size": 1519, @@ -5769,6 +6041,28 @@ def test_create_queue_rest_bad_request( "host": "host_value", } }, + "http_target": { + "uri_override": { + "scheme": 1, + "host": "host_value", + "port": 453, + "path_override": {"path": "path_value"}, + "query_override": {"query_params": "query_params_value"}, + "uri_override_enforce_mode": 1, + }, + "http_method": 1, + "header_overrides": [ + {"header": {"key": "key_value", "value": "value_value"}} + ], + "oauth_token": { + "service_account_email": "service_account_email_value", + "scope": "scope_value", + }, + "oidc_token": { + "service_account_email": "service_account_email_value", + "audience": "audience_value", + }, + }, "rate_limits": { "max_dispatches_per_second": 0.26380000000000003, "max_burst_size": 1519, @@ -5900,6 +6194,28 @@ def test_update_queue_rest(request_type): "host": "host_value", } }, + "http_target": { + "uri_override": { + "scheme": 1, + "host": "host_value", + "port": 453, + "path_override": {"path": "path_value"}, + "query_override": {"query_params": "query_params_value"}, + "uri_override_enforce_mode": 1, + }, + "http_method": 1, + "header_overrides": [ + {"header": {"key": "key_value", "value": "value_value"}} + ], + "oauth_token": { + "service_account_email": "service_account_email_value", + "scope": "scope_value", + }, + "oidc_token": { + "service_account_email": "service_account_email_value", + "audience": "audience_value", + }, + }, "rate_limits": { "max_dispatches_per_second": 0.26380000000000003, "max_burst_size": 1519, @@ -6111,6 +6427,28 @@ def test_update_queue_rest_bad_request( "host": "host_value", } }, + "http_target": { + "uri_override": { + "scheme": 1, + "host": "host_value", + "port": 453, + "path_override": {"path": "path_value"}, + "query_override": {"query_params": "query_params_value"}, + "uri_override_enforce_mode": 1, + }, + "http_method": 1, + "header_overrides": [ + {"header": {"key": "key_value", "value": "value_value"}} + ], + "oauth_token": { + "service_account_email": "service_account_email_value", + "scope": "scope_value", + }, + "oidc_token": { + "service_account_email": "service_account_email_value", + "audience": "audience_value", + }, + }, "rate_limits": { "max_dispatches_per_second": 0.26380000000000003, "max_burst_size": 1519, @@ -9517,61 +9855,336 @@ def test_run_task_rest_error(): ) -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.CloudTasksGrpcTransport( +@pytest.mark.parametrize( + "request_type", + [ + cloudtasks.BufferTaskRequest, + dict, + ], +) +def test_buffer_task_rest(request_type): + client = CloudTasksClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = CloudTasksClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.CloudTasksGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CloudTasksClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # send a request that will satisfy transcoding + request_init = { + "queue": "projects/sample1/locations/sample2/queues/sample3", + "task_id": "sample4", + } + request = request_type(**request_init) - # It is an error to provide an api_key and a transport instance. - transport = transports.CloudTasksGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = CloudTasksClient( - client_options=options, - transport=transport, - ) + # 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 = cloudtasks.BufferTaskResponse() - # It is an error to provide an api_key and a credential. - options = mock.Mock() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = CloudTasksClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = cloudtasks.BufferTaskResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) - # It is an error to provide scopes and a transport instance. - transport = transports.CloudTasksGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CloudTasksClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.buffer_task(request) + # Establish that the response is the type that we expect. + assert isinstance(response, cloudtasks.BufferTaskResponse) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.CloudTasksGrpcTransport( + +def test_buffer_task_rest_required_fields(request_type=cloudtasks.BufferTaskRequest): + transport_class = transports.CloudTasksRestTransport + + request_init = {} + request_init["queue"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).buffer_task._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["queue"] = "queue_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).buffer_task._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "queue" in jsonified_request + assert jsonified_request["queue"] == "queue_value" + + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = cloudtasks.BufferTaskResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = cloudtasks.BufferTaskResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.buffer_task(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_buffer_task_rest_unset_required_fields(): + transport = transports.CloudTasksRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.buffer_task._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("queue",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_buffer_task_rest_interceptors(null_interceptor): + transport = transports.CloudTasksRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CloudTasksRestInterceptor(), + ) + client = CloudTasksClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CloudTasksRestInterceptor, "post_buffer_task" + ) as post, mock.patch.object( + transports.CloudTasksRestInterceptor, "pre_buffer_task" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = cloudtasks.BufferTaskRequest.pb(cloudtasks.BufferTaskRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = cloudtasks.BufferTaskResponse.to_json( + cloudtasks.BufferTaskResponse() + ) + + request = cloudtasks.BufferTaskRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = cloudtasks.BufferTaskResponse() + + client.buffer_task( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_buffer_task_rest_bad_request( + transport: str = "rest", request_type=cloudtasks.BufferTaskRequest +): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "queue": "projects/sample1/locations/sample2/queues/sample3", + "task_id": "sample4", + } + request = request_type(**request_init) + + # 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.buffer_task(request) + + +def test_buffer_task_rest_flattened(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # 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 = cloudtasks.BufferTaskResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "queue": "projects/sample1/locations/sample2/queues/sample3", + "task_id": "sample4", + } + + # get truthy value for each flattened field + mock_args = dict( + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = cloudtasks.BufferTaskResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.buffer_task(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta3/{queue=projects/*/locations/*/queues/*}/tasks/{task_id}:buffer" + % client.transport._host, + args[1], + ) + + +def test_buffer_task_rest_flattened_error(transport: str = "rest"): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.buffer_task( + cloudtasks.BufferTaskRequest(), + queue="queue_value", + task_id="task_id_value", + body=httpbody_pb2.HttpBody(content_type="content_type_value"), + ) + + +def test_buffer_task_rest_error(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CloudTasksGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CloudTasksGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CloudTasksClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CloudTasksGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CloudTasksClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CloudTasksClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CloudTasksGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CloudTasksClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CloudTasksGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), ) client = CloudTasksClient(transport=transport) @@ -9672,6 +10285,9 @@ def test_cloud_tasks_base_transport(): "create_task", "delete_task", "run_task", + "buffer_task", + "get_location", + "list_locations", ) for method in methods: with pytest.raises(NotImplementedError): @@ -9975,6 +10591,9 @@ def test_cloud_tasks_client_transport_session_collision(transport_name): session1 = client1.transport.run_task._session session2 = client2.transport.run_task._session assert session1 != session2 + session1 = client1.transport.buffer_task._session + session2 = client2.transport.buffer_task._session + assert session1 != session2 def test_cloud_tasks_grpc_transport_channel(): @@ -10292,6 +10911,406 @@ async def test_transport_close_async(): close.assert_called_once() +def test_get_location_rest_bad_request( + transport: str = "rest", request_type=locations_pb2.GetLocationRequest +): + client = CloudTasksClient( + 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.get_location(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.GetLocationRequest, + dict, + ], +) +def test_get_location_rest(request_type): + client = CloudTasksClient( + 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 = locations_pb2.Location() + + # 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_location(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_list_locations_rest_bad_request( + transport: str = "rest", request_type=locations_pb2.ListLocationsRequest +): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({"name": "projects/sample1"}, 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_locations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.ListLocationsRequest, + dict, + ], +) +def test_list_locations_rest(request_type): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1"} + 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 = locations_pb2.ListLocationsResponse() + + # 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_locations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_list_locations(transport: str = "grpc"): + client = CloudTasksClient( + 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 = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + response = client.list_locations(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, locations_pb2.ListLocationsResponse) + + +@pytest.mark.asyncio +async def test_list_locations_async(transport: str = "grpc"): + client = CloudTasksAsyncClient( + 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 = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations(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, locations_pb2.ListLocationsResponse) + + +def test_list_locations_field_headers(): + client = CloudTasksClient( + 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 = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = locations_pb2.ListLocationsResponse() + + client.list_locations(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_locations_field_headers_async(): + client = CloudTasksAsyncClient( + 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 = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + await client.list_locations(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_locations_from_dict(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + + response = client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_locations_from_dict_async(): + client = CloudTasksAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_location(transport: str = "grpc"): + client = CloudTasksClient( + 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 = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + response = client.get_location(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, locations_pb2.Location) + + +@pytest.mark.asyncio +async def test_get_location_async(transport: str = "grpc_asyncio"): + client = CloudTasksAsyncClient( + 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 = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location(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, locations_pb2.Location) + + +def test_get_location_field_headers(): + client = CloudTasksClient(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 = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = locations_pb2.Location() + + client.get_location(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/abc", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_location_field_headers_async(): + client = CloudTasksAsyncClient(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 = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + await client.get_location(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/abc", + ) in kw["metadata"] + + +def test_get_location_from_dict(): + client = CloudTasksClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + + response = client.get_location( + request={ + "name": "locations/abc", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_location_from_dict_async(): + client = CloudTasksAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location( + request={ + "name": "locations", + } + ) + call.assert_called() + + def test_transport_close(): transports = { "rest": "_session",