apache-airflow-providers-google 10.2.0rc1__py3-none-any.whl → 10.3.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. airflow/providers/google/__init__.py +1 -1
  2. airflow/providers/google/ads/hooks/ads.py +38 -39
  3. airflow/providers/google/ads/transfers/ads_to_gcs.py +4 -4
  4. airflow/providers/google/cloud/_internal_client/secret_manager_client.py +6 -9
  5. airflow/providers/google/cloud/hooks/bigquery.py +328 -318
  6. airflow/providers/google/cloud/hooks/cloud_sql.py +66 -22
  7. airflow/providers/google/cloud/hooks/cloud_storage_transfer_service.py +46 -70
  8. airflow/providers/google/cloud/hooks/dataflow.py +11 -15
  9. airflow/providers/google/cloud/hooks/dataform.py +3 -3
  10. airflow/providers/google/cloud/hooks/dataproc.py +577 -573
  11. airflow/providers/google/cloud/hooks/functions.py +60 -76
  12. airflow/providers/google/cloud/hooks/gcs.py +108 -18
  13. airflow/providers/google/cloud/hooks/kubernetes_engine.py +69 -90
  14. airflow/providers/google/cloud/links/datafusion.py +4 -3
  15. airflow/providers/google/cloud/operators/bigquery.py +201 -191
  16. airflow/providers/google/cloud/operators/bigquery_dts.py +2 -1
  17. airflow/providers/google/cloud/operators/cloud_build.py +2 -1
  18. airflow/providers/google/cloud/operators/cloud_composer.py +4 -3
  19. airflow/providers/google/cloud/operators/cloud_sql.py +62 -28
  20. airflow/providers/google/cloud/operators/dataflow.py +6 -4
  21. airflow/providers/google/cloud/operators/dataform.py +3 -2
  22. airflow/providers/google/cloud/operators/dataproc.py +127 -123
  23. airflow/providers/google/cloud/operators/dataproc_metastore.py +18 -26
  24. airflow/providers/google/cloud/operators/gcs.py +35 -13
  25. airflow/providers/google/cloud/operators/kubernetes_engine.py +92 -42
  26. airflow/providers/google/cloud/operators/mlengine.py +2 -6
  27. airflow/providers/google/cloud/operators/vision.py +47 -56
  28. airflow/providers/google/cloud/sensors/bigquery.py +3 -2
  29. airflow/providers/google/cloud/sensors/gcs.py +5 -7
  30. airflow/providers/google/cloud/sensors/pubsub.py +2 -2
  31. airflow/providers/google/cloud/transfers/bigquery_to_bigquery.py +3 -2
  32. airflow/providers/google/cloud/transfers/bigquery_to_gcs.py +2 -1
  33. airflow/providers/google/cloud/transfers/facebook_ads_to_gcs.py +4 -4
  34. airflow/providers/google/cloud/transfers/gcs_to_bigquery.py +6 -5
  35. airflow/providers/google/cloud/transfers/gcs_to_gcs.py +46 -7
  36. airflow/providers/google/cloud/transfers/gcs_to_sftp.py +5 -2
  37. airflow/providers/google/cloud/triggers/cloud_sql.py +102 -0
  38. airflow/providers/google/cloud/triggers/kubernetes_engine.py +28 -6
  39. airflow/providers/google/cloud/utils/bigquery.py +17 -0
  40. airflow/providers/google/get_provider_info.py +7 -2
  41. airflow/providers/google/suite/transfers/gcs_to_gdrive.py +4 -0
  42. airflow/providers/google/suite/transfers/local_to_drive.py +28 -26
  43. apache_airflow_providers_google-10.3.0rc1.dist-info/METADATA +289 -0
  44. {apache_airflow_providers_google-10.2.0rc1.dist-info → apache_airflow_providers_google-10.3.0rc1.dist-info}/RECORD +49 -48
  45. apache_airflow_providers_google-10.2.0rc1.dist-info/METADATA +0 -1824
  46. {apache_airflow_providers_google-10.2.0rc1.dist-info → apache_airflow_providers_google-10.3.0rc1.dist-info}/LICENSE +0 -0
  47. {apache_airflow_providers_google-10.2.0rc1.dist-info → apache_airflow_providers_google-10.3.0rc1.dist-info}/NOTICE +0 -0
  48. {apache_airflow_providers_google-10.2.0rc1.dist-info → apache_airflow_providers_google-10.3.0rc1.dist-info}/WHEEL +0 -0
  49. {apache_airflow_providers_google-10.2.0rc1.dist-info → apache_airflow_providers_google-10.3.0rc1.dist-info}/entry_points.txt +0 -0
  50. {apache_airflow_providers_google-10.2.0rc1.dist-info → apache_airflow_providers_google-10.3.0rc1.dist-info}/top_level.txt +0 -0
@@ -39,16 +39,18 @@ from typing import Any, Sequence
39
39
  from urllib.parse import quote_plus
40
40
 
41
41
  import httpx
42
+ from aiohttp import ClientSession
43
+ from gcloud.aio.auth import AioSession, Token
42
44
  from googleapiclient.discovery import Resource, build
43
45
  from googleapiclient.errors import HttpError
44
-
45
- from airflow.exceptions import AirflowException
46
+ from requests import Session
46
47
 
47
48
  # Number of retries - used by googleapiclient method calls to perform retries
48
49
  # For requests that are "retriable"
50
+ from airflow.exceptions import AirflowException
49
51
  from airflow.hooks.base import BaseHook
50
52
  from airflow.models import Connection
51
- from airflow.providers.google.common.hooks.base_google import GoogleBaseHook, get_field
53
+ from airflow.providers.google.common.hooks.base_google import GoogleBaseAsyncHook, GoogleBaseHook, get_field
52
54
  from airflow.providers.mysql.hooks.mysql import MySqlHook
53
55
  from airflow.providers.postgres.hooks.postgres import PostgresHook
54
56
  from airflow.utils.log.logging_mixin import LoggingMixin
@@ -300,8 +302,7 @@ class CloudSQLHook(GoogleBaseHook):
300
302
  self._wait_for_operation_to_complete(project_id=project_id, operation_name=operation_name)
301
303
 
302
304
  @GoogleBaseHook.fallback_to_default_project_id
303
- @GoogleBaseHook.operation_in_progress_retry()
304
- def export_instance(self, instance: str, body: dict, project_id: str) -> None:
305
+ def export_instance(self, instance: str, body: dict, project_id: str):
305
306
  """
306
307
  Exports data from a Cloud SQL instance to a Cloud Storage bucket as a SQL dump
307
308
  or CSV file.
@@ -321,7 +322,7 @@ class CloudSQLHook(GoogleBaseHook):
321
322
  .execute(num_retries=self.num_retries)
322
323
  )
323
324
  operation_name = response["name"]
324
- self._wait_for_operation_to_complete(project_id=project_id, operation_name=operation_name)
325
+ return operation_name
325
326
 
326
327
  @GoogleBaseHook.fallback_to_default_project_id
327
328
  def import_instance(self, instance: str, body: dict, project_id: str) -> None:
@@ -376,6 +377,7 @@ class CloudSQLHook(GoogleBaseHook):
376
377
  except HttpError as ex:
377
378
  raise AirflowException(f"Cloning of instance {instance} failed: {ex.content}")
378
379
 
380
+ @GoogleBaseHook.fallback_to_default_project_id
379
381
  def _wait_for_operation_to_complete(
380
382
  self, project_id: str, operation_name: str, time_to_sleep: int = TIME_TO_SLEEP_IN_SECONDS
381
383
  ) -> None:
@@ -412,6 +414,42 @@ CLOUD_SQL_PROXY_VERSION_DOWNLOAD_URL = (
412
414
  )
413
415
 
414
416
 
417
+ class CloudSQLAsyncHook(GoogleBaseAsyncHook):
418
+ """Class to get asynchronous hook for Google Cloud SQL."""
419
+
420
+ sync_hook_class = CloudSQLHook
421
+
422
+ async def _get_conn(self, session: Session, url: str):
423
+ scopes = [
424
+ "https://www.googleapis.com/auth/cloud-platform",
425
+ "https://www.googleapis.com/auth/sqlservice.admin",
426
+ ]
427
+
428
+ async with Token(scopes=scopes) as token:
429
+ session_aio = AioSession(session)
430
+ headers = {
431
+ "Authorization": f"Bearer {await token.get()}",
432
+ }
433
+ return await session_aio.get(url=url, headers=headers)
434
+
435
+ async def get_operation_name(self, project_id: str, operation_name: str, session):
436
+ url = f"https://sqladmin.googleapis.com/sql/v1beta4/projects/{project_id}/operations/{operation_name}"
437
+ return await self._get_conn(url=str(url), session=session)
438
+
439
+ async def get_operation(self, project_id: str, operation_name: str):
440
+ async with ClientSession() as session:
441
+ try:
442
+ operation = await self.get_operation_name(
443
+ project_id=project_id,
444
+ operation_name=operation_name,
445
+ session=session,
446
+ )
447
+ operation = await operation.json(content_type=None)
448
+ except HttpError as e:
449
+ raise e
450
+ return operation
451
+
452
+
415
453
  class CloudSqlProxyRunner(LoggingMixin):
416
454
  """
417
455
  Downloads and runs cloud-sql-proxy as subprocess of the Python process.
@@ -840,12 +878,13 @@ class CloudSQLDatabaseHook(BaseHook):
840
878
 
841
879
  @staticmethod
842
880
  def _generate_unique_path() -> str:
843
- """
844
- We are not using mkdtemp here as the path generated with mkdtemp
845
- can be close to 60 characters and there is a limitation in
846
- length of socket path to around 100 characters in total.
847
- We append project/location/instance to it later and postgres
848
- appends its own prefix, so we chose a shorter "${tempdir()}[8 random characters]".
881
+ """Generate a unique path.
882
+
883
+ We don't using mkdtemp here since it can generate paths close to 60
884
+ characters. We append project/location/instance to the path, Postgres
885
+ will then appends its own prefix, making the resulting path exceed the
886
+ 100 character length limitation of a socket path. This generates a
887
+ shorter path ``${tempdir()}[8 random characters]``.
849
888
  """
850
889
  random.seed()
851
890
  while True:
@@ -926,9 +965,10 @@ class CloudSQLDatabaseHook(BaseHook):
926
965
  return instance_specification
927
966
 
928
967
  def create_connection(self) -> Connection:
929
- """
930
- Create Connection object, according to whether it uses proxy, TCP, UNIX sockets, SSL.
931
- Connection ID will be randomly generated.
968
+ """Create a connection.
969
+
970
+ Connection ID will be randomly generated according to whether it uses
971
+ proxy, TCP, UNIX sockets, SSL.
932
972
  """
933
973
  uri = self._generate_connection_uri()
934
974
  connection = Connection(conn_id=self.db_conn_id, uri=uri)
@@ -936,9 +976,9 @@ class CloudSQLDatabaseHook(BaseHook):
936
976
  return connection
937
977
 
938
978
  def get_sqlproxy_runner(self) -> CloudSqlProxyRunner:
939
- """
940
- Retrieve Cloud SQL Proxy runner. It is used to manage the proxy
941
- lifecycle per task.
979
+ """Retrieve Cloud SQL Proxy runner.
980
+
981
+ It is used to manage the proxy lifecycle per task.
942
982
 
943
983
  :return: The Cloud SQL Proxy runner.
944
984
  """
@@ -956,9 +996,10 @@ class CloudSQLDatabaseHook(BaseHook):
956
996
  )
957
997
 
958
998
  def get_database_hook(self, connection: Connection) -> PostgresHook | MySqlHook:
959
- """
960
- Retrieve database hook. This is the actual Postgres or MySQL database hook
961
- that uses proxy or connects directly to the Google Cloud SQL database.
999
+ """Retrieve database hook.
1000
+
1001
+ This is the actual Postgres or MySQL database hook that uses proxy or
1002
+ connects directly to the Google Cloud SQL database.
962
1003
  """
963
1004
  if self.database_type == "postgres":
964
1005
  db_hook: PostgresHook | MySqlHook = PostgresHook(connection=connection, schema=self.database)
@@ -986,7 +1027,10 @@ class CloudSQLDatabaseHook(BaseHook):
986
1027
  self.sql_proxy_tcp_port = self.reserved_tcp_socket.getsockname()[1]
987
1028
 
988
1029
  def free_reserved_port(self) -> None:
989
- """Free TCP port. Makes it immediately ready to be used by Cloud SQL Proxy."""
1030
+ """Free TCP port.
1031
+
1032
+ Makes it immediately ready to be used by Cloud SQL Proxy.
1033
+ """
990
1034
  if self.reserved_tcp_socket:
991
1035
  self.reserved_tcp_socket.close()
992
1036
  self.reserved_tcp_socket = None
@@ -39,7 +39,7 @@ TIME_TO_SLEEP_IN_SECONDS = 10
39
39
 
40
40
 
41
41
  class GcpTransferJobsStatus:
42
- """Class with Google Cloud Transfer jobs statuses."""
42
+ """Google Cloud Transfer job status."""
43
43
 
44
44
  ENABLED = "ENABLED"
45
45
  DISABLED = "DISABLED"
@@ -47,7 +47,7 @@ class GcpTransferJobsStatus:
47
47
 
48
48
 
49
49
  class GcpTransferOperationStatus:
50
- """Class with Google Cloud Transfer operations statuses."""
50
+ """Google Cloud Transfer operation status."""
51
51
 
52
52
  IN_PROGRESS = "IN_PROGRESS"
53
53
  PAUSED = "PAUSED"
@@ -104,9 +104,7 @@ NEGATIVE_STATUSES = {GcpTransferOperationStatus.FAILED, GcpTransferOperationStat
104
104
 
105
105
 
106
106
  def gen_job_name(job_name: str) -> str:
107
- """
108
- Adds unique suffix to job name. If suffix already exists, updates it.
109
- Suffix — current timestamp.
107
+ """Add a unique suffix to the job name.
110
108
 
111
109
  :param job_name:
112
110
  :return: job_name with suffix
@@ -116,11 +114,10 @@ def gen_job_name(job_name: str) -> str:
116
114
 
117
115
 
118
116
  class CloudDataTransferServiceHook(GoogleBaseHook):
119
- """
120
- Hook for Google Storage Transfer Service.
117
+ """Google Storage Transfer Service functionalities.
121
118
 
122
- All the methods in the hook where project_id is used must be called with
123
- keyword arguments rather than positional.
119
+ All methods in the hook with *project_id* in the signature must be called
120
+ with keyword arguments rather than positional.
124
121
  """
125
122
 
126
123
  def __init__(
@@ -130,10 +127,11 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
130
127
  impersonation_chain: str | Sequence[str] | None = None,
131
128
  **kwargs,
132
129
  ) -> None:
133
- if kwargs.get("delegate_to") is not None:
130
+ if "delegate_to" in kwargs:
134
131
  raise RuntimeError(
135
- "The `delegate_to` parameter has been deprecated before and finally removed in this version"
136
- " of Google Provider. You MUST convert it to `impersonate_chain`"
132
+ "The `delegate_to` parameter has been deprecated before and "
133
+ "finally removed in this version of Google Provider. You MUST "
134
+ "convert it to `impersonate_chain`."
137
135
  )
138
136
  super().__init__(
139
137
  gcp_conn_id=gcp_conn_id,
@@ -143,8 +141,7 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
143
141
  self._conn = None
144
142
 
145
143
  def get_conn(self) -> Resource:
146
- """
147
- Retrieves connection to Google Storage Transfer service.
144
+ """Retrieve connection to Google Storage Transfer service.
148
145
 
149
146
  :return: Google Storage Transfer service object
150
147
  """
@@ -156,13 +153,11 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
156
153
  return self._conn
157
154
 
158
155
  def create_transfer_job(self, body: dict) -> dict:
159
- """
160
- Creates a transfer job that runs periodically.
156
+ """Create a transfer job that runs periodically.
161
157
 
162
- :param body: (Required) A request body, as described in
158
+ :param body: (Required) The request body, as described in
163
159
  https://cloud.google.com/storage-transfer/docs/reference/rest/v1/transferJobs/patch#request-body
164
- :return: transfer job.
165
- See:
160
+ :return: The transfer job. See:
166
161
  https://cloud.google.com/storage-transfer/docs/reference/rest/v1/transferJobs#TransferJob
167
162
  """
168
163
  body = self._inject_project_id(body, BODY, PROJECT_ID)
@@ -200,9 +195,7 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
200
195
 
201
196
  @GoogleBaseHook.fallback_to_default_project_id
202
197
  def get_transfer_job(self, job_name: str, project_id: str) -> dict:
203
- """
204
- Gets the latest state of a long-running operation in Google Storage
205
- Transfer Service.
198
+ """Get latest state of a long-running Google Storage Transfer Service job.
206
199
 
207
200
  :param job_name: (Required) Name of the job to be fetched
208
201
  :param project_id: (Optional) the ID of the project that owns the Transfer
@@ -218,9 +211,9 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
218
211
  )
219
212
 
220
213
  def list_transfer_job(self, request_filter: dict | None = None, **kwargs) -> list[dict]:
221
- """
222
- Lists long-running operations in Google Storage Transfer
223
- Service that match the specified filter.
214
+ """List long-running operations in Google Storage Transfer Service.
215
+
216
+ A filter can be specified to match only certain entries.
224
217
 
225
218
  :param request_filter: (Required) A request filter, as described in
226
219
  https://cloud.google.com/storage-transfer/docs/reference/rest/v1/transferJobs/list#body.QUERY_PARAMETERS.filter
@@ -252,8 +245,7 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
252
245
 
253
246
  @GoogleBaseHook.fallback_to_default_project_id
254
247
  def enable_transfer_job(self, job_name: str, project_id: str) -> dict:
255
- """
256
- New transfers will be performed based on the schedule.
248
+ """Make new transfers be performed based on the schedule.
257
249
 
258
250
  :param job_name: (Required) Name of the job to be updated
259
251
  :param project_id: (Optional) the ID of the project that owns the Transfer
@@ -276,8 +268,7 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
276
268
  )
277
269
 
278
270
  def update_transfer_job(self, job_name: str, body: dict) -> dict:
279
- """
280
- Updates a transfer job that runs periodically.
271
+ """Update a transfer job that runs periodically.
281
272
 
282
273
  :param job_name: (Required) Name of the job to be updated
283
274
  :param body: A request body, as described in
@@ -294,11 +285,11 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
294
285
 
295
286
  @GoogleBaseHook.fallback_to_default_project_id
296
287
  def delete_transfer_job(self, job_name: str, project_id: str) -> None:
297
- """
298
- Deletes a transfer job. This is a soft delete. After a transfer job is
299
- deleted, the job and all the transfer executions are subject to garbage
300
- collection. Transfer jobs become eligible for garbage collection
301
- 30 days after soft delete.
288
+ """Delete a transfer job.
289
+
290
+ This is a soft delete. After a transfer job is deleted, the job and all
291
+ the transfer executions are subject to garbage collection. Transfer jobs
292
+ become eligible for garbage collection 30 days after soft delete.
302
293
 
303
294
  :param job_name: (Required) Name of the job to be deleted
304
295
  :param project_id: (Optional) the ID of the project that owns the Transfer
@@ -320,21 +311,19 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
320
311
  )
321
312
 
322
313
  def cancel_transfer_operation(self, operation_name: str) -> None:
323
- """
324
- Cancels an transfer operation in Google Storage Transfer Service.
314
+ """Cancel a transfer operation in Google Storage Transfer Service.
325
315
 
326
316
  :param operation_name: Name of the transfer operation.
327
317
  """
328
318
  self.get_conn().transferOperations().cancel(name=operation_name).execute(num_retries=self.num_retries)
329
319
 
330
320
  def get_transfer_operation(self, operation_name: str) -> dict:
331
- """
332
- Gets an transfer operation in Google Storage Transfer Service.
321
+ """Get a transfer operation in Google Storage Transfer Service.
333
322
 
334
323
  :param operation_name: (Required) Name of the transfer operation.
335
324
  :return: transfer operation
336
- See:
337
- https://cloud.google.com/storage-transfer/docs/reference/rest/v1/Operation
325
+
326
+ .. seealso:: https://cloud.google.com/storage-transfer/docs/reference/rest/v1/Operation
338
327
  """
339
328
  return (
340
329
  self.get_conn()
@@ -344,18 +333,15 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
344
333
  )
345
334
 
346
335
  def list_transfer_operations(self, request_filter: dict | None = None, **kwargs) -> list[dict]:
347
- """
348
- Gets an transfer operation in Google Storage Transfer Service.
336
+ """Get a transfer operation in Google Storage Transfer Service.
349
337
 
350
338
  :param request_filter: (Required) A request filter, as described in
351
339
  https://cloud.google.com/storage-transfer/docs/reference/rest/v1/transferJobs/list#body.QUERY_PARAMETERS.filter
352
340
  With one additional improvement:
353
-
354
- * project_id is optional if you have a project id defined
355
- in the connection
356
- See: :doc:`/connections/gcp`
357
-
358
341
  :return: transfer operation
342
+
343
+ The ``project_id`` parameter is optional if you have a project ID
344
+ defined in the connection. See: :doc:`/connections/gcp`
359
345
  """
360
346
  # To preserve backward compatibility
361
347
  # TODO: remove one day
@@ -390,16 +376,14 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
390
376
  return operations
391
377
 
392
378
  def pause_transfer_operation(self, operation_name: str) -> None:
393
- """
394
- Pauses an transfer operation in Google Storage Transfer Service.
379
+ """Pause a transfer operation in Google Storage Transfer Service.
395
380
 
396
381
  :param operation_name: (Required) Name of the transfer operation.
397
382
  """
398
383
  self.get_conn().transferOperations().pause(name=operation_name).execute(num_retries=self.num_retries)
399
384
 
400
385
  def resume_transfer_operation(self, operation_name: str) -> None:
401
- """
402
- Resumes an transfer operation in Google Storage Transfer Service.
386
+ """Resume a transfer operation in Google Storage Transfer Service.
403
387
 
404
388
  :param operation_name: (Required) Name of the transfer operation.
405
389
  """
@@ -411,17 +395,14 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
411
395
  expected_statuses: set[str] | None = None,
412
396
  timeout: float | timedelta | None = None,
413
397
  ) -> None:
414
- """
415
- Waits until the job reaches the expected state.
398
+ """Wait until the job reaches the expected state.
416
399
 
417
- :param job: Transfer job
418
- See:
400
+ :param job: The transfer job to wait for. See:
419
401
  https://cloud.google.com/storage-transfer/docs/reference/rest/v1/transferJobs#TransferJob
420
- :param expected_statuses: State that is expected
421
- See:
402
+ :param expected_statuses: The expected state. See:
422
403
  https://cloud.google.com/storage-transfer/docs/reference/rest/v1/transferOperations#Status
423
- :param timeout: Time in which the operation must end in seconds. If not specified, defaults to 60
424
- seconds.
404
+ :param timeout: Time in which the operation must end in seconds. If not
405
+ specified, defaults to 60 seconds.
425
406
  """
426
407
  expected_statuses = (
427
408
  {GcpTransferOperationStatus.SUCCESS} if not expected_statuses else expected_statuses
@@ -458,20 +439,15 @@ class CloudDataTransferServiceHook(GoogleBaseHook):
458
439
  def operations_contain_expected_statuses(
459
440
  operations: list[dict], expected_statuses: set[str] | str
460
441
  ) -> bool:
461
- """
462
- Checks whether the operation list has an operation with the
463
- expected status, then returns true
464
- If it encounters operations in FAILED or ABORTED state
465
- throw :class:`airflow.exceptions.AirflowException`.
442
+ """Check whether an operation exists with the expected status.
466
443
 
467
444
  :param operations: (Required) List of transfer operations to check.
468
- :param expected_statuses: (Required) status that is expected
469
- See:
445
+ :param expected_statuses: (Required) The expected status. See:
470
446
  https://cloud.google.com/storage-transfer/docs/reference/rest/v1/transferOperations#Status
471
- :return: If there is an operation with the expected state
472
- in the operation list, returns true,
473
- :raises: airflow.exceptions.AirflowException If it encounters operations
474
- with a state in the list,
447
+ :return: If there is an operation with the expected state in the
448
+ operation list, returns true,
449
+ :raises AirflowException: If it encounters operations with state FAILED
450
+ or ABORTED in the list.
475
451
  """
476
452
  expected_statuses_set = (
477
453
  {expected_statuses} if isinstance(expected_statuses, str) else set(expected_statuses)
@@ -57,29 +57,25 @@ T = TypeVar("T", bound=Callable)
57
57
  def process_line_and_extract_dataflow_job_id_callback(
58
58
  on_new_job_id_callback: Callable[[str], None] | None
59
59
  ) -> Callable[[str], None]:
60
- """
61
- Returns callback which triggers function passed as `on_new_job_id_callback` when Dataflow job_id is found.
62
- To be used for `process_line_callback` in
60
+ """Build callback that triggers the specified function.
61
+
62
+ The returned callback is intended to be used as ``process_line_callback`` in
63
63
  :py:class:`~airflow.providers.apache.beam.hooks.beam.BeamCommandRunner`.
64
64
 
65
65
  :param on_new_job_id_callback: Callback called when the job ID is known
66
66
  """
67
67
 
68
- def _process_line_and_extract_job_id(
69
- line: str,
70
- # on_new_job_id_callback: Callable[[str], None] | None
71
- ) -> None:
68
+ def _process_line_and_extract_job_id(line: str) -> None:
72
69
  # Job id info: https://goo.gl/SE29y9.
70
+ if on_new_job_id_callback is None:
71
+ return
73
72
  matched_job = JOB_ID_PATTERN.search(line)
74
- if matched_job:
75
- job_id = matched_job.group("job_id_java") or matched_job.group("job_id_python")
76
- if on_new_job_id_callback:
77
- on_new_job_id_callback(job_id)
78
-
79
- def wrap(line: str):
80
- return _process_line_and_extract_job_id(line)
73
+ if matched_job is None:
74
+ return
75
+ job_id = matched_job.group("job_id_java") or matched_job.group("job_id_python")
76
+ on_new_job_id_callback(job_id)
81
77
 
82
- return wrap
78
+ return _process_line_and_extract_job_id
83
79
 
84
80
 
85
81
  def _fallback_variable_parameter(parameter_name: str, variable_key_name: str) -> Callable[[T], T]:
@@ -604,9 +604,9 @@ class DataformHook(GoogleBaseHook):
604
604
  timeout: float | None = None,
605
605
  metadata: Sequence[tuple[str, str]] = (),
606
606
  ) -> InstallNpmPackagesResponse:
607
- """
608
- Installs npm dependencies in the provided workspace. Requires "package.json"
609
- to be created in workspace.
607
+ """Install NPM dependencies in the provided workspace.
608
+
609
+ Requires "package.json" to be created in the workspace.
610
610
 
611
611
  :param project_id: Required. The ID of the Google Cloud project where workspace located.
612
612
  :param region: Required. The ID of the Google Cloud region where workspace located.