apache-airflow-providers-google 14.0.0__py3-none-any.whl → 19.1.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.
- airflow/providers/google/3rd-party-licenses/LICENSES.txt +14 -0
- airflow/providers/google/3rd-party-licenses/NOTICE +5 -0
- airflow/providers/google/__init__.py +3 -3
- airflow/providers/google/_vendor/__init__.py +0 -0
- airflow/providers/google/_vendor/json_merge_patch.py +91 -0
- airflow/providers/google/ads/hooks/ads.py +52 -43
- airflow/providers/google/ads/operators/ads.py +2 -2
- airflow/providers/google/ads/transfers/ads_to_gcs.py +3 -19
- airflow/providers/google/assets/gcs.py +1 -11
- airflow/providers/google/cloud/_internal_client/secret_manager_client.py +3 -2
- airflow/providers/google/cloud/bundles/gcs.py +161 -0
- airflow/providers/google/cloud/hooks/alloy_db.py +2 -3
- airflow/providers/google/cloud/hooks/bigquery.py +195 -318
- airflow/providers/google/cloud/hooks/bigquery_dts.py +8 -8
- airflow/providers/google/cloud/hooks/bigtable.py +3 -2
- airflow/providers/google/cloud/hooks/cloud_batch.py +8 -9
- airflow/providers/google/cloud/hooks/cloud_build.py +6 -65
- airflow/providers/google/cloud/hooks/cloud_composer.py +292 -24
- airflow/providers/google/cloud/hooks/cloud_logging.py +109 -0
- airflow/providers/google/cloud/hooks/cloud_memorystore.py +4 -3
- airflow/providers/google/cloud/hooks/cloud_run.py +20 -11
- airflow/providers/google/cloud/hooks/cloud_sql.py +136 -64
- airflow/providers/google/cloud/hooks/cloud_storage_transfer_service.py +35 -15
- airflow/providers/google/cloud/hooks/compute.py +7 -6
- airflow/providers/google/cloud/hooks/compute_ssh.py +7 -4
- airflow/providers/google/cloud/hooks/datacatalog.py +12 -3
- airflow/providers/google/cloud/hooks/dataflow.py +87 -242
- airflow/providers/google/cloud/hooks/dataform.py +9 -14
- airflow/providers/google/cloud/hooks/datafusion.py +7 -9
- airflow/providers/google/cloud/hooks/dataplex.py +13 -12
- airflow/providers/google/cloud/hooks/dataprep.py +2 -2
- airflow/providers/google/cloud/hooks/dataproc.py +76 -74
- airflow/providers/google/cloud/hooks/dataproc_metastore.py +4 -3
- airflow/providers/google/cloud/hooks/dlp.py +5 -4
- airflow/providers/google/cloud/hooks/gcs.py +144 -33
- airflow/providers/google/cloud/hooks/gen_ai.py +196 -0
- airflow/providers/google/cloud/hooks/kms.py +3 -2
- airflow/providers/google/cloud/hooks/kubernetes_engine.py +22 -17
- airflow/providers/google/cloud/hooks/looker.py +6 -1
- airflow/providers/google/cloud/hooks/managed_kafka.py +227 -3
- airflow/providers/google/cloud/hooks/mlengine.py +7 -8
- airflow/providers/google/cloud/hooks/natural_language.py +3 -2
- airflow/providers/google/cloud/hooks/os_login.py +3 -2
- airflow/providers/google/cloud/hooks/pubsub.py +6 -6
- airflow/providers/google/cloud/hooks/secret_manager.py +105 -12
- airflow/providers/google/cloud/hooks/spanner.py +75 -10
- airflow/providers/google/cloud/hooks/speech_to_text.py +3 -2
- airflow/providers/google/cloud/hooks/stackdriver.py +18 -18
- airflow/providers/google/cloud/hooks/tasks.py +4 -3
- airflow/providers/google/cloud/hooks/text_to_speech.py +3 -2
- airflow/providers/google/cloud/hooks/translate.py +8 -17
- airflow/providers/google/cloud/hooks/vertex_ai/auto_ml.py +8 -222
- airflow/providers/google/cloud/hooks/vertex_ai/batch_prediction_job.py +9 -15
- airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py +33 -283
- airflow/providers/google/cloud/hooks/vertex_ai/dataset.py +5 -12
- airflow/providers/google/cloud/hooks/vertex_ai/endpoint_service.py +6 -12
- airflow/providers/google/cloud/hooks/vertex_ai/experiment_service.py +202 -0
- airflow/providers/google/cloud/hooks/vertex_ai/feature_store.py +311 -10
- airflow/providers/google/cloud/hooks/vertex_ai/generative_model.py +79 -75
- airflow/providers/google/cloud/hooks/vertex_ai/hyperparameter_tuning_job.py +7 -13
- airflow/providers/google/cloud/hooks/vertex_ai/model_service.py +8 -12
- airflow/providers/google/cloud/hooks/vertex_ai/pipeline_job.py +6 -12
- airflow/providers/google/cloud/hooks/vertex_ai/prediction_service.py +3 -2
- airflow/providers/google/cloud/hooks/vertex_ai/ray.py +223 -0
- airflow/providers/google/cloud/hooks/video_intelligence.py +3 -2
- airflow/providers/google/cloud/hooks/vision.py +7 -7
- airflow/providers/google/cloud/hooks/workflows.py +4 -3
- airflow/providers/google/cloud/links/alloy_db.py +0 -46
- airflow/providers/google/cloud/links/base.py +77 -7
- airflow/providers/google/cloud/links/bigquery.py +0 -47
- airflow/providers/google/cloud/links/bigquery_dts.py +0 -20
- airflow/providers/google/cloud/links/bigtable.py +0 -48
- airflow/providers/google/cloud/links/cloud_build.py +0 -73
- airflow/providers/google/cloud/links/cloud_functions.py +0 -33
- airflow/providers/google/cloud/links/cloud_memorystore.py +0 -58
- airflow/providers/google/cloud/links/{life_sciences.py → cloud_run.py} +5 -27
- airflow/providers/google/cloud/links/cloud_sql.py +0 -33
- airflow/providers/google/cloud/links/cloud_storage_transfer.py +17 -46
- airflow/providers/google/cloud/links/cloud_tasks.py +7 -26
- airflow/providers/google/cloud/links/compute.py +0 -58
- airflow/providers/google/cloud/links/data_loss_prevention.py +0 -169
- airflow/providers/google/cloud/links/datacatalog.py +23 -54
- airflow/providers/google/cloud/links/dataflow.py +0 -34
- airflow/providers/google/cloud/links/dataform.py +0 -64
- airflow/providers/google/cloud/links/datafusion.py +1 -90
- airflow/providers/google/cloud/links/dataplex.py +0 -154
- airflow/providers/google/cloud/links/dataprep.py +0 -24
- airflow/providers/google/cloud/links/dataproc.py +11 -89
- airflow/providers/google/cloud/links/datastore.py +0 -31
- airflow/providers/google/cloud/links/kubernetes_engine.py +11 -61
- airflow/providers/google/cloud/links/managed_kafka.py +11 -51
- airflow/providers/google/cloud/links/mlengine.py +0 -70
- airflow/providers/google/cloud/links/pubsub.py +0 -32
- airflow/providers/google/cloud/links/spanner.py +0 -33
- airflow/providers/google/cloud/links/stackdriver.py +0 -30
- airflow/providers/google/cloud/links/translate.py +17 -187
- airflow/providers/google/cloud/links/vertex_ai.py +28 -195
- airflow/providers/google/cloud/links/workflows.py +0 -52
- airflow/providers/google/cloud/log/gcs_task_handler.py +166 -118
- airflow/providers/google/cloud/log/stackdriver_task_handler.py +14 -9
- airflow/providers/google/cloud/openlineage/CloudStorageTransferJobFacet.json +68 -0
- airflow/providers/google/cloud/openlineage/CloudStorageTransferRunFacet.json +60 -0
- airflow/providers/google/cloud/openlineage/DataFusionRunFacet.json +32 -0
- airflow/providers/google/cloud/openlineage/facets.py +141 -40
- airflow/providers/google/cloud/openlineage/mixins.py +14 -13
- airflow/providers/google/cloud/openlineage/utils.py +19 -3
- airflow/providers/google/cloud/operators/alloy_db.py +76 -61
- airflow/providers/google/cloud/operators/bigquery.py +104 -667
- airflow/providers/google/cloud/operators/bigquery_dts.py +12 -12
- airflow/providers/google/cloud/operators/bigtable.py +38 -7
- airflow/providers/google/cloud/operators/cloud_base.py +22 -1
- airflow/providers/google/cloud/operators/cloud_batch.py +18 -18
- airflow/providers/google/cloud/operators/cloud_build.py +80 -36
- airflow/providers/google/cloud/operators/cloud_composer.py +157 -71
- airflow/providers/google/cloud/operators/cloud_logging_sink.py +341 -0
- airflow/providers/google/cloud/operators/cloud_memorystore.py +74 -46
- airflow/providers/google/cloud/operators/cloud_run.py +39 -20
- airflow/providers/google/cloud/operators/cloud_sql.py +46 -61
- airflow/providers/google/cloud/operators/cloud_storage_transfer_service.py +92 -14
- airflow/providers/google/cloud/operators/compute.py +18 -50
- airflow/providers/google/cloud/operators/datacatalog.py +167 -29
- airflow/providers/google/cloud/operators/dataflow.py +38 -15
- airflow/providers/google/cloud/operators/dataform.py +19 -7
- airflow/providers/google/cloud/operators/datafusion.py +43 -43
- airflow/providers/google/cloud/operators/dataplex.py +212 -126
- airflow/providers/google/cloud/operators/dataprep.py +1 -5
- airflow/providers/google/cloud/operators/dataproc.py +134 -207
- airflow/providers/google/cloud/operators/dataproc_metastore.py +102 -84
- airflow/providers/google/cloud/operators/datastore.py +22 -6
- airflow/providers/google/cloud/operators/dlp.py +24 -45
- airflow/providers/google/cloud/operators/functions.py +21 -14
- airflow/providers/google/cloud/operators/gcs.py +15 -12
- airflow/providers/google/cloud/operators/gen_ai.py +389 -0
- airflow/providers/google/cloud/operators/kubernetes_engine.py +115 -106
- airflow/providers/google/cloud/operators/looker.py +1 -1
- airflow/providers/google/cloud/operators/managed_kafka.py +362 -40
- airflow/providers/google/cloud/operators/natural_language.py +5 -3
- airflow/providers/google/cloud/operators/pubsub.py +69 -21
- airflow/providers/google/cloud/operators/spanner.py +53 -45
- airflow/providers/google/cloud/operators/speech_to_text.py +5 -4
- airflow/providers/google/cloud/operators/stackdriver.py +5 -11
- airflow/providers/google/cloud/operators/tasks.py +6 -15
- airflow/providers/google/cloud/operators/text_to_speech.py +4 -3
- airflow/providers/google/cloud/operators/translate.py +46 -20
- airflow/providers/google/cloud/operators/translate_speech.py +4 -3
- airflow/providers/google/cloud/operators/vertex_ai/auto_ml.py +44 -34
- airflow/providers/google/cloud/operators/vertex_ai/batch_prediction_job.py +34 -12
- airflow/providers/google/cloud/operators/vertex_ai/custom_job.py +62 -53
- airflow/providers/google/cloud/operators/vertex_ai/dataset.py +75 -11
- airflow/providers/google/cloud/operators/vertex_ai/endpoint_service.py +48 -12
- airflow/providers/google/cloud/operators/vertex_ai/experiment_service.py +435 -0
- airflow/providers/google/cloud/operators/vertex_ai/feature_store.py +532 -1
- airflow/providers/google/cloud/operators/vertex_ai/generative_model.py +135 -116
- airflow/providers/google/cloud/operators/vertex_ai/hyperparameter_tuning_job.py +16 -12
- airflow/providers/google/cloud/operators/vertex_ai/model_service.py +62 -14
- airflow/providers/google/cloud/operators/vertex_ai/pipeline_job.py +35 -10
- airflow/providers/google/cloud/operators/vertex_ai/ray.py +393 -0
- airflow/providers/google/cloud/operators/video_intelligence.py +5 -3
- airflow/providers/google/cloud/operators/vision.py +7 -5
- airflow/providers/google/cloud/operators/workflows.py +24 -19
- airflow/providers/google/cloud/secrets/secret_manager.py +2 -1
- airflow/providers/google/cloud/sensors/bigquery.py +2 -2
- airflow/providers/google/cloud/sensors/bigquery_dts.py +6 -4
- airflow/providers/google/cloud/sensors/bigtable.py +14 -6
- airflow/providers/google/cloud/sensors/cloud_composer.py +535 -33
- airflow/providers/google/cloud/sensors/cloud_storage_transfer_service.py +6 -5
- airflow/providers/google/cloud/sensors/dataflow.py +27 -10
- airflow/providers/google/cloud/sensors/dataform.py +2 -2
- airflow/providers/google/cloud/sensors/datafusion.py +4 -4
- airflow/providers/google/cloud/sensors/dataplex.py +7 -5
- airflow/providers/google/cloud/sensors/dataprep.py +2 -2
- airflow/providers/google/cloud/sensors/dataproc.py +10 -9
- airflow/providers/google/cloud/sensors/dataproc_metastore.py +4 -3
- airflow/providers/google/cloud/sensors/gcs.py +22 -21
- airflow/providers/google/cloud/sensors/looker.py +5 -5
- airflow/providers/google/cloud/sensors/pubsub.py +20 -20
- airflow/providers/google/cloud/sensors/tasks.py +2 -2
- airflow/providers/google/cloud/sensors/vertex_ai/feature_store.py +2 -2
- airflow/providers/google/cloud/sensors/workflows.py +6 -4
- airflow/providers/google/cloud/transfers/adls_to_gcs.py +1 -1
- airflow/providers/google/cloud/transfers/azure_blob_to_gcs.py +2 -2
- airflow/providers/google/cloud/transfers/azure_fileshare_to_gcs.py +2 -2
- airflow/providers/google/cloud/transfers/bigquery_to_bigquery.py +11 -8
- airflow/providers/google/cloud/transfers/bigquery_to_gcs.py +14 -13
- airflow/providers/google/cloud/transfers/bigquery_to_mssql.py +7 -3
- airflow/providers/google/cloud/transfers/bigquery_to_mysql.py +12 -1
- airflow/providers/google/cloud/transfers/bigquery_to_postgres.py +24 -10
- airflow/providers/google/cloud/transfers/bigquery_to_sql.py +104 -5
- airflow/providers/google/cloud/transfers/calendar_to_gcs.py +1 -1
- airflow/providers/google/cloud/transfers/cassandra_to_gcs.py +18 -22
- airflow/providers/google/cloud/transfers/facebook_ads_to_gcs.py +4 -5
- airflow/providers/google/cloud/transfers/gcs_to_bigquery.py +45 -38
- airflow/providers/google/cloud/transfers/gcs_to_gcs.py +2 -2
- airflow/providers/google/cloud/transfers/gcs_to_local.py +5 -3
- airflow/providers/google/cloud/transfers/gcs_to_sftp.py +10 -4
- airflow/providers/google/cloud/transfers/gdrive_to_gcs.py +6 -2
- airflow/providers/google/cloud/transfers/gdrive_to_local.py +2 -2
- airflow/providers/google/cloud/transfers/http_to_gcs.py +193 -0
- airflow/providers/google/cloud/transfers/local_to_gcs.py +2 -2
- airflow/providers/google/cloud/transfers/mssql_to_gcs.py +1 -1
- airflow/providers/google/cloud/transfers/oracle_to_gcs.py +36 -11
- airflow/providers/google/cloud/transfers/postgres_to_gcs.py +44 -12
- airflow/providers/google/cloud/transfers/s3_to_gcs.py +12 -6
- airflow/providers/google/cloud/transfers/salesforce_to_gcs.py +2 -2
- airflow/providers/google/cloud/transfers/sftp_to_gcs.py +36 -14
- airflow/providers/google/cloud/transfers/sheets_to_gcs.py +3 -3
- airflow/providers/google/cloud/transfers/sql_to_gcs.py +10 -10
- airflow/providers/google/cloud/triggers/bigquery.py +75 -34
- airflow/providers/google/cloud/triggers/bigquery_dts.py +2 -1
- airflow/providers/google/cloud/triggers/cloud_batch.py +2 -1
- airflow/providers/google/cloud/triggers/cloud_build.py +3 -2
- airflow/providers/google/cloud/triggers/cloud_composer.py +303 -47
- airflow/providers/google/cloud/triggers/cloud_run.py +2 -2
- airflow/providers/google/cloud/triggers/cloud_storage_transfer_service.py +96 -5
- airflow/providers/google/cloud/triggers/dataflow.py +125 -2
- airflow/providers/google/cloud/triggers/datafusion.py +1 -1
- airflow/providers/google/cloud/triggers/dataplex.py +16 -3
- airflow/providers/google/cloud/triggers/dataproc.py +124 -53
- airflow/providers/google/cloud/triggers/kubernetes_engine.py +46 -28
- airflow/providers/google/cloud/triggers/mlengine.py +1 -1
- airflow/providers/google/cloud/triggers/pubsub.py +17 -20
- airflow/providers/google/cloud/triggers/vertex_ai.py +8 -7
- airflow/providers/google/cloud/utils/bigquery.py +5 -7
- airflow/providers/google/cloud/utils/bigquery_get_data.py +1 -1
- airflow/providers/google/cloud/utils/credentials_provider.py +4 -3
- airflow/providers/google/cloud/utils/dataform.py +1 -1
- airflow/providers/google/cloud/utils/external_token_supplier.py +0 -1
- airflow/providers/google/cloud/utils/field_validator.py +1 -2
- airflow/providers/google/cloud/utils/validators.py +43 -0
- airflow/providers/google/common/auth_backend/google_openid.py +26 -9
- airflow/providers/google/common/consts.py +2 -1
- airflow/providers/google/common/deprecated.py +2 -1
- airflow/providers/google/common/hooks/base_google.py +40 -43
- airflow/providers/google/common/hooks/operation_helpers.py +78 -0
- airflow/providers/google/common/links/storage.py +0 -22
- airflow/providers/google/common/utils/get_secret.py +31 -0
- airflow/providers/google/common/utils/id_token_credentials.py +4 -5
- airflow/providers/google/firebase/operators/firestore.py +2 -2
- airflow/providers/google/get_provider_info.py +61 -216
- airflow/providers/google/go_module_utils.py +35 -3
- airflow/providers/google/leveldb/hooks/leveldb.py +30 -6
- airflow/providers/google/leveldb/operators/leveldb.py +2 -2
- airflow/providers/google/marketing_platform/hooks/analytics_admin.py +3 -2
- airflow/providers/google/marketing_platform/hooks/display_video.py +3 -109
- airflow/providers/google/marketing_platform/hooks/search_ads.py +1 -1
- airflow/providers/google/marketing_platform/links/analytics_admin.py +4 -5
- airflow/providers/google/marketing_platform/operators/analytics_admin.py +7 -6
- airflow/providers/google/marketing_platform/operators/campaign_manager.py +5 -5
- airflow/providers/google/marketing_platform/operators/display_video.py +28 -489
- airflow/providers/google/marketing_platform/operators/search_ads.py +2 -2
- airflow/providers/google/marketing_platform/sensors/campaign_manager.py +2 -2
- airflow/providers/google/marketing_platform/sensors/display_video.py +4 -64
- airflow/providers/google/suite/hooks/calendar.py +1 -1
- airflow/providers/google/suite/hooks/drive.py +2 -2
- airflow/providers/google/suite/hooks/sheets.py +15 -1
- airflow/providers/google/suite/operators/sheets.py +8 -3
- airflow/providers/google/suite/sensors/drive.py +2 -2
- airflow/providers/google/suite/transfers/gcs_to_gdrive.py +2 -2
- airflow/providers/google/suite/transfers/gcs_to_sheets.py +1 -1
- airflow/providers/google/suite/transfers/local_to_drive.py +3 -3
- airflow/providers/google/suite/transfers/sql_to_sheets.py +5 -4
- airflow/providers/google/version_compat.py +15 -1
- {apache_airflow_providers_google-14.0.0.dist-info → apache_airflow_providers_google-19.1.0rc1.dist-info}/METADATA +117 -72
- apache_airflow_providers_google-19.1.0rc1.dist-info/RECORD +331 -0
- {apache_airflow_providers_google-14.0.0.dist-info → apache_airflow_providers_google-19.1.0rc1.dist-info}/WHEEL +1 -1
- apache_airflow_providers_google-19.1.0rc1.dist-info/licenses/NOTICE +5 -0
- airflow/providers/google/cloud/example_dags/example_cloud_task.py +0 -54
- airflow/providers/google/cloud/hooks/automl.py +0 -679
- airflow/providers/google/cloud/hooks/life_sciences.py +0 -159
- airflow/providers/google/cloud/links/automl.py +0 -193
- airflow/providers/google/cloud/operators/automl.py +0 -1360
- airflow/providers/google/cloud/operators/life_sciences.py +0 -119
- airflow/providers/google/cloud/operators/mlengine.py +0 -1515
- airflow/providers/google/cloud/utils/mlengine_operator_utils.py +0 -273
- apache_airflow_providers_google-14.0.0.dist-info/RECORD +0 -318
- /airflow/providers/google/cloud/{example_dags → bundles}/__init__.py +0 -0
- {apache_airflow_providers_google-14.0.0.dist-info → apache_airflow_providers_google-19.1.0rc1.dist-info}/entry_points.txt +0 -0
- {airflow/providers/google → apache_airflow_providers_google-19.1.0rc1.dist-info/licenses}/LICENSE +0 -0
|
@@ -23,12 +23,6 @@ from collections.abc import Sequence
|
|
|
23
23
|
from copy import copy
|
|
24
24
|
from typing import TYPE_CHECKING
|
|
25
25
|
|
|
26
|
-
from airflow.providers.google.common.consts import CLIENT_INFO
|
|
27
|
-
from airflow.providers.google.common.hooks.base_google import (
|
|
28
|
-
PROVIDE_PROJECT_ID,
|
|
29
|
-
GoogleBaseAsyncHook,
|
|
30
|
-
GoogleBaseHook,
|
|
31
|
-
)
|
|
32
26
|
from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault
|
|
33
27
|
from google.cloud.bigquery_datatransfer_v1 import DataTransferServiceAsyncClient, DataTransferServiceClient
|
|
34
28
|
from google.cloud.bigquery_datatransfer_v1.types import (
|
|
@@ -37,11 +31,17 @@ from google.cloud.bigquery_datatransfer_v1.types import (
|
|
|
37
31
|
TransferRun,
|
|
38
32
|
)
|
|
39
33
|
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
from airflow.providers.google.common.consts import CLIENT_INFO
|
|
35
|
+
from airflow.providers.google.common.hooks.base_google import (
|
|
36
|
+
PROVIDE_PROJECT_ID,
|
|
37
|
+
GoogleBaseAsyncHook,
|
|
38
|
+
GoogleBaseHook,
|
|
39
|
+
)
|
|
42
40
|
|
|
41
|
+
if TYPE_CHECKING:
|
|
43
42
|
from google.api_core.retry import Retry
|
|
44
43
|
from google.api_core.retry_async import AsyncRetry
|
|
44
|
+
from googleapiclient.discovery import Resource
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
def get_object_id(obj: dict) -> str:
|
|
@@ -22,13 +22,14 @@ from __future__ import annotations
|
|
|
22
22
|
from collections.abc import Sequence
|
|
23
23
|
from typing import TYPE_CHECKING
|
|
24
24
|
|
|
25
|
-
from airflow.providers.google.common.consts import CLIENT_INFO
|
|
26
|
-
from airflow.providers.google.common.hooks.base_google import GoogleBaseHook
|
|
27
25
|
from google.cloud.bigtable import Client, enums
|
|
28
26
|
from google.cloud.bigtable.cluster import Cluster
|
|
29
27
|
from google.cloud.bigtable.instance import Instance
|
|
30
28
|
from google.cloud.bigtable.table import ClusterState, Table
|
|
31
29
|
|
|
30
|
+
from airflow.providers.google.common.consts import CLIENT_INFO
|
|
31
|
+
from airflow.providers.google.common.hooks.base_google import GoogleBaseHook
|
|
32
|
+
|
|
32
33
|
if TYPE_CHECKING:
|
|
33
34
|
import enum
|
|
34
35
|
|
|
@@ -23,9 +23,6 @@ import time
|
|
|
23
23
|
from collections.abc import Iterable, Sequence
|
|
24
24
|
from typing import TYPE_CHECKING
|
|
25
25
|
|
|
26
|
-
from airflow.exceptions import AirflowException
|
|
27
|
-
from airflow.providers.google.common.consts import CLIENT_INFO
|
|
28
|
-
from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook
|
|
29
26
|
from google.cloud.batch import ListJobsRequest, ListTasksRequest
|
|
30
27
|
from google.cloud.batch_v1 import (
|
|
31
28
|
BatchServiceAsyncClient,
|
|
@@ -36,6 +33,10 @@ from google.cloud.batch_v1 import (
|
|
|
36
33
|
Task,
|
|
37
34
|
)
|
|
38
35
|
|
|
36
|
+
from airflow.exceptions import AirflowException
|
|
37
|
+
from airflow.providers.google.common.consts import CLIENT_INFO
|
|
38
|
+
from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook
|
|
39
|
+
|
|
39
40
|
if TYPE_CHECKING:
|
|
40
41
|
from google.api_core import operation
|
|
41
42
|
from google.cloud.batch_v1.services.batch_service import pagers
|
|
@@ -146,20 +147,18 @@ class CloudBatchHook(GoogleBaseHook):
|
|
|
146
147
|
status: JobStatus.State = job.status.state
|
|
147
148
|
if status == JobStatus.State.SUCCEEDED:
|
|
148
149
|
return job
|
|
149
|
-
|
|
150
|
+
if status == JobStatus.State.FAILED:
|
|
150
151
|
message = (
|
|
151
152
|
"Unexpected error in the operation: "
|
|
152
153
|
"Batch job with name {job_name} has failed its execution."
|
|
153
154
|
)
|
|
154
155
|
raise AirflowException(message)
|
|
155
|
-
|
|
156
|
+
if status == JobStatus.State.DELETION_IN_PROGRESS:
|
|
156
157
|
message = (
|
|
157
|
-
"Unexpected error in the operation: "
|
|
158
|
-
"Batch job with name {job_name} is being deleted."
|
|
158
|
+
"Unexpected error in the operation: Batch job with name {job_name} is being deleted."
|
|
159
159
|
)
|
|
160
160
|
raise AirflowException(message)
|
|
161
|
-
|
|
162
|
-
time.sleep(polling_period_seconds)
|
|
161
|
+
time.sleep(polling_period_seconds)
|
|
163
162
|
except Exception as e:
|
|
164
163
|
self.log.exception("Exception occurred while checking for job completion.")
|
|
165
164
|
raise e
|
|
@@ -22,15 +22,16 @@ from __future__ import annotations
|
|
|
22
22
|
from collections.abc import Sequence
|
|
23
23
|
from typing import TYPE_CHECKING
|
|
24
24
|
|
|
25
|
-
from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning
|
|
26
|
-
from airflow.providers.google.common.consts import CLIENT_INFO
|
|
27
|
-
from airflow.providers.google.common.deprecated import deprecated
|
|
28
|
-
from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook
|
|
29
25
|
from google.api_core.client_options import ClientOptions
|
|
30
26
|
from google.api_core.exceptions import AlreadyExists
|
|
31
27
|
from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault
|
|
32
28
|
from google.cloud.devtools.cloudbuild_v1 import CloudBuildAsyncClient, CloudBuildClient, GetBuildRequest
|
|
33
29
|
|
|
30
|
+
from airflow.exceptions import AirflowException
|
|
31
|
+
from airflow.providers.google.common.consts import CLIENT_INFO
|
|
32
|
+
from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook
|
|
33
|
+
from airflow.providers.google.common.hooks.operation_helpers import OperationHelper
|
|
34
|
+
|
|
34
35
|
if TYPE_CHECKING:
|
|
35
36
|
from google.api_core.operation import Operation
|
|
36
37
|
from google.api_core.retry import Retry
|
|
@@ -41,7 +42,7 @@ if TYPE_CHECKING:
|
|
|
41
42
|
TIME_TO_SLEEP_IN_SECONDS = 5
|
|
42
43
|
|
|
43
44
|
|
|
44
|
-
class CloudBuildHook(GoogleBaseHook):
|
|
45
|
+
class CloudBuildHook(GoogleBaseHook, OperationHelper):
|
|
45
46
|
"""
|
|
46
47
|
Hook for the Google Cloud Build Service.
|
|
47
48
|
|
|
@@ -79,14 +80,6 @@ class CloudBuildHook(GoogleBaseHook):
|
|
|
79
80
|
except Exception:
|
|
80
81
|
raise AirflowException("Could not retrieve Build ID from Operation.")
|
|
81
82
|
|
|
82
|
-
def wait_for_operation(self, operation: Operation, timeout: float | None = None):
|
|
83
|
-
"""Wait for long-lasting operation to complete."""
|
|
84
|
-
try:
|
|
85
|
-
return operation.result(timeout=timeout)
|
|
86
|
-
except Exception:
|
|
87
|
-
error = operation.exception(timeout=timeout)
|
|
88
|
-
raise AirflowException(error)
|
|
89
|
-
|
|
90
83
|
def get_conn(self, location: str = "global") -> CloudBuildClient:
|
|
91
84
|
"""
|
|
92
85
|
Retrieve the connection to Google Cloud Build.
|
|
@@ -184,58 +177,6 @@ class CloudBuildHook(GoogleBaseHook):
|
|
|
184
177
|
|
|
185
178
|
return operation, id_
|
|
186
179
|
|
|
187
|
-
@GoogleBaseHook.fallback_to_default_project_id
|
|
188
|
-
@deprecated(
|
|
189
|
-
planned_removal_date="March 01, 2025",
|
|
190
|
-
use_instead="create_build_without_waiting_for_result",
|
|
191
|
-
category=AirflowProviderDeprecationWarning,
|
|
192
|
-
)
|
|
193
|
-
def create_build(
|
|
194
|
-
self,
|
|
195
|
-
build: dict | Build,
|
|
196
|
-
project_id: str = PROVIDE_PROJECT_ID,
|
|
197
|
-
wait: bool = True,
|
|
198
|
-
retry: Retry | _MethodDefault = DEFAULT,
|
|
199
|
-
timeout: float | None = None,
|
|
200
|
-
metadata: Sequence[tuple[str, str]] = (),
|
|
201
|
-
) -> Build:
|
|
202
|
-
"""
|
|
203
|
-
Start a build with the specified configuration.
|
|
204
|
-
|
|
205
|
-
:param build: The build resource to create. If a dict is provided, it must be of the same form
|
|
206
|
-
as the protobuf message `google.cloud.devtools.cloudbuild_v1.types.Build`
|
|
207
|
-
:param project_id: Optional, Google Cloud Project project_id where the function belongs.
|
|
208
|
-
If set to None or missing, the default project_id from the GCP connection is used.
|
|
209
|
-
:param wait: Optional, wait for operation to finish.
|
|
210
|
-
:param retry: Optional, a retry object used to retry requests. If `None` is specified, requests
|
|
211
|
-
will not be retried.
|
|
212
|
-
:param timeout: Optional, the amount of time, in seconds, to wait for the request to complete.
|
|
213
|
-
Note that if `retry` is specified, the timeout applies to each individual attempt.
|
|
214
|
-
:param metadata: Optional, additional metadata that is provided to the method.
|
|
215
|
-
|
|
216
|
-
"""
|
|
217
|
-
client = self.get_conn()
|
|
218
|
-
|
|
219
|
-
self.log.info("Start creating build...")
|
|
220
|
-
|
|
221
|
-
operation = client.create_build(
|
|
222
|
-
request={"project_id": project_id, "build": build},
|
|
223
|
-
retry=retry,
|
|
224
|
-
timeout=timeout,
|
|
225
|
-
metadata=metadata,
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
id_ = self._get_build_id_from_operation(operation)
|
|
229
|
-
|
|
230
|
-
if not wait:
|
|
231
|
-
return self.get_build(id_=id_, project_id=project_id)
|
|
232
|
-
|
|
233
|
-
operation.result()
|
|
234
|
-
|
|
235
|
-
self.log.info("Build has been created: %s.", id_)
|
|
236
|
-
|
|
237
|
-
return self.get_build(id_=id_, project_id=project_id)
|
|
238
|
-
|
|
239
180
|
@GoogleBaseHook.fallback_to_default_project_id
|
|
240
181
|
def create_build_trigger(
|
|
241
182
|
self,
|
|
@@ -18,15 +18,16 @@
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
20
|
import asyncio
|
|
21
|
+
import json
|
|
21
22
|
import time
|
|
22
23
|
from collections.abc import MutableSequence, Sequence
|
|
23
|
-
from typing import TYPE_CHECKING
|
|
24
|
+
from typing import TYPE_CHECKING, Any
|
|
25
|
+
from urllib.parse import urlencode, urljoin
|
|
24
26
|
|
|
25
|
-
from
|
|
26
|
-
from airflow.providers.google.common.consts import CLIENT_INFO
|
|
27
|
-
from airflow.providers.google.common.hooks.base_google import GoogleBaseHook
|
|
27
|
+
from aiohttp import ClientSession
|
|
28
28
|
from google.api_core.client_options import ClientOptions
|
|
29
29
|
from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault
|
|
30
|
+
from google.auth.transport.requests import AuthorizedSession, Request
|
|
30
31
|
from google.cloud.orchestration.airflow.service_v1 import (
|
|
31
32
|
EnvironmentsAsyncClient,
|
|
32
33
|
EnvironmentsClient,
|
|
@@ -34,6 +35,10 @@ from google.cloud.orchestration.airflow.service_v1 import (
|
|
|
34
35
|
PollAirflowCommandResponse,
|
|
35
36
|
)
|
|
36
37
|
|
|
38
|
+
from airflow.exceptions import AirflowException
|
|
39
|
+
from airflow.providers.google.common.consts import CLIENT_INFO
|
|
40
|
+
from airflow.providers.google.common.hooks.base_google import GoogleBaseAsyncHook, GoogleBaseHook
|
|
41
|
+
|
|
37
42
|
if TYPE_CHECKING:
|
|
38
43
|
from google.api_core.operation import Operation
|
|
39
44
|
from google.api_core.operation_async import AsyncOperation
|
|
@@ -51,8 +56,10 @@ if TYPE_CHECKING:
|
|
|
51
56
|
)
|
|
52
57
|
from google.protobuf.field_mask_pb2 import FieldMask
|
|
53
58
|
|
|
59
|
+
from airflow.providers.google.common.hooks.operation_helpers import OperationHelper
|
|
60
|
+
|
|
54
61
|
|
|
55
|
-
class CloudComposerHook(GoogleBaseHook):
|
|
62
|
+
class CloudComposerHook(GoogleBaseHook, OperationHelper):
|
|
56
63
|
"""Hook for Google Cloud Composer APIs."""
|
|
57
64
|
|
|
58
65
|
client_options = ClientOptions(api_endpoint="composer.googleapis.com:443")
|
|
@@ -73,13 +80,33 @@ class CloudComposerHook(GoogleBaseHook):
|
|
|
73
80
|
client_options=self.client_options,
|
|
74
81
|
)
|
|
75
82
|
|
|
76
|
-
def
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
def make_composer_airflow_api_request(
|
|
84
|
+
self,
|
|
85
|
+
method: str,
|
|
86
|
+
airflow_uri: str,
|
|
87
|
+
path: str,
|
|
88
|
+
data: Any | None = None,
|
|
89
|
+
timeout: float | None = None,
|
|
90
|
+
):
|
|
91
|
+
"""
|
|
92
|
+
Make a request to Cloud Composer environment's web server.
|
|
93
|
+
|
|
94
|
+
:param method: The request method to use ('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE').
|
|
95
|
+
:param airflow_uri: The URI of the Apache Airflow Web UI hosted within this environment.
|
|
96
|
+
:param path: The path to send the request.
|
|
97
|
+
:param data: Dictionary, list of tuples, bytes, or file-like object to send in the body of the request.
|
|
98
|
+
:param timeout: The timeout for this request.
|
|
99
|
+
"""
|
|
100
|
+
authed_session = AuthorizedSession(self.get_credentials())
|
|
101
|
+
|
|
102
|
+
resp = authed_session.request(
|
|
103
|
+
method=method,
|
|
104
|
+
url=urljoin(airflow_uri, path),
|
|
105
|
+
data=data,
|
|
106
|
+
headers={"Content-Type": "application/json"},
|
|
107
|
+
timeout=timeout,
|
|
108
|
+
)
|
|
109
|
+
return resp
|
|
83
110
|
|
|
84
111
|
def get_operation(self, operation_name):
|
|
85
112
|
return self.get_environment_client().transport.operations_client.get_operation(name=operation_name)
|
|
@@ -413,20 +440,160 @@ class CloudComposerHook(GoogleBaseHook):
|
|
|
413
440
|
self.log.info("Waiting for result...")
|
|
414
441
|
time.sleep(poll_interval)
|
|
415
442
|
|
|
443
|
+
def trigger_dag_run(
|
|
444
|
+
self,
|
|
445
|
+
composer_airflow_uri: str,
|
|
446
|
+
composer_dag_id: str,
|
|
447
|
+
composer_dag_conf: dict | None = None,
|
|
448
|
+
timeout: float | None = None,
|
|
449
|
+
) -> dict:
|
|
450
|
+
"""
|
|
451
|
+
Trigger DAG run for provided Apache Airflow Web UI hosted within Composer environment.
|
|
452
|
+
|
|
453
|
+
:param composer_airflow_uri: The URI of the Apache Airflow Web UI hosted within Composer environment.
|
|
454
|
+
:param composer_dag_id: The ID of DAG which will be triggered.
|
|
455
|
+
:param composer_dag_conf: Configuration parameters for the DAG run.
|
|
456
|
+
:param timeout: The timeout for this request.
|
|
457
|
+
"""
|
|
458
|
+
response = self.make_composer_airflow_api_request(
|
|
459
|
+
method="POST",
|
|
460
|
+
airflow_uri=composer_airflow_uri,
|
|
461
|
+
path=f"/api/v1/dags/{composer_dag_id}/dagRuns",
|
|
462
|
+
data=json.dumps(
|
|
463
|
+
{
|
|
464
|
+
"conf": composer_dag_conf or {},
|
|
465
|
+
}
|
|
466
|
+
),
|
|
467
|
+
timeout=timeout,
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
if response.status_code != 200:
|
|
471
|
+
self.log.error(response.text)
|
|
472
|
+
response.raise_for_status()
|
|
473
|
+
|
|
474
|
+
return response.json()
|
|
475
|
+
|
|
476
|
+
def get_dag_runs(
|
|
477
|
+
self,
|
|
478
|
+
composer_airflow_uri: str,
|
|
479
|
+
composer_dag_id: str,
|
|
480
|
+
timeout: float | None = None,
|
|
481
|
+
) -> dict:
|
|
482
|
+
"""
|
|
483
|
+
Get the list of dag runs for provided DAG.
|
|
416
484
|
|
|
417
|
-
|
|
485
|
+
:param composer_airflow_uri: The URI of the Apache Airflow Web UI hosted within Composer environment.
|
|
486
|
+
:param composer_dag_id: The ID of DAG.
|
|
487
|
+
:param timeout: The timeout for this request.
|
|
488
|
+
"""
|
|
489
|
+
response = self.make_composer_airflow_api_request(
|
|
490
|
+
method="GET",
|
|
491
|
+
airflow_uri=composer_airflow_uri,
|
|
492
|
+
path=f"/api/v1/dags/{composer_dag_id}/dagRuns",
|
|
493
|
+
timeout=timeout,
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
if response.status_code != 200:
|
|
497
|
+
self.log.error(
|
|
498
|
+
"Failed to get DAG runs for dag_id=%s from %s (status=%s): %s",
|
|
499
|
+
composer_dag_id,
|
|
500
|
+
composer_airflow_uri,
|
|
501
|
+
response.status_code,
|
|
502
|
+
response.text,
|
|
503
|
+
)
|
|
504
|
+
response.raise_for_status()
|
|
505
|
+
|
|
506
|
+
return response.json()
|
|
507
|
+
|
|
508
|
+
def get_task_instances(
|
|
509
|
+
self,
|
|
510
|
+
composer_airflow_uri: str,
|
|
511
|
+
composer_dag_id: str,
|
|
512
|
+
query_parameters: dict | None = None,
|
|
513
|
+
timeout: float | None = None,
|
|
514
|
+
) -> dict:
|
|
515
|
+
"""
|
|
516
|
+
Get the list of task instances for provided DAG.
|
|
517
|
+
|
|
518
|
+
:param composer_airflow_uri: The URI of the Apache Airflow Web UI hosted within Composer environment.
|
|
519
|
+
:param composer_dag_id: The ID of DAG.
|
|
520
|
+
:query_parameters: Query parameters for this request.
|
|
521
|
+
:param timeout: The timeout for this request.
|
|
522
|
+
"""
|
|
523
|
+
query_string = f"?{urlencode(query_parameters)}" if query_parameters else ""
|
|
524
|
+
|
|
525
|
+
response = self.make_composer_airflow_api_request(
|
|
526
|
+
method="GET",
|
|
527
|
+
airflow_uri=composer_airflow_uri,
|
|
528
|
+
path=f"/api/v1/dags/{composer_dag_id}/dagRuns/~/taskInstances{query_string}",
|
|
529
|
+
timeout=timeout,
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
if response.status_code != 200:
|
|
533
|
+
self.log.error(
|
|
534
|
+
"Failed to get task instances for dag_id=%s from %s (status=%s): %s",
|
|
535
|
+
composer_dag_id,
|
|
536
|
+
composer_airflow_uri,
|
|
537
|
+
response.status_code,
|
|
538
|
+
response.text,
|
|
539
|
+
)
|
|
540
|
+
response.raise_for_status()
|
|
541
|
+
|
|
542
|
+
return response.json()
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
class CloudComposerAsyncHook(GoogleBaseAsyncHook):
|
|
418
546
|
"""Hook for Google Cloud Composer async APIs."""
|
|
419
547
|
|
|
548
|
+
sync_hook_class = CloudComposerHook
|
|
549
|
+
|
|
420
550
|
client_options = ClientOptions(api_endpoint="composer.googleapis.com:443")
|
|
421
551
|
|
|
422
|
-
def get_environment_client(self) -> EnvironmentsAsyncClient:
|
|
552
|
+
async def get_environment_client(self) -> EnvironmentsAsyncClient:
|
|
423
553
|
"""Retrieve client library object that allow access Environments service."""
|
|
554
|
+
sync_hook = await self.get_sync_hook()
|
|
424
555
|
return EnvironmentsAsyncClient(
|
|
425
|
-
credentials=
|
|
556
|
+
credentials=sync_hook.get_credentials(),
|
|
426
557
|
client_info=CLIENT_INFO,
|
|
427
558
|
client_options=self.client_options,
|
|
428
559
|
)
|
|
429
560
|
|
|
561
|
+
async def make_composer_airflow_api_request(
|
|
562
|
+
self,
|
|
563
|
+
method: str,
|
|
564
|
+
airflow_uri: str,
|
|
565
|
+
path: str,
|
|
566
|
+
data: Any | None = None,
|
|
567
|
+
timeout: float | None = None,
|
|
568
|
+
):
|
|
569
|
+
"""
|
|
570
|
+
Make a request to Cloud Composer environment's web server.
|
|
571
|
+
|
|
572
|
+
:param method: The request method to use ('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE').
|
|
573
|
+
:param airflow_uri: The URI of the Apache Airflow Web UI hosted within this environment.
|
|
574
|
+
:param path: The path to send the request.
|
|
575
|
+
:param data: Dictionary, list of tuples, bytes, or file-like object to send in the body of the request.
|
|
576
|
+
:param timeout: The timeout for this request.
|
|
577
|
+
"""
|
|
578
|
+
sync_hook = await self.get_sync_hook()
|
|
579
|
+
credentials = sync_hook.get_credentials()
|
|
580
|
+
|
|
581
|
+
if not credentials.valid:
|
|
582
|
+
credentials.refresh(Request())
|
|
583
|
+
|
|
584
|
+
async with ClientSession() as session:
|
|
585
|
+
async with session.request(
|
|
586
|
+
method=method,
|
|
587
|
+
url=urljoin(airflow_uri, path),
|
|
588
|
+
data=data,
|
|
589
|
+
headers={
|
|
590
|
+
"Content-Type": "application/json",
|
|
591
|
+
"Authorization": f"Bearer {credentials.token}",
|
|
592
|
+
},
|
|
593
|
+
timeout=timeout,
|
|
594
|
+
) as response:
|
|
595
|
+
return await response.json(), response.status
|
|
596
|
+
|
|
430
597
|
def get_environment_name(self, project_id, region, environment_id):
|
|
431
598
|
return f"projects/{project_id}/locations/{region}/environments/{environment_id}"
|
|
432
599
|
|
|
@@ -434,9 +601,8 @@ class CloudComposerAsyncHook(GoogleBaseHook):
|
|
|
434
601
|
return f"projects/{project_id}/locations/{region}"
|
|
435
602
|
|
|
436
603
|
async def get_operation(self, operation_name):
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
)
|
|
604
|
+
client = await self.get_environment_client()
|
|
605
|
+
return await client.transport.operations_client.get_operation(name=operation_name)
|
|
440
606
|
|
|
441
607
|
@GoogleBaseHook.fallback_to_default_project_id
|
|
442
608
|
async def create_environment(
|
|
@@ -459,7 +625,7 @@ class CloudComposerAsyncHook(GoogleBaseHook):
|
|
|
459
625
|
:param timeout: The timeout for this request.
|
|
460
626
|
:param metadata: Strings which should be sent along with the request as metadata.
|
|
461
627
|
"""
|
|
462
|
-
client = self.get_environment_client()
|
|
628
|
+
client = await self.get_environment_client()
|
|
463
629
|
return await client.create_environment(
|
|
464
630
|
request={"parent": self.get_parent(project_id, region), "environment": environment},
|
|
465
631
|
retry=retry,
|
|
@@ -487,7 +653,7 @@ class CloudComposerAsyncHook(GoogleBaseHook):
|
|
|
487
653
|
:param timeout: The timeout for this request.
|
|
488
654
|
:param metadata: Strings which should be sent along with the request as metadata.
|
|
489
655
|
"""
|
|
490
|
-
client = self.get_environment_client()
|
|
656
|
+
client = await self.get_environment_client()
|
|
491
657
|
name = self.get_environment_name(project_id, region, environment_id)
|
|
492
658
|
return await client.delete_environment(
|
|
493
659
|
request={"name": name}, retry=retry, timeout=timeout, metadata=metadata
|
|
@@ -523,7 +689,7 @@ class CloudComposerAsyncHook(GoogleBaseHook):
|
|
|
523
689
|
:param timeout: The timeout for this request.
|
|
524
690
|
:param metadata: Strings which should be sent along with the request as metadata.
|
|
525
691
|
"""
|
|
526
|
-
client = self.get_environment_client()
|
|
692
|
+
client = await self.get_environment_client()
|
|
527
693
|
name = self.get_environment_name(project_id, region, environment_id)
|
|
528
694
|
|
|
529
695
|
return await client.update_environment(
|
|
@@ -533,6 +699,35 @@ class CloudComposerAsyncHook(GoogleBaseHook):
|
|
|
533
699
|
metadata=metadata,
|
|
534
700
|
)
|
|
535
701
|
|
|
702
|
+
@GoogleBaseHook.fallback_to_default_project_id
|
|
703
|
+
async def get_environment(
|
|
704
|
+
self,
|
|
705
|
+
project_id: str,
|
|
706
|
+
region: str,
|
|
707
|
+
environment_id: str,
|
|
708
|
+
retry: AsyncRetry | _MethodDefault = DEFAULT,
|
|
709
|
+
timeout: float | None = None,
|
|
710
|
+
metadata: Sequence[tuple[str, str]] = (),
|
|
711
|
+
) -> Environment:
|
|
712
|
+
"""
|
|
713
|
+
Get an existing environment.
|
|
714
|
+
|
|
715
|
+
:param project_id: Required. The ID of the Google Cloud project that the service belongs to.
|
|
716
|
+
:param region: Required. The ID of the Google Cloud region that the service belongs to.
|
|
717
|
+
:param environment_id: Required. The ID of the Google Cloud environment that the service belongs to.
|
|
718
|
+
:param retry: Designation of what errors, if any, should be retried.
|
|
719
|
+
:param timeout: The timeout for this request.
|
|
720
|
+
:param metadata: Strings which should be sent along with the request as metadata.
|
|
721
|
+
"""
|
|
722
|
+
client = await self.get_environment_client()
|
|
723
|
+
|
|
724
|
+
return await client.get_environment(
|
|
725
|
+
request={"name": self.get_environment_name(project_id, region, environment_id)},
|
|
726
|
+
retry=retry,
|
|
727
|
+
timeout=timeout,
|
|
728
|
+
metadata=metadata,
|
|
729
|
+
)
|
|
730
|
+
|
|
536
731
|
@GoogleBaseHook.fallback_to_default_project_id
|
|
537
732
|
async def execute_airflow_command(
|
|
538
733
|
self,
|
|
@@ -561,7 +756,7 @@ class CloudComposerAsyncHook(GoogleBaseHook):
|
|
|
561
756
|
:param timeout: The timeout for this request.
|
|
562
757
|
:param metadata: Strings which should be sent along with the request as metadata.
|
|
563
758
|
"""
|
|
564
|
-
client = self.get_environment_client()
|
|
759
|
+
client = await self.get_environment_client()
|
|
565
760
|
|
|
566
761
|
return await client.execute_airflow_command(
|
|
567
762
|
request={
|
|
@@ -603,7 +798,7 @@ class CloudComposerAsyncHook(GoogleBaseHook):
|
|
|
603
798
|
:param timeout: The timeout for this request.
|
|
604
799
|
:param metadata: Strings which should be sent along with the request as metadata.
|
|
605
800
|
"""
|
|
606
|
-
client = self.get_environment_client()
|
|
801
|
+
client = await self.get_environment_client()
|
|
607
802
|
|
|
608
803
|
return await client.poll_airflow_command(
|
|
609
804
|
request={
|
|
@@ -647,9 +842,82 @@ class CloudComposerAsyncHook(GoogleBaseHook):
|
|
|
647
842
|
self.log.exception("Exception occurred while polling CMD result")
|
|
648
843
|
raise AirflowException(ex)
|
|
649
844
|
|
|
650
|
-
|
|
845
|
+
try:
|
|
846
|
+
result_dict = PollAirflowCommandResponse.to_dict(result)
|
|
847
|
+
except Exception as ex:
|
|
848
|
+
self.log.exception("Exception occurred while transforming PollAirflowCommandResponse")
|
|
849
|
+
raise AirflowException(ex)
|
|
850
|
+
|
|
651
851
|
if result_dict["output_end"]:
|
|
652
852
|
return result_dict
|
|
653
853
|
|
|
654
854
|
self.log.info("Sleeping for %s seconds.", poll_interval)
|
|
655
855
|
await asyncio.sleep(poll_interval)
|
|
856
|
+
|
|
857
|
+
async def get_dag_runs(
|
|
858
|
+
self,
|
|
859
|
+
composer_airflow_uri: str,
|
|
860
|
+
composer_dag_id: str,
|
|
861
|
+
timeout: float | None = None,
|
|
862
|
+
) -> dict:
|
|
863
|
+
"""
|
|
864
|
+
Get the list of dag runs for provided DAG.
|
|
865
|
+
|
|
866
|
+
:param composer_airflow_uri: The URI of the Apache Airflow Web UI hosted within Composer environment.
|
|
867
|
+
:param composer_dag_id: The ID of DAG.
|
|
868
|
+
:param timeout: The timeout for this request.
|
|
869
|
+
"""
|
|
870
|
+
response_body, response_status_code = await self.make_composer_airflow_api_request(
|
|
871
|
+
method="GET",
|
|
872
|
+
airflow_uri=composer_airflow_uri,
|
|
873
|
+
path=f"/api/v1/dags/{composer_dag_id}/dagRuns",
|
|
874
|
+
timeout=timeout,
|
|
875
|
+
)
|
|
876
|
+
|
|
877
|
+
if response_status_code != 200:
|
|
878
|
+
self.log.error(
|
|
879
|
+
"Failed to get DAG runs for dag_id=%s from %s (status=%s): %s",
|
|
880
|
+
composer_dag_id,
|
|
881
|
+
composer_airflow_uri,
|
|
882
|
+
response_status_code,
|
|
883
|
+
response_body["title"],
|
|
884
|
+
)
|
|
885
|
+
raise AirflowException(response_body["title"])
|
|
886
|
+
|
|
887
|
+
return response_body
|
|
888
|
+
|
|
889
|
+
async def get_task_instances(
|
|
890
|
+
self,
|
|
891
|
+
composer_airflow_uri: str,
|
|
892
|
+
composer_dag_id: str,
|
|
893
|
+
query_parameters: dict | None = None,
|
|
894
|
+
timeout: float | None = None,
|
|
895
|
+
) -> dict:
|
|
896
|
+
"""
|
|
897
|
+
Get the list of task instances for provided DAG.
|
|
898
|
+
|
|
899
|
+
:param composer_airflow_uri: The URI of the Apache Airflow Web UI hosted within Composer environment.
|
|
900
|
+
:param composer_dag_id: The ID of DAG.
|
|
901
|
+
:query_parameters: Query parameters for this request.
|
|
902
|
+
:param timeout: The timeout for this request.
|
|
903
|
+
"""
|
|
904
|
+
query_string = f"?{urlencode(query_parameters)}" if query_parameters else ""
|
|
905
|
+
|
|
906
|
+
response_body, response_status_code = await self.make_composer_airflow_api_request(
|
|
907
|
+
method="GET",
|
|
908
|
+
airflow_uri=composer_airflow_uri,
|
|
909
|
+
path=f"/api/v1/dags/{composer_dag_id}/dagRuns/~/taskInstances{query_string}",
|
|
910
|
+
timeout=timeout,
|
|
911
|
+
)
|
|
912
|
+
|
|
913
|
+
if response_status_code != 200:
|
|
914
|
+
self.log.error(
|
|
915
|
+
"Failed to get task instances for dag_id=%s from %s (status=%s): %s",
|
|
916
|
+
composer_dag_id,
|
|
917
|
+
composer_airflow_uri,
|
|
918
|
+
response_status_code,
|
|
919
|
+
response_body["title"],
|
|
920
|
+
)
|
|
921
|
+
raise AirflowException(response_body["title"])
|
|
922
|
+
|
|
923
|
+
return response_body
|