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
@@ -21,6 +21,7 @@ from __future__ import annotations
21
21
  import datetime
22
22
  import subprocess
23
23
  import sys
24
+ import warnings
24
25
  from pathlib import Path
25
26
  from tempfile import NamedTemporaryFile, TemporaryDirectory
26
27
  from typing import TYPE_CHECKING, Sequence
@@ -33,7 +34,7 @@ if TYPE_CHECKING:
33
34
  from google.api_core.exceptions import Conflict
34
35
  from google.cloud.exceptions import GoogleCloudError
35
36
 
36
- from airflow.exceptions import AirflowException
37
+ from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning
37
38
  from airflow.providers.google.cloud.hooks.gcs import GCSHook
38
39
  from airflow.providers.google.cloud.operators.cloud_base import GoogleCloudBaseOperator
39
40
  from airflow.providers.google.common.links.storage import FileDetailsLink, StorageLink
@@ -157,16 +158,17 @@ class GCSCreateBucketOperator(GoogleCloudBaseOperator):
157
158
 
158
159
  class GCSListObjectsOperator(GoogleCloudBaseOperator):
159
160
  """
160
- List all objects from the bucket with the given string prefix and delimiter in name.
161
+ List all objects from the bucket filtered by given string prefix and delimiter in name,
162
+ or match_glob.
161
163
 
162
164
  This operator returns a python list with the name of objects which can be used by
163
165
  XCom in the downstream task.
164
166
 
165
167
  :param bucket: The Google Cloud Storage bucket to find the objects. (templated)
166
- :param prefix: String or list of strings, which filter objects whose name begin with
168
+ :param prefix: String or list of strings, which filter objects whose name begins with
167
169
  it/them. (templated)
168
- :param delimiter: The delimiter by which you want to filter the objects. (templated)
169
- For example, to lists the CSV files from in a directory in GCS you would use
170
+ :param delimiter: (Deprecated) The delimiter by which you want to filter the objects. (templated)
171
+ For example, to list the CSV files from in a directory in GCS you would use
170
172
  delimiter='.csv'.
171
173
  :param gcp_conn_id: (Optional) The connection ID used to connect to Google Cloud.
172
174
  :param impersonation_chain: Optional service account to impersonate using short-term
@@ -177,6 +179,8 @@ class GCSListObjectsOperator(GoogleCloudBaseOperator):
177
179
  If set as a sequence, the identities from the list must grant
178
180
  Service Account Token Creator IAM role to the directly preceding identity, with first
179
181
  account from the list granting this role to the originating account (templated).
182
+ :param match_glob: (Optional) filters objects based on the glob pattern given by the string
183
+ (e.g, ``'**/*/.json'``)
180
184
 
181
185
  **Example**:
182
186
  The following Operator would list all the Avro files from ``sales/sales-2017``
@@ -186,7 +190,7 @@ class GCSListObjectsOperator(GoogleCloudBaseOperator):
186
190
  task_id='GCS_Files',
187
191
  bucket='data',
188
192
  prefix='sales/sales-2017/',
189
- delimiter='.avro',
193
+ match_glob='**/*/.avro',
190
194
  gcp_conn_id=google_cloud_conn_id
191
195
  )
192
196
  """
@@ -210,14 +214,22 @@ class GCSListObjectsOperator(GoogleCloudBaseOperator):
210
214
  delimiter: str | None = None,
211
215
  gcp_conn_id: str = "google_cloud_default",
212
216
  impersonation_chain: str | Sequence[str] | None = None,
217
+ match_glob: str | None = None,
213
218
  **kwargs,
214
219
  ) -> None:
215
220
  super().__init__(**kwargs)
216
221
  self.bucket = bucket
217
222
  self.prefix = prefix
223
+ if delimiter:
224
+ warnings.warn(
225
+ "Usage of 'delimiter' is deprecated, please use 'match_glob' instead",
226
+ AirflowProviderDeprecationWarning,
227
+ stacklevel=2,
228
+ )
218
229
  self.delimiter = delimiter
219
230
  self.gcp_conn_id = gcp_conn_id
220
231
  self.impersonation_chain = impersonation_chain
232
+ self.match_glob = match_glob
221
233
 
222
234
  def execute(self, context: Context) -> list:
223
235
  hook = GCSHook(
@@ -225,12 +237,20 @@ class GCSListObjectsOperator(GoogleCloudBaseOperator):
225
237
  impersonation_chain=self.impersonation_chain,
226
238
  )
227
239
 
228
- self.log.info(
229
- "Getting list of the files. Bucket: %s; Delimiter: %s; Prefix(es): %s",
230
- self.bucket,
231
- self.delimiter,
232
- self.prefix,
233
- )
240
+ if self.match_glob:
241
+ self.log.info(
242
+ "Getting list of the files. Bucket: %s; MatchGlob: %s; Prefix(es): %s",
243
+ self.bucket,
244
+ self.match_glob,
245
+ self.prefix,
246
+ )
247
+ else:
248
+ self.log.info(
249
+ "Getting list of the files. Bucket: %s; Delimiter: %s; Prefix(es): %s",
250
+ self.bucket,
251
+ self.delimiter,
252
+ self.prefix,
253
+ )
234
254
 
235
255
  StorageLink.persist(
236
256
  context=context,
@@ -238,7 +258,9 @@ class GCSListObjectsOperator(GoogleCloudBaseOperator):
238
258
  uri=self.bucket,
239
259
  project_id=hook.project_id,
240
260
  )
241
- return hook.list(bucket_name=self.bucket, prefix=self.prefix, delimiter=self.delimiter)
261
+ return hook.list(
262
+ bucket_name=self.bucket, prefix=self.prefix, delimiter=self.delimiter, match_glob=self.match_glob
263
+ )
242
264
 
243
265
 
244
266
  class GCSDeleteObjectsOperator(GoogleCloudBaseOperator):
@@ -20,19 +20,22 @@ from __future__ import annotations
20
20
 
21
21
  import warnings
22
22
  from functools import cached_property
23
- from typing import TYPE_CHECKING, Sequence
23
+ from typing import TYPE_CHECKING, Any, Sequence
24
24
 
25
25
  from google.api_core.exceptions import AlreadyExists
26
26
  from google.cloud.container_v1.types import Cluster
27
27
  from kubernetes.client.models import V1Pod
28
28
 
29
+ from airflow.configuration import conf
29
30
  from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning
31
+ from airflow.providers.cncf.kubernetes.utils.pod_manager import OnFinishAction
30
32
 
31
33
  try:
32
34
  from airflow.providers.cncf.kubernetes.operators.pod import KubernetesPodOperator
33
35
  except ImportError:
34
36
  # preserve backward compatibility for older versions of cncf.kubernetes provider
35
37
  from airflow.providers.cncf.kubernetes.operators.kubernetes_pod import KubernetesPodOperator
38
+
36
39
  from airflow.providers.google.cloud.hooks.kubernetes_engine import GKEHook, GKEPodHook
37
40
  from airflow.providers.google.cloud.links.kubernetes_engine import (
38
41
  KubernetesEngineClusterLink,
@@ -45,7 +48,6 @@ from airflow.utils.timezone import utcnow
45
48
  if TYPE_CHECKING:
46
49
  from airflow.utils.context import Context
47
50
 
48
-
49
51
  KUBE_CONFIG_ENV_VAR = "KUBECONFIG"
50
52
 
51
53
 
@@ -108,7 +110,7 @@ class GKEDeleteClusterOperator(GoogleCloudBaseOperator):
108
110
  gcp_conn_id: str = "google_cloud_default",
109
111
  api_version: str = "v2",
110
112
  impersonation_chain: str | Sequence[str] | None = None,
111
- deferrable: bool = False,
113
+ deferrable: bool = conf.getboolean("operators", "default_deferrable", fallback=False),
112
114
  poll_interval: int = 10,
113
115
  **kwargs,
114
116
  ) -> None:
@@ -255,7 +257,7 @@ class GKECreateClusterOperator(GoogleCloudBaseOperator):
255
257
  api_version: str = "v2",
256
258
  impersonation_chain: str | Sequence[str] | None = None,
257
259
  poll_interval: int = 10,
258
- deferrable: bool = False,
260
+ deferrable: bool = conf.getboolean("operators", "default_deferrable", fallback=False),
259
261
  **kwargs,
260
262
  ) -> None:
261
263
  super().__init__(**kwargs)
@@ -268,41 +270,71 @@ class GKECreateClusterOperator(GoogleCloudBaseOperator):
268
270
  self.impersonation_chain = impersonation_chain
269
271
  self.poll_interval = poll_interval
270
272
  self.deferrable = deferrable
271
- self._check_input()
273
+ self._validate_input()
272
274
 
273
275
  self._hook: GKEHook | None = None
274
276
 
275
- def _check_input(self) -> None:
276
- if (
277
- not all([self.project_id, self.location, self.body])
278
- or (isinstance(self.body, dict) and "name" not in self.body)
279
- or (
280
- isinstance(self.body, dict)
281
- and ("initial_node_count" not in self.body and "node_pools" not in self.body)
282
- )
283
- or (not (isinstance(self.body, dict)) and not (getattr(self.body, "name", None)))
284
- or (
285
- not (isinstance(self.body, dict))
286
- and (
287
- not (getattr(self.body, "initial_node_count", None))
288
- and not (getattr(self.body, "node_pools", None))
277
+ def _validate_input(self) -> None:
278
+ """Primary validation of the input body."""
279
+ self._alert_deprecated_body_fields()
280
+
281
+ error_messages: list[str] = []
282
+ if not self._body_field("name"):
283
+ error_messages.append("Field body['name'] is missing or incorrect")
284
+
285
+ if self._body_field("initial_node_count"):
286
+ if self._body_field("node_pools"):
287
+ error_messages.append(
288
+ "Do not use filed body['initial_node_count'] and body['node_pools'] at the same time."
289
289
  )
290
- )
291
- ):
292
- self.log.error(
293
- "One of (project_id, location, body, body['name'], "
294
- "body['initial_node_count']), body['node_pools'] is missing or incorrect"
295
- )
296
- raise AirflowException("Operator has incorrect or missing input.")
297
- elif (
298
- isinstance(self.body, dict) and ("initial_node_count" in self.body and "node_pools" in self.body)
299
- ) or (
300
- not (isinstance(self.body, dict))
301
- and (getattr(self.body, "initial_node_count", None) and getattr(self.body, "node_pools", None))
302
- ):
303
- self.log.error("Only one of body['initial_node_count']) and body['node_pools'] may be specified")
290
+
291
+ if self._body_field("node_config"):
292
+ if self._body_field("node_pools"):
293
+ error_messages.append(
294
+ "Do not use filed body['node_config'] and body['node_pools'] at the same time."
295
+ )
296
+
297
+ if self._body_field("node_pools"):
298
+ if any([self._body_field("node_config"), self._body_field("initial_node_count")]):
299
+ error_messages.append(
300
+ "The field body['node_pools'] should not be set if "
301
+ "body['node_config'] or body['initial_code_count'] are specified."
302
+ )
303
+
304
+ if not any([self._body_field("node_config"), self._body_field("initial_node_count")]):
305
+ if not self._body_field("node_pools"):
306
+ error_messages.append(
307
+ "Field body['node_pools'] is required if none of fields "
308
+ "body['initial_node_count'] or body['node_pools'] are specified."
309
+ )
310
+
311
+ for message in error_messages:
312
+ self.log.error(message)
313
+
314
+ if error_messages:
304
315
  raise AirflowException("Operator has incorrect or missing input.")
305
316
 
317
+ def _body_field(self, field_name: str, default_value: Any = None) -> Any:
318
+ """Extracts the value of the given field name."""
319
+ if isinstance(self.body, dict):
320
+ return self.body.get(field_name, default_value)
321
+ else:
322
+ return getattr(self.body, field_name, default_value)
323
+
324
+ def _alert_deprecated_body_fields(self) -> None:
325
+ """Generates warning messages if deprecated fields were used in the body."""
326
+ deprecated_body_fields_with_replacement = [
327
+ ("initial_node_count", "node_pool.initial_node_count"),
328
+ ("node_config", "node_pool.config"),
329
+ ("zone", "location"),
330
+ ("instance_group_urls", "node_pools.instance_group_urls"),
331
+ ]
332
+ for deprecated_field, replacement in deprecated_body_fields_with_replacement:
333
+ if self._body_field(deprecated_field):
334
+ warnings.warn(
335
+ f"The body field '{deprecated_field}' is deprecated. Use '{replacement}' instead."
336
+ )
337
+
306
338
  def execute(self, context: Context) -> str:
307
339
  hook = self._get_hook()
308
340
  try:
@@ -397,11 +429,16 @@ class GKEStartPodOperator(KubernetesPodOperator):
397
429
  Service Account Token Creator IAM role to the directly preceding identity, with first
398
430
  account from the list granting this role to the originating account (templated).
399
431
  :param regional: The location param is region name.
432
+ :param deferrable: Run operator in the deferrable mode.
433
+ :param on_finish_action: What to do when the pod reaches its final state, or the execution is interrupted.
434
+ If "delete_pod", the pod will be deleted regardless it's state; if "delete_succeeded_pod",
435
+ only succeeded pod will be deleted. You can set to "keep_pod" to keep the pod.
436
+ Current default is `keep_pod`, but this will be changed in the next major release of this provider.
400
437
  :param is_delete_operator_pod: What to do when the pod reaches its final
401
438
  state, or the execution is interrupted. If True, delete the
402
439
  pod; if False, leave the pod. Current default is False, but this will be
403
440
  changed in the next major release of this provider.
404
- :param deferrable: Run operator in the deferrable mode.
441
+ Deprecated - use `on_finish_action` instead.
405
442
  """
406
443
 
407
444
  template_fields: Sequence[str] = tuple(
@@ -419,19 +456,32 @@ class GKEStartPodOperator(KubernetesPodOperator):
419
456
  gcp_conn_id: str = "google_cloud_default",
420
457
  impersonation_chain: str | Sequence[str] | None = None,
421
458
  regional: bool | None = None,
459
+ on_finish_action: str | None = None,
422
460
  is_delete_operator_pod: bool | None = None,
423
461
  **kwargs,
424
462
  ) -> None:
425
- if is_delete_operator_pod is None:
463
+ if is_delete_operator_pod is not None:
426
464
  warnings.warn(
427
- f"You have not set parameter `is_delete_operator_pod` in class {self.__class__.__name__}. "
428
- "Currently the default for this parameter is `False` but in a future release the default "
429
- "will be changed to `True`. To ensure pods are not deleted in the future you will need to "
430
- "set `is_delete_operator_pod=False` explicitly.",
465
+ "`is_delete_operator_pod` parameter is deprecated, please use `on_finish_action`",
431
466
  AirflowProviderDeprecationWarning,
432
467
  stacklevel=2,
433
468
  )
434
- is_delete_operator_pod = False
469
+ kwargs["on_finish_action"] = (
470
+ OnFinishAction.DELETE_POD if is_delete_operator_pod else OnFinishAction.KEEP_POD
471
+ )
472
+ else:
473
+ if on_finish_action is not None:
474
+ kwargs["on_finish_action"] = OnFinishAction(on_finish_action)
475
+ else:
476
+ warnings.warn(
477
+ f"You have not set parameter `on_finish_action` in class {self.__class__.__name__}. "
478
+ "Currently the default for this parameter is `keep_pod` but in a future release"
479
+ " the default will be changed to `delete_pod`. To ensure pods are not deleted in"
480
+ " the future you will need to set `on_finish_action=keep_pod` explicitly.",
481
+ AirflowProviderDeprecationWarning,
482
+ stacklevel=2,
483
+ )
484
+ kwargs["on_finish_action"] = OnFinishAction.KEEP_POD
435
485
 
436
486
  if regional is not None:
437
487
  warnings.warn(
@@ -442,7 +492,7 @@ class GKEStartPodOperator(KubernetesPodOperator):
442
492
  stacklevel=2,
443
493
  )
444
494
 
445
- super().__init__(is_delete_operator_pod=is_delete_operator_pod, **kwargs)
495
+ super().__init__(**kwargs)
446
496
  self.project_id = project_id
447
497
  self.location = location
448
498
  self.cluster_name = cluster_name
@@ -530,8 +580,8 @@ class GKEStartPodOperator(KubernetesPodOperator):
530
580
  cluster_context=self.cluster_context,
531
581
  poll_interval=self.poll_interval,
532
582
  in_cluster=self.in_cluster,
533
- should_delete_pod=self.is_delete_operator_pod,
534
583
  base_container_name=self.base_container_name,
584
+ on_finish_action=self.on_finish_action,
535
585
  ),
536
586
  method_name="execute_complete",
537
587
  kwargs={"cluster_url": self._cluster_url, "ssl_ca_cert": self._ssl_ca_cert},
@@ -27,6 +27,7 @@ from typing import TYPE_CHECKING, Any, Sequence
27
27
 
28
28
  from googleapiclient.errors import HttpError
29
29
 
30
+ from airflow.configuration import conf
30
31
  from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning
31
32
  from airflow.providers.google.cloud.hooks.mlengine import MLEngineHook
32
33
  from airflow.providers.google.cloud.links.mlengine import (
@@ -722,7 +723,6 @@ class MLEngineCreateVersionOperator(GoogleCloudBaseOperator):
722
723
  impersonation_chain: str | Sequence[str] | None = None,
723
724
  **kwargs,
724
725
  ) -> None:
725
-
726
726
  super().__init__(**kwargs)
727
727
  self._project_id = project_id
728
728
  self._model_name = model_name
@@ -804,7 +804,6 @@ class MLEngineSetDefaultVersionOperator(GoogleCloudBaseOperator):
804
804
  impersonation_chain: str | Sequence[str] | None = None,
805
805
  **kwargs,
806
806
  ) -> None:
807
-
808
807
  super().__init__(**kwargs)
809
808
  self._project_id = project_id
810
809
  self._model_name = model_name
@@ -883,7 +882,6 @@ class MLEngineListVersionsOperator(GoogleCloudBaseOperator):
883
882
  impersonation_chain: str | Sequence[str] | None = None,
884
883
  **kwargs,
885
884
  ) -> None:
886
-
887
885
  super().__init__(**kwargs)
888
886
  self._project_id = project_id
889
887
  self._model_name = model_name
@@ -961,7 +959,6 @@ class MLEngineDeleteVersionOperator(GoogleCloudBaseOperator):
961
959
  impersonation_chain: str | Sequence[str] | None = None,
962
960
  **kwargs,
963
961
  ) -> None:
964
-
965
962
  super().__init__(**kwargs)
966
963
  self._project_id = project_id
967
964
  self._model_name = model_name
@@ -1098,7 +1095,7 @@ class MLEngineStartTrainingJobOperator(GoogleCloudBaseOperator):
1098
1095
  labels: dict[str, str] | None = None,
1099
1096
  impersonation_chain: str | Sequence[str] | None = None,
1100
1097
  hyperparameters: dict | None = None,
1101
- deferrable: bool = False,
1098
+ deferrable: bool = conf.getboolean("operators", "default_deferrable", fallback=False),
1102
1099
  cancel_on_kill: bool = True,
1103
1100
  **kwargs,
1104
1101
  ) -> None:
@@ -1370,7 +1367,6 @@ class MLEngineTrainingCancelJobOperator(GoogleCloudBaseOperator):
1370
1367
  raise AirflowException("Google Cloud project id is required.")
1371
1368
 
1372
1369
  def execute(self, context: Context):
1373
-
1374
1370
  hook = MLEngineHook(
1375
1371
  gcp_conn_id=self._gcp_conn_id,
1376
1372
  impersonation_chain=self._impersonation_chain,
@@ -44,8 +44,7 @@ MetaData = Sequence[Tuple[str, str]]
44
44
 
45
45
 
46
46
  class CloudVisionCreateProductSetOperator(GoogleCloudBaseOperator):
47
- """
48
- Creates a new ProductSet resource.
47
+ """Create a new ProductSet resource.
49
48
 
50
49
  .. seealso::
51
50
  For more information on how to use this operator, take a look at the guide:
@@ -137,8 +136,7 @@ class CloudVisionCreateProductSetOperator(GoogleCloudBaseOperator):
137
136
 
138
137
 
139
138
  class CloudVisionGetProductSetOperator(GoogleCloudBaseOperator):
140
- """
141
- Gets information associated with a ProductSet.
139
+ """Get information associated with a ProductSet.
142
140
 
143
141
  .. seealso::
144
142
  For more information on how to use this operator, take a look at the guide:
@@ -215,19 +213,21 @@ class CloudVisionGetProductSetOperator(GoogleCloudBaseOperator):
215
213
 
216
214
 
217
215
  class CloudVisionUpdateProductSetOperator(GoogleCloudBaseOperator):
218
- """
219
- Makes changes to a `ProductSet` resource. Only display_name can be updated currently.
216
+ """Make changes to a `ProductSet` resource.
220
217
 
221
- .. note:: To locate the `ProductSet` resource, its `name` in the form
218
+ Only ``display_name`` can be updated currently.
219
+
220
+ .. note:: To locate the ``ProductSet`` resource, its ``name`` in the form
222
221
  `projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID` is necessary.
223
222
 
224
- You can provide the `name` directly as an attribute of the `product_set` object.
225
- However, you can leave it blank and provide `location` and `product_set_id` instead
226
- (and optionally `project_id` - if not present, the connection default will be used)
227
- and the `name` will be created by the operator itself.
223
+ You can provide the ``name` directly as an attribute of the ``product_set``
224
+ object. You can also leave it blank, in which case ``name`` will be created
225
+ by the operator from ``location`` and ``product_set_id`` instead (and
226
+ optionally ``project_id``; if not present, the connection default will be
227
+ used).
228
228
 
229
- This mechanism exists for your convenience, to allow leaving the `project_id` empty
230
- and having Airflow use the connection default `project_id`.
229
+ This mechanism exists for your convenience, to allow leaving the
230
+ ``project_id`` empty and having Airflow use the connection default.
231
231
 
232
232
  .. seealso::
233
233
  For more information on how to use this operator, take a look at the guide:
@@ -319,17 +319,17 @@ class CloudVisionUpdateProductSetOperator(GoogleCloudBaseOperator):
319
319
 
320
320
 
321
321
  class CloudVisionDeleteProductSetOperator(GoogleCloudBaseOperator):
322
- """
323
- Permanently deletes a `ProductSet`. `Products` and `ReferenceImages` in the
324
- `ProductSet` are not deleted. The actual image files are not deleted from Google
325
- Cloud Storage.
322
+ """Permanently deletes a ``ProductSet``.
323
+
324
+ ``Products`` and ``ReferenceImages`` in the ``ProductSet`` are not deleted.
325
+ The actual image files are not deleted from Google Cloud Storage.
326
326
 
327
327
  .. seealso::
328
328
  For more information on how to use this operator, take a look at the guide:
329
329
  :ref:`howto/operator:CloudVisionDeleteProductSetOperator`
330
330
 
331
- :param location: (Required) The region where the ProductSet is located. Valid regions (as of 2019-02-05)
332
- are: us-east1, us-west1, europe-west1, asia-east1
331
+ :param location: (Required) The region where the ProductSet is located.
332
+ Valid regions (as of 2019-02-05) are: us-east1, us-west1, europe-west1, asia-east1
333
333
  :param product_set_id: (Required) The resource id of this ProductSet.
334
334
  :param project_id: (Optional) The project in which the ProductSet should be created.
335
335
  If set to None or missing, the default project_id from the Google Cloud connection is used.
@@ -399,14 +399,13 @@ class CloudVisionDeleteProductSetOperator(GoogleCloudBaseOperator):
399
399
 
400
400
 
401
401
  class CloudVisionCreateProductOperator(GoogleCloudBaseOperator):
402
- """
403
- Creates and returns a new product resource.
402
+ """Create and return a new product resource.
404
403
 
405
- Possible errors regarding the `Product` object provided:
404
+ Possible errors regarding the ``Product`` object provided:
406
405
 
407
- - Returns `INVALID_ARGUMENT` if `display_name` is missing or longer than 4096 characters.
408
- - Returns `INVALID_ARGUMENT` if `description` is longer than 4096 characters.
409
- - Returns `INVALID_ARGUMENT` if `product_category` is missing or invalid.
406
+ - Returns ``INVALID_ARGUMENT`` if ``display_name`` is missing or longer than 4096 characters.
407
+ - Returns ``INVALID_ARGUMENT`` if ``description`` is longer than 4096 characters.
408
+ - Returns ``INVALID_ARGUMENT`` if ``product_category`` is missing or invalid.
410
409
 
411
410
  .. seealso::
412
411
  For more information on how to use this operator, take a look at the guide:
@@ -497,8 +496,7 @@ class CloudVisionCreateProductOperator(GoogleCloudBaseOperator):
497
496
 
498
497
 
499
498
  class CloudVisionGetProductOperator(GoogleCloudBaseOperator):
500
- """
501
- Gets information associated with a `Product`.
499
+ """Get information associated with a ``Product``.
502
500
 
503
501
  Possible errors:
504
502
 
@@ -579,9 +577,9 @@ class CloudVisionGetProductOperator(GoogleCloudBaseOperator):
579
577
 
580
578
 
581
579
  class CloudVisionUpdateProductOperator(GoogleCloudBaseOperator):
582
- """
583
- Makes changes to a Product resource. Only the display_name, description, and labels fields can be
584
- updated right now.
580
+ """Make changes to a Product resource.
581
+
582
+ Only the display_name, description, and labels fields can be updated right now.
585
583
 
586
584
  If labels are updated, the change will not be reflected in queries until the next index time.
587
585
 
@@ -692,11 +690,11 @@ class CloudVisionUpdateProductOperator(GoogleCloudBaseOperator):
692
690
 
693
691
 
694
692
  class CloudVisionDeleteProductOperator(GoogleCloudBaseOperator):
695
- """
696
- Permanently deletes a product and its reference images.
693
+ """Permanently delete a product and its reference images.
697
694
 
698
- Metadata of the product and all its images will be deleted right away, but search queries against
699
- ProductSets containing the product may still work until all related caches are refreshed.
695
+ Metadata of the product and all its images will be deleted right away, but
696
+ search queries against ProductSets containing the product may still work
697
+ until all related caches are refreshed.
700
698
 
701
699
  Possible errors:
702
700
 
@@ -777,8 +775,7 @@ class CloudVisionDeleteProductOperator(GoogleCloudBaseOperator):
777
775
 
778
776
 
779
777
  class CloudVisionImageAnnotateOperator(GoogleCloudBaseOperator):
780
- """
781
- Run image detection and annotation for an image or a batch of images.
778
+ """Run image detection and annotation for an image or a batch of images.
782
779
 
783
780
  .. seealso::
784
781
  For more information on how to use this operator, take a look at the guide:
@@ -845,8 +842,7 @@ class CloudVisionImageAnnotateOperator(GoogleCloudBaseOperator):
845
842
 
846
843
 
847
844
  class CloudVisionCreateReferenceImageOperator(GoogleCloudBaseOperator):
848
- """
849
- Creates and returns a new ReferenceImage ID resource.
845
+ """Create and return a new ReferenceImage ID resource.
850
846
 
851
847
  .. seealso::
852
848
  For more information on how to use this operator, take a look at the guide:
@@ -949,8 +945,7 @@ class CloudVisionCreateReferenceImageOperator(GoogleCloudBaseOperator):
949
945
 
950
946
 
951
947
  class CloudVisionDeleteReferenceImageOperator(GoogleCloudBaseOperator):
952
- """
953
- Deletes a ReferenceImage ID resource.
948
+ """Delete a ReferenceImage ID resource.
954
949
 
955
950
  .. seealso::
956
951
  For more information on how to use this operator, take a look at the guide:
@@ -1035,10 +1030,10 @@ class CloudVisionDeleteReferenceImageOperator(GoogleCloudBaseOperator):
1035
1030
 
1036
1031
 
1037
1032
  class CloudVisionAddProductToProductSetOperator(GoogleCloudBaseOperator):
1038
- """
1039
- Adds a Product to the specified ProductSet. If the Product is already present, no change is made.
1033
+ """Add a Product to the specified ProductSet.
1040
1034
 
1041
- One Product can be added to at most 100 ProductSets.
1035
+ If the Product is already present, no change is made. One Product can be
1036
+ added to at most 100 ProductSets.
1042
1037
 
1043
1038
  Possible errors:
1044
1039
 
@@ -1124,8 +1119,7 @@ class CloudVisionAddProductToProductSetOperator(GoogleCloudBaseOperator):
1124
1119
 
1125
1120
 
1126
1121
  class CloudVisionRemoveProductFromProductSetOperator(GoogleCloudBaseOperator):
1127
- """
1128
- Removes a Product from the specified ProductSet.
1122
+ """Remove a Product from the specified ProductSet.
1129
1123
 
1130
1124
  .. seealso::
1131
1125
  For more information on how to use this operator, take a look at the guide:
@@ -1207,8 +1201,7 @@ class CloudVisionRemoveProductFromProductSetOperator(GoogleCloudBaseOperator):
1207
1201
 
1208
1202
 
1209
1203
  class CloudVisionDetectTextOperator(GoogleCloudBaseOperator):
1210
- """
1211
- Detects Text in the image.
1204
+ """Detect Text in the image.
1212
1205
 
1213
1206
  .. seealso::
1214
1207
  For more information on how to use this operator, take a look at the guide:
@@ -1289,8 +1282,7 @@ class CloudVisionDetectTextOperator(GoogleCloudBaseOperator):
1289
1282
 
1290
1283
 
1291
1284
  class CloudVisionTextDetectOperator(GoogleCloudBaseOperator):
1292
- """
1293
- Detects Document Text in the image.
1285
+ """Detect Document Text in the image.
1294
1286
 
1295
1287
  .. seealso::
1296
1288
  For more information on how to use this operator, take a look at the guide:
@@ -1370,8 +1362,7 @@ class CloudVisionTextDetectOperator(GoogleCloudBaseOperator):
1370
1362
 
1371
1363
 
1372
1364
  class CloudVisionDetectImageLabelsOperator(GoogleCloudBaseOperator):
1373
- """
1374
- Detects Document Text in the image.
1365
+ """Detect Document Text in the image.
1375
1366
 
1376
1367
  .. seealso::
1377
1368
  For more information on how to use this operator, take a look at the guide:
@@ -1441,8 +1432,7 @@ class CloudVisionDetectImageLabelsOperator(GoogleCloudBaseOperator):
1441
1432
 
1442
1433
 
1443
1434
  class CloudVisionDetectImageSafeSearchOperator(GoogleCloudBaseOperator):
1444
- """
1445
- Detects Document Text in the image.
1435
+ """Detect Document Text in the image.
1446
1436
 
1447
1437
  .. seealso::
1448
1438
  For more information on how to use this operator, take a look at the guide:
@@ -1514,9 +1504,10 @@ class CloudVisionDetectImageSafeSearchOperator(GoogleCloudBaseOperator):
1514
1504
  def prepare_additional_parameters(
1515
1505
  additional_properties: dict | None, language_hints: Any, web_detection_params: Any
1516
1506
  ) -> dict | None:
1517
- """
1518
- Creates additional_properties parameter based on language_hints, web_detection_params and
1519
- additional_properties parameters specified by the user.
1507
+ """Create a value for the ``additional_properties`` parameter.
1508
+
1509
+ The new value is based on ``language_hints``, ``web_detection_params``, and
1510
+ ``additional_properties`` parameters specified by the user.
1520
1511
  """
1521
1512
  if language_hints is None and web_detection_params is None:
1522
1513
  return additional_properties
@@ -22,6 +22,7 @@ import warnings
22
22
  from datetime import timedelta
23
23
  from typing import TYPE_CHECKING, Any, Sequence
24
24
 
25
+ from airflow.configuration import conf
25
26
  from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning
26
27
  from airflow.providers.google.cloud.hooks.bigquery import BigQueryHook
27
28
  from airflow.providers.google.cloud.triggers.bigquery import (
@@ -71,7 +72,7 @@ class BigQueryTableExistenceSensor(BaseSensorOperator):
71
72
  table_id: str,
72
73
  gcp_conn_id: str = "google_cloud_default",
73
74
  impersonation_chain: str | Sequence[str] | None = None,
74
- deferrable: bool = False,
75
+ deferrable: bool = conf.getboolean("operators", "default_deferrable", fallback=False),
75
76
  **kwargs,
76
77
  ) -> None:
77
78
  if deferrable and "poke_interval" not in kwargs:
@@ -184,7 +185,7 @@ class BigQueryTablePartitionExistenceSensor(BaseSensorOperator):
184
185
  partition_id: str,
185
186
  gcp_conn_id: str = "google_cloud_default",
186
187
  impersonation_chain: str | Sequence[str] | None = None,
187
- deferrable: bool = False,
188
+ deferrable: bool = conf.getboolean("operators", "default_deferrable", fallback=False),
188
189
  **kwargs,
189
190
  ) -> None:
190
191
  if deferrable and "poke_interval" not in kwargs: