1# -*- coding: utf-8 -*-
2# Copyright 2024 Google LLC
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16from typing import Optional, Sequence, Tuple, Union
17
18from google.api_core import client_options as client_options_lib # type: ignore
19from google.api_core import gapic_v1 # type: ignore
20from google.api_core.operations_v1 import pagers_async as pagers
21from google.api_core.operations_v1.transports.base import (
22 DEFAULT_CLIENT_INFO,
23 OperationsTransport,
24)
25from google.api_core.operations_v1.abstract_operations_base_client import (
26 AbstractOperationsBaseClient,
27)
28from google.longrunning import operations_pb2
29
30try:
31 from google.auth.aio import credentials as ga_credentials # type: ignore
32except ImportError as e: # pragma: NO COVER
33 raise ImportError(
34 "The `async_rest` extra of `google-api-core` is required to use long-running operations. Install it by running "
35 "`pip install google-api-core[async_rest]`."
36 ) from e
37
38
39class AsyncOperationsRestClient(AbstractOperationsBaseClient):
40 """Manages long-running operations with a REST API service for the asynchronous client.
41
42 When an API method normally takes long time to complete, it can be
43 designed to return [Operation][google.api_core.operations_v1.Operation] to the
44 client, and the client can use this interface to receive the real
45 response asynchronously by polling the operation resource, or pass
46 the operation resource to another API (such as Google Cloud Pub/Sub
47 API) to receive the response. Any API service that returns
48 long-running operations should implement the ``Operations``
49 interface so developers can have a consistent client experience.
50 """
51
52 def __init__(
53 self,
54 *,
55 credentials: Optional[ga_credentials.Credentials] = None,
56 transport: Union[str, OperationsTransport, None] = None,
57 client_options: Optional[client_options_lib.ClientOptions] = None,
58 client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
59 ) -> None:
60 """Instantiates the operations client.
61
62 Args:
63 credentials (Optional[google.auth.aio.credentials.Credentials]): The
64 authorization credentials to attach to requests. These
65 credentials identify the application to the service; if none
66 are specified, the client will attempt to ascertain the
67 credentials from the environment.
68 transport (Union[str, OperationsTransport]): The
69 transport to use. If set to None, this defaults to 'rest_asyncio'.
70 client_options (google.api_core.client_options.ClientOptions): Custom options for the
71 client. It won't take effect if a ``transport`` instance is provided.
72 (1) The ``api_endpoint`` property can be used to override the
73 default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
74 environment variable can also be used to override the endpoint:
75 "always" (always use the default mTLS endpoint), "never" (always
76 use the default regular endpoint) and "auto" (auto switch to the
77 default mTLS endpoint if client certificate is present, this is
78 the default value). However, the ``api_endpoint`` property takes
79 precedence if provided.
80 (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
81 is "true", then the ``client_cert_source`` property can be used
82 to provide client certificate for mutual TLS transport. If
83 not provided, the default SSL client certificate will be used if
84 present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
85 set, no client certificate will be used.
86 client_info (google.api_core.gapic_v1.client_info.ClientInfo):
87 The client info used to send a user-agent string along with
88 API requests. If ``None``, then default info will be used.
89 Generally, you only need to set this if you're developing
90 your own client library.
91
92 Raises:
93 google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
94 creation failed for any reason.
95 """
96 super().__init__(
97 credentials=credentials, # type: ignore
98 # NOTE: If a transport is not provided, we force the client to use the async
99 # REST transport.
100 transport=transport or "rest_asyncio",
101 client_options=client_options,
102 client_info=client_info,
103 )
104
105 async def get_operation(
106 self,
107 name: str,
108 *,
109 # TODO(https://github.com/googleapis/python-api-core/issues/722): Leverage `retry`
110 # to allow configuring retryable error codes.
111 retry=gapic_v1.method_async.DEFAULT,
112 timeout: Optional[float] = None,
113 metadata: Sequence[Tuple[str, str]] = (),
114 ) -> operations_pb2.Operation:
115 r"""Gets the latest state of a long-running operation.
116 Clients can use this method to poll the operation result
117 at intervals as recommended by the API service.
118
119 Args:
120 name (str):
121 The name of the operation resource.
122 timeout (float): The timeout for this request.
123 metadata (Sequence[Tuple[str, str]]): Strings which should be
124 sent along with the request as metadata.
125
126 Returns:
127 google.longrunning.operations_pb2.Operation:
128 This resource represents a long-
129 running operation that is the result of a
130 network API call.
131
132 """
133
134 request = operations_pb2.GetOperationRequest(name=name)
135
136 # Wrap the RPC method; this adds retry and timeout information,
137 # and friendly error handling.
138 rpc = self._transport._wrapped_methods[self._transport.get_operation]
139
140 # Certain fields should be provided within the metadata header;
141 # add these here.
142 metadata = tuple(metadata or ()) + (
143 gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
144 )
145
146 # Send the request.
147 response = await rpc(
148 request,
149 retry=retry,
150 timeout=timeout,
151 metadata=metadata,
152 )
153
154 # Done; return the response.
155 return response
156
157 async def list_operations(
158 self,
159 name: str,
160 filter_: Optional[str] = None,
161 *,
162 page_size: Optional[int] = None,
163 page_token: Optional[str] = None,
164 # TODO(https://github.com/googleapis/python-api-core/issues/722): Leverage `retry`
165 # to allow configuring retryable error codes.
166 retry=gapic_v1.method_async.DEFAULT,
167 timeout: Optional[float] = None,
168 metadata: Sequence[Tuple[str, str]] = (),
169 ) -> pagers.ListOperationsAsyncPager:
170 r"""Lists operations that match the specified filter in the request.
171 If the server doesn't support this method, it returns
172 ``UNIMPLEMENTED``.
173
174 NOTE: the ``name`` binding allows API services to override the
175 binding to use different resource name schemes, such as
176 ``users/*/operations``. To override the binding, API services
177 can add a binding such as ``"/v1/{name=users/*}/operations"`` to
178 their service configuration. For backwards compatibility, the
179 default name includes the operations collection id, however
180 overriding users must ensure the name binding is the parent
181 resource, without the operations collection id.
182
183 Args:
184 name (str):
185 The name of the operation's parent
186 resource.
187 filter_ (str):
188 The standard list filter.
189 This corresponds to the ``filter`` field
190 on the ``request`` instance; if ``request`` is provided, this
191 should not be set.
192 timeout (float): The timeout for this request.
193 metadata (Sequence[Tuple[str, str]]): Strings which should be
194 sent along with the request as metadata.
195
196 Returns:
197 google.api_core.operations_v1.pagers.ListOperationsPager:
198 The response message for
199 [Operations.ListOperations][google.api_core.operations_v1.Operations.ListOperations].
200
201 Iterating over this object will yield results and
202 resolve additional pages automatically.
203
204 """
205 # Create a protobuf request object.
206 request = operations_pb2.ListOperationsRequest(name=name, filter=filter_)
207 if page_size is not None:
208 request.page_size = page_size
209 if page_token is not None:
210 request.page_token = page_token
211
212 # Wrap the RPC method; this adds retry and timeout information,
213 # and friendly error handling.
214 rpc = self._transport._wrapped_methods[self._transport.list_operations]
215
216 # Certain fields should be provided within the metadata header;
217 # add these here.
218 metadata = tuple(metadata or ()) + (
219 gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
220 )
221
222 # Send the request.
223 response = await rpc(
224 request,
225 retry=retry,
226 timeout=timeout,
227 metadata=metadata,
228 )
229
230 # This method is paged; wrap the response in a pager, which provides
231 # an `__iter__` convenience method.
232 response = pagers.ListOperationsAsyncPager(
233 method=rpc,
234 request=request,
235 response=response,
236 metadata=metadata,
237 )
238
239 # Done; return the response.
240 return response
241
242 async def delete_operation(
243 self,
244 name: str,
245 *,
246 # TODO(https://github.com/googleapis/python-api-core/issues/722): Leverage `retry`
247 # to allow configuring retryable error codes.
248 retry=gapic_v1.method_async.DEFAULT,
249 timeout: Optional[float] = None,
250 metadata: Sequence[Tuple[str, str]] = (),
251 ) -> None:
252 r"""Deletes a long-running operation. This method indicates that the
253 client is no longer interested in the operation result. It does
254 not cancel the operation. If the server doesn't support this
255 method, it returns ``google.rpc.Code.UNIMPLEMENTED``.
256
257 Args:
258 name (str):
259 The name of the operation resource to
260 be deleted.
261
262 This corresponds to the ``name`` field
263 on the ``request`` instance; if ``request`` is provided, this
264 should not be set.
265 timeout (float): The timeout for this request.
266 metadata (Sequence[Tuple[str, str]]): Strings which should be
267 sent along with the request as metadata.
268 """
269 # Create the request object.
270 request = operations_pb2.DeleteOperationRequest(name=name)
271
272 # Wrap the RPC method; this adds retry and timeout information,
273 # and friendly error handling.
274 rpc = self._transport._wrapped_methods[self._transport.delete_operation]
275
276 # Certain fields should be provided within the metadata header;
277 # add these here.
278 metadata = tuple(metadata or ()) + (
279 gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
280 )
281
282 # Send the request.
283 await rpc(
284 request,
285 retry=retry,
286 timeout=timeout,
287 metadata=metadata,
288 )
289
290 async def cancel_operation(
291 self,
292 name: Optional[str] = None,
293 *,
294 # TODO(https://github.com/googleapis/python-api-core/issues/722): Leverage `retry`
295 # to allow configuring retryable error codes.
296 retry=gapic_v1.method_async.DEFAULT,
297 timeout: Optional[float] = None,
298 metadata: Sequence[Tuple[str, str]] = (),
299 ) -> None:
300 r"""Starts asynchronous cancellation on a long-running operation.
301 The server makes a best effort to cancel the operation, but
302 success is not guaranteed. If the server doesn't support this
303 method, it returns ``google.rpc.Code.UNIMPLEMENTED``. Clients
304 can use
305 [Operations.GetOperation][google.api_core.operations_v1.Operations.GetOperation]
306 or other methods to check whether the cancellation succeeded or
307 whether the operation completed despite cancellation. On
308 successful cancellation, the operation is not deleted; instead,
309 it becomes an operation with an
310 [Operation.error][google.api_core.operations_v1.Operation.error] value with
311 a [google.rpc.Status.code][google.rpc.Status.code] of 1,
312 corresponding to ``Code.CANCELLED``.
313
314 Args:
315 name (str):
316 The name of the operation resource to
317 be cancelled.
318
319 This corresponds to the ``name`` field
320 on the ``request`` instance; if ``request`` is provided, this
321 should not be set.
322 timeout (float): The timeout for this request.
323 metadata (Sequence[Tuple[str, str]]): Strings which should be
324 sent along with the request as metadata.
325 """
326 # Create the request object.
327 request = operations_pb2.CancelOperationRequest(name=name)
328
329 # Wrap the RPC method; this adds retry and timeout information,
330 # and friendly error handling.
331 rpc = self._transport._wrapped_methods[self._transport.cancel_operation]
332
333 # Certain fields should be provided within the metadata header;
334 # add these here.
335 metadata = tuple(metadata or ()) + (
336 gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
337 )
338
339 # Send the request.
340 await rpc(
341 request,
342 retry=retry,
343 timeout=timeout,
344 metadata=metadata,
345 )