1# Copyright 2017 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""A client for the google.longrunning.operations meta-API.
16
17This is a client that deals with long-running operations that follow the
18pattern outlined by the `Google API Style Guide`_.
19
20When an API method normally takes long time to complete, it can be designed to
21return ``Operation`` to the client, and the client can use this interface to
22receive the real response asynchronously by polling the operation resource to
23receive the response.
24
25It is not a separate service, but rather an interface implemented by a larger
26service. The protocol-level definition is available at
27`google/longrunning/operations.proto`_. Typically, this will be constructed
28automatically by another client class to deal with operations.
29
30.. _Google API Style Guide:
31    https://cloud.google.com/apis/design/design_pattern
32    s#long_running_operations
33.. _google/longrunning/operations.proto:
34    https://github.com/googleapis/googleapis/blob/master/google/longrunning
35    /operations.proto
36"""
37
38import functools
39
40from google.api_core import gapic_v1
41from google.api_core import page_iterator
42from google.api_core.operations_v1 import operations_client_config
43from google.longrunning import operations_pb2
44
45
46class OperationsClient(object):
47    """Client for interacting with long-running operations within a service.
48
49    Args:
50        channel (grpc.Channel): The gRPC channel associated with the service
51            that implements the ``google.longrunning.operations`` interface.
52        client_config (dict):
53            A dictionary of call options for each method. If not specified
54            the default configuration is used.
55    """
56
57    def __init__(self, channel, client_config=operations_client_config.config):
58        # Create the gRPC client stub.
59        self.operations_stub = operations_pb2.OperationsStub(channel)
60
61        # Create all wrapped methods using the interface configuration.
62        # The interface config contains all of the default settings for retry
63        # and timeout for each RPC method.
64        interfaces = client_config["interfaces"]
65        interface_config = interfaces["google.longrunning.Operations"]
66        method_configs = gapic_v1.config.parse_method_configs(interface_config)
67
68        self._get_operation = gapic_v1.method.wrap_method(
69            self.operations_stub.GetOperation,
70            default_retry=method_configs["GetOperation"].retry,
71            default_timeout=method_configs["GetOperation"].timeout,
72        )
73
74        self._list_operations = gapic_v1.method.wrap_method(
75            self.operations_stub.ListOperations,
76            default_retry=method_configs["ListOperations"].retry,
77            default_timeout=method_configs["ListOperations"].timeout,
78        )
79
80        self._cancel_operation = gapic_v1.method.wrap_method(
81            self.operations_stub.CancelOperation,
82            default_retry=method_configs["CancelOperation"].retry,
83            default_timeout=method_configs["CancelOperation"].timeout,
84        )
85
86        self._delete_operation = gapic_v1.method.wrap_method(
87            self.operations_stub.DeleteOperation,
88            default_retry=method_configs["DeleteOperation"].retry,
89            default_timeout=method_configs["DeleteOperation"].timeout,
90        )
91
92    # Service calls
93    def get_operation(
94        self,
95        name,
96        retry=gapic_v1.method.DEFAULT,
97        timeout=gapic_v1.method.DEFAULT,
98        metadata=None,
99    ):
100        """Gets the latest state of a long-running operation.
101
102        Clients can use this method to poll the operation result at intervals
103        as recommended by the API service.
104
105        Example:
106            >>> from google.api_core import operations_v1
107            >>> api = operations_v1.OperationsClient()
108            >>> name = ''
109            >>> response = api.get_operation(name)
110
111        Args:
112            name (str): The name of the operation resource.
113            retry (google.api_core.retry.Retry): The retry strategy to use
114                when invoking the RPC. If unspecified, the default retry from
115                the client configuration will be used. If ``None``, then this
116                method will not retry the RPC at all.
117            timeout (float): The amount of time in seconds to wait for the RPC
118                to complete. Note that if ``retry`` is used, this timeout
119                applies to each individual attempt and the overall time it
120                takes for this method to complete may be longer. If
121                unspecified, the the default timeout in the client
122                configuration is used. If ``None``, then the RPC method will
123                not time out.
124            metadata (Optional[List[Tuple[str, str]]]):
125                Additional gRPC metadata.
126
127        Returns:
128            google.longrunning.operations_pb2.Operation: The state of the
129                operation.
130
131        Raises:
132            google.api_core.exceptions.GoogleAPICallError: If an error occurred
133                while invoking the RPC, the appropriate ``GoogleAPICallError``
134                subclass will be raised.
135        """
136        request = operations_pb2.GetOperationRequest(name=name)
137
138        # Add routing header
139        metadata = metadata or []
140        metadata.append(gapic_v1.routing_header.to_grpc_metadata({"name": name}))
141
142        return self._get_operation(request, retry=retry, timeout=timeout, metadata=metadata)
143
144    def list_operations(
145        self,
146        name,
147        filter_,
148        retry=gapic_v1.method.DEFAULT,
149        timeout=gapic_v1.method.DEFAULT,
150        metadata=None,
151    ):
152        """
153        Lists operations that match the specified filter in the request.
154
155        Example:
156            >>> from google.api_core import operations_v1
157            >>> api = operations_v1.OperationsClient()
158            >>> name = ''
159            >>>
160            >>> # Iterate over all results
161            >>> for operation in api.list_operations(name):
162            >>>   # process operation
163            >>>   pass
164            >>>
165            >>> # Or iterate over results one page at a time
166            >>> iter = api.list_operations(name)
167            >>> for page in iter.pages:
168            >>>   for operation in page:
169            >>>     # process operation
170            >>>     pass
171
172        Args:
173            name (str): The name of the operation collection.
174            filter_ (str): The standard list filter.
175            retry (google.api_core.retry.Retry): The retry strategy to use
176                when invoking the RPC. If unspecified, the default retry from
177                the client configuration will be used. If ``None``, then this
178                method will not retry the RPC at all.
179            timeout (float): The amount of time in seconds to wait for the RPC
180                to complete. Note that if ``retry`` is used, this timeout
181                applies to each individual attempt and the overall time it
182                takes for this method to complete may be longer. If
183                unspecified, the the default timeout in the client
184                configuration is used. If ``None``, then the RPC method will
185                not time out.
186            metadata (Optional[List[Tuple[str, str]]]): Additional gRPC
187                metadata.
188
189        Returns:
190            google.api_core.page_iterator.Iterator: An iterator that yields
191                :class:`google.longrunning.operations_pb2.Operation` instances.
192
193        Raises:
194            google.api_core.exceptions.MethodNotImplemented: If the server
195                does not support this method. Services are not required to
196                implement this method.
197            google.api_core.exceptions.GoogleAPICallError: If an error occurred
198                while invoking the RPC, the appropriate ``GoogleAPICallError``
199                subclass will be raised.
200        """
201        # Create the request object.
202        request = operations_pb2.ListOperationsRequest(name=name, filter=filter_)
203
204        # Add routing header
205        metadata = metadata or []
206        metadata.append(gapic_v1.routing_header.to_grpc_metadata({"name": name}))
207
208        # Create the method used to fetch pages
209        method = functools.partial(self._list_operations, retry=retry, timeout=timeout, metadata=metadata)
210
211        iterator = page_iterator.GRPCIterator(
212            client=None,
213            method=method,
214            request=request,
215            items_field="operations",
216            request_token_field="page_token",
217            response_token_field="next_page_token",
218        )
219
220        return iterator
221
222    def cancel_operation(
223        self,
224        name,
225        retry=gapic_v1.method.DEFAULT,
226        timeout=gapic_v1.method.DEFAULT,
227        metadata=None,
228    ):
229        """Starts asynchronous cancellation on a long-running operation.
230
231        The server makes a best effort to cancel the operation, but success is
232        not guaranteed. Clients can use :meth:`get_operation` or service-
233        specific methods to check whether the cancellation succeeded or whether
234        the operation completed despite cancellation. On successful
235        cancellation, the operation is not deleted; instead, it becomes an
236        operation with an ``Operation.error`` value with a
237        ``google.rpc.Status.code`` of ``1``, corresponding to
238        ``Code.CANCELLED``.
239
240        Example:
241            >>> from google.api_core import operations_v1
242            >>> api = operations_v1.OperationsClient()
243            >>> name = ''
244            >>> api.cancel_operation(name)
245
246        Args:
247            name (str): The name of the operation resource to be cancelled.
248            retry (google.api_core.retry.Retry): The retry strategy to use
249                when invoking the RPC. If unspecified, the default retry from
250                the client configuration will be used. If ``None``, then this
251                method will not retry the RPC at all.
252            timeout (float): The amount of time in seconds to wait for the RPC
253                to complete. Note that if ``retry`` is used, this timeout
254                applies to each individual attempt and the overall time it
255                takes for this method to complete may be longer. If
256                unspecified, the the default timeout in the client
257                configuration is used. If ``None``, then the RPC method will
258                not time out.
259            metadata (Optional[List[Tuple[str, str]]]): Additional gRPC
260                metadata.
261
262        Raises:
263            google.api_core.exceptions.MethodNotImplemented: If the server
264                does not support this method. Services are not required to
265                implement this method.
266            google.api_core.exceptions.GoogleAPICallError: If an error occurred
267                while invoking the RPC, the appropriate ``GoogleAPICallError``
268                subclass will be raised.
269        """
270        # Create the request object.
271        request = operations_pb2.CancelOperationRequest(name=name)
272
273        # Add routing header
274        metadata = metadata or []
275        metadata.append(gapic_v1.routing_header.to_grpc_metadata({"name": name}))
276
277        self._cancel_operation(request, retry=retry, timeout=timeout, metadata=metadata)
278
279    def delete_operation(
280        self,
281        name,
282        retry=gapic_v1.method.DEFAULT,
283        timeout=gapic_v1.method.DEFAULT,
284        metadata=None,
285    ):
286        """Deletes a long-running operation.
287
288        This method indicates that the client is no longer interested in the
289        operation result. It does not cancel the operation.
290
291        Example:
292            >>> from google.api_core import operations_v1
293            >>> api = operations_v1.OperationsClient()
294            >>> name = ''
295            >>> api.delete_operation(name)
296
297        Args:
298            name (str): The name of the operation resource to be deleted.
299            retry (google.api_core.retry.Retry): The retry strategy to use
300                when invoking the RPC. If unspecified, the default retry from
301                the client configuration will be used. If ``None``, then this
302                method will not retry the RPC at all.
303            timeout (float): The amount of time in seconds to wait for the RPC
304                to complete. Note that if ``retry`` is used, this timeout
305                applies to each individual attempt and the overall time it
306                takes for this method to complete may be longer. If
307                unspecified, the the default timeout in the client
308                configuration is used. If ``None``, then the RPC method will
309                not time out.
310            metadata (Optional[List[Tuple[str, str]]]): Additional gRPC
311                metadata.
312
313        Raises:
314            google.api_core.exceptions.MethodNotImplemented: If the server
315                does not support this method. Services are not required to
316                implement this method.
317            google.api_core.exceptions.GoogleAPICallError: If an error occurred
318                while invoking the RPC, the appropriate ``GoogleAPICallError``
319                subclass will be raised.
320        """
321        # Create the request object.
322        request = operations_pb2.DeleteOperationRequest(name=name)
323
324        # Add routing header
325        metadata = metadata or []
326        metadata.append(gapic_v1.routing_header.to_grpc_metadata({"name": name}))
327
328        self._delete_operation(request, retry=retry, timeout=timeout, metadata=metadata)
329