apache-airflow-providers-google 15.1.0rc1__py3-none-any.whl → 19.3.0__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 (257) hide show
  1. airflow/providers/google/3rd-party-licenses/NOTICE +2 -12
  2. airflow/providers/google/__init__.py +3 -3
  3. airflow/providers/google/ads/hooks/ads.py +39 -6
  4. airflow/providers/google/ads/operators/ads.py +2 -2
  5. airflow/providers/google/ads/transfers/ads_to_gcs.py +2 -2
  6. airflow/providers/google/assets/gcs.py +1 -11
  7. airflow/providers/google/cloud/bundles/__init__.py +16 -0
  8. airflow/providers/google/cloud/bundles/gcs.py +161 -0
  9. airflow/providers/google/cloud/hooks/alloy_db.py +1 -1
  10. airflow/providers/google/cloud/hooks/bigquery.py +176 -293
  11. airflow/providers/google/cloud/hooks/cloud_batch.py +1 -1
  12. airflow/providers/google/cloud/hooks/cloud_build.py +1 -1
  13. airflow/providers/google/cloud/hooks/cloud_composer.py +288 -15
  14. airflow/providers/google/cloud/hooks/cloud_logging.py +109 -0
  15. airflow/providers/google/cloud/hooks/cloud_memorystore.py +1 -1
  16. airflow/providers/google/cloud/hooks/cloud_run.py +18 -10
  17. airflow/providers/google/cloud/hooks/cloud_sql.py +102 -23
  18. airflow/providers/google/cloud/hooks/cloud_storage_transfer_service.py +29 -7
  19. airflow/providers/google/cloud/hooks/compute.py +1 -1
  20. airflow/providers/google/cloud/hooks/compute_ssh.py +6 -2
  21. airflow/providers/google/cloud/hooks/datacatalog.py +10 -1
  22. airflow/providers/google/cloud/hooks/dataflow.py +72 -95
  23. airflow/providers/google/cloud/hooks/dataform.py +1 -1
  24. airflow/providers/google/cloud/hooks/datafusion.py +21 -19
  25. airflow/providers/google/cloud/hooks/dataplex.py +2 -2
  26. airflow/providers/google/cloud/hooks/dataprep.py +1 -1
  27. airflow/providers/google/cloud/hooks/dataproc.py +73 -72
  28. airflow/providers/google/cloud/hooks/dataproc_metastore.py +1 -1
  29. airflow/providers/google/cloud/hooks/dlp.py +1 -1
  30. airflow/providers/google/cloud/hooks/functions.py +1 -1
  31. airflow/providers/google/cloud/hooks/gcs.py +112 -15
  32. airflow/providers/google/cloud/hooks/gdm.py +1 -1
  33. airflow/providers/google/cloud/hooks/gen_ai.py +196 -0
  34. airflow/providers/google/cloud/hooks/kubernetes_engine.py +3 -3
  35. airflow/providers/google/cloud/hooks/looker.py +6 -2
  36. airflow/providers/google/cloud/hooks/managed_kafka.py +1 -1
  37. airflow/providers/google/cloud/hooks/mlengine.py +4 -3
  38. airflow/providers/google/cloud/hooks/pubsub.py +3 -0
  39. airflow/providers/google/cloud/hooks/secret_manager.py +102 -10
  40. airflow/providers/google/cloud/hooks/spanner.py +74 -9
  41. airflow/providers/google/cloud/hooks/stackdriver.py +11 -9
  42. airflow/providers/google/cloud/hooks/tasks.py +1 -1
  43. airflow/providers/google/cloud/hooks/translate.py +2 -2
  44. airflow/providers/google/cloud/hooks/vertex_ai/auto_ml.py +2 -210
  45. airflow/providers/google/cloud/hooks/vertex_ai/batch_prediction_job.py +3 -3
  46. airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py +28 -2
  47. airflow/providers/google/cloud/hooks/vertex_ai/experiment_service.py +202 -0
  48. airflow/providers/google/cloud/hooks/vertex_ai/feature_store.py +308 -8
  49. airflow/providers/google/cloud/hooks/vertex_ai/generative_model.py +79 -75
  50. airflow/providers/google/cloud/hooks/vertex_ai/hyperparameter_tuning_job.py +1 -1
  51. airflow/providers/google/cloud/hooks/vertex_ai/model_service.py +1 -1
  52. airflow/providers/google/cloud/hooks/vertex_ai/pipeline_job.py +1 -1
  53. airflow/providers/google/cloud/hooks/vertex_ai/ray.py +223 -0
  54. airflow/providers/google/cloud/hooks/vision.py +3 -3
  55. airflow/providers/google/cloud/hooks/workflows.py +1 -1
  56. airflow/providers/google/cloud/links/alloy_db.py +0 -46
  57. airflow/providers/google/cloud/links/base.py +77 -13
  58. airflow/providers/google/cloud/links/bigquery.py +0 -47
  59. airflow/providers/google/cloud/links/bigquery_dts.py +0 -20
  60. airflow/providers/google/cloud/links/bigtable.py +0 -48
  61. airflow/providers/google/cloud/links/cloud_build.py +0 -73
  62. airflow/providers/google/cloud/links/cloud_functions.py +0 -33
  63. airflow/providers/google/cloud/links/cloud_memorystore.py +0 -58
  64. airflow/providers/google/cloud/links/{life_sciences.py → cloud_run.py} +5 -27
  65. airflow/providers/google/cloud/links/cloud_sql.py +0 -33
  66. airflow/providers/google/cloud/links/cloud_storage_transfer.py +17 -44
  67. airflow/providers/google/cloud/links/cloud_tasks.py +7 -26
  68. airflow/providers/google/cloud/links/compute.py +0 -58
  69. airflow/providers/google/cloud/links/data_loss_prevention.py +0 -169
  70. airflow/providers/google/cloud/links/datacatalog.py +23 -54
  71. airflow/providers/google/cloud/links/dataflow.py +0 -34
  72. airflow/providers/google/cloud/links/dataform.py +0 -64
  73. airflow/providers/google/cloud/links/datafusion.py +1 -96
  74. airflow/providers/google/cloud/links/dataplex.py +0 -154
  75. airflow/providers/google/cloud/links/dataprep.py +0 -24
  76. airflow/providers/google/cloud/links/dataproc.py +11 -95
  77. airflow/providers/google/cloud/links/datastore.py +0 -31
  78. airflow/providers/google/cloud/links/kubernetes_engine.py +9 -60
  79. airflow/providers/google/cloud/links/managed_kafka.py +0 -70
  80. airflow/providers/google/cloud/links/mlengine.py +0 -70
  81. airflow/providers/google/cloud/links/pubsub.py +0 -32
  82. airflow/providers/google/cloud/links/spanner.py +0 -33
  83. airflow/providers/google/cloud/links/stackdriver.py +0 -30
  84. airflow/providers/google/cloud/links/translate.py +17 -187
  85. airflow/providers/google/cloud/links/vertex_ai.py +28 -195
  86. airflow/providers/google/cloud/links/workflows.py +0 -52
  87. airflow/providers/google/cloud/log/gcs_task_handler.py +58 -22
  88. airflow/providers/google/cloud/log/stackdriver_task_handler.py +9 -6
  89. airflow/providers/google/cloud/openlineage/CloudStorageTransferJobFacet.json +68 -0
  90. airflow/providers/google/cloud/openlineage/CloudStorageTransferRunFacet.json +60 -0
  91. airflow/providers/google/cloud/openlineage/DataFusionRunFacet.json +32 -0
  92. airflow/providers/google/cloud/openlineage/facets.py +102 -1
  93. airflow/providers/google/cloud/openlineage/mixins.py +10 -8
  94. airflow/providers/google/cloud/openlineage/utils.py +15 -1
  95. airflow/providers/google/cloud/operators/alloy_db.py +71 -56
  96. airflow/providers/google/cloud/operators/bigquery.py +73 -636
  97. airflow/providers/google/cloud/operators/bigquery_dts.py +4 -6
  98. airflow/providers/google/cloud/operators/bigtable.py +37 -8
  99. airflow/providers/google/cloud/operators/cloud_base.py +21 -1
  100. airflow/providers/google/cloud/operators/cloud_batch.py +3 -3
  101. airflow/providers/google/cloud/operators/cloud_build.py +76 -33
  102. airflow/providers/google/cloud/operators/cloud_composer.py +129 -41
  103. airflow/providers/google/cloud/operators/cloud_logging_sink.py +341 -0
  104. airflow/providers/google/cloud/operators/cloud_memorystore.py +69 -43
  105. airflow/providers/google/cloud/operators/cloud_run.py +24 -6
  106. airflow/providers/google/cloud/operators/cloud_sql.py +8 -17
  107. airflow/providers/google/cloud/operators/cloud_storage_transfer_service.py +93 -12
  108. airflow/providers/google/cloud/operators/compute.py +9 -41
  109. airflow/providers/google/cloud/operators/datacatalog.py +157 -21
  110. airflow/providers/google/cloud/operators/dataflow.py +40 -16
  111. airflow/providers/google/cloud/operators/dataform.py +15 -5
  112. airflow/providers/google/cloud/operators/datafusion.py +42 -21
  113. airflow/providers/google/cloud/operators/dataplex.py +194 -110
  114. airflow/providers/google/cloud/operators/dataprep.py +1 -5
  115. airflow/providers/google/cloud/operators/dataproc.py +80 -36
  116. airflow/providers/google/cloud/operators/dataproc_metastore.py +97 -89
  117. airflow/providers/google/cloud/operators/datastore.py +23 -7
  118. airflow/providers/google/cloud/operators/dlp.py +6 -29
  119. airflow/providers/google/cloud/operators/functions.py +17 -8
  120. airflow/providers/google/cloud/operators/gcs.py +12 -9
  121. airflow/providers/google/cloud/operators/gen_ai.py +389 -0
  122. airflow/providers/google/cloud/operators/kubernetes_engine.py +62 -100
  123. airflow/providers/google/cloud/operators/looker.py +2 -2
  124. airflow/providers/google/cloud/operators/managed_kafka.py +108 -53
  125. airflow/providers/google/cloud/operators/natural_language.py +1 -1
  126. airflow/providers/google/cloud/operators/pubsub.py +68 -15
  127. airflow/providers/google/cloud/operators/spanner.py +26 -13
  128. airflow/providers/google/cloud/operators/speech_to_text.py +2 -3
  129. airflow/providers/google/cloud/operators/stackdriver.py +1 -9
  130. airflow/providers/google/cloud/operators/tasks.py +1 -12
  131. airflow/providers/google/cloud/operators/text_to_speech.py +2 -3
  132. airflow/providers/google/cloud/operators/translate.py +41 -17
  133. airflow/providers/google/cloud/operators/translate_speech.py +2 -3
  134. airflow/providers/google/cloud/operators/vertex_ai/auto_ml.py +39 -19
  135. airflow/providers/google/cloud/operators/vertex_ai/batch_prediction_job.py +30 -10
  136. airflow/providers/google/cloud/operators/vertex_ai/custom_job.py +55 -27
  137. airflow/providers/google/cloud/operators/vertex_ai/dataset.py +70 -8
  138. airflow/providers/google/cloud/operators/vertex_ai/endpoint_service.py +43 -9
  139. airflow/providers/google/cloud/operators/vertex_ai/experiment_service.py +435 -0
  140. airflow/providers/google/cloud/operators/vertex_ai/feature_store.py +532 -1
  141. airflow/providers/google/cloud/operators/vertex_ai/generative_model.py +135 -115
  142. airflow/providers/google/cloud/operators/vertex_ai/hyperparameter_tuning_job.py +12 -10
  143. airflow/providers/google/cloud/operators/vertex_ai/model_service.py +57 -11
  144. airflow/providers/google/cloud/operators/vertex_ai/pipeline_job.py +31 -8
  145. airflow/providers/google/cloud/operators/vertex_ai/ray.py +393 -0
  146. airflow/providers/google/cloud/operators/video_intelligence.py +1 -1
  147. airflow/providers/google/cloud/operators/vision.py +2 -2
  148. airflow/providers/google/cloud/operators/workflows.py +18 -15
  149. airflow/providers/google/cloud/secrets/secret_manager.py +3 -2
  150. airflow/providers/google/cloud/sensors/bigquery.py +3 -3
  151. airflow/providers/google/cloud/sensors/bigquery_dts.py +2 -3
  152. airflow/providers/google/cloud/sensors/bigtable.py +11 -4
  153. airflow/providers/google/cloud/sensors/cloud_composer.py +533 -30
  154. airflow/providers/google/cloud/sensors/cloud_storage_transfer_service.py +2 -3
  155. airflow/providers/google/cloud/sensors/dataflow.py +26 -10
  156. airflow/providers/google/cloud/sensors/dataform.py +2 -3
  157. airflow/providers/google/cloud/sensors/datafusion.py +4 -5
  158. airflow/providers/google/cloud/sensors/dataplex.py +2 -3
  159. airflow/providers/google/cloud/sensors/dataprep.py +2 -2
  160. airflow/providers/google/cloud/sensors/dataproc.py +2 -3
  161. airflow/providers/google/cloud/sensors/dataproc_metastore.py +2 -3
  162. airflow/providers/google/cloud/sensors/gcs.py +4 -5
  163. airflow/providers/google/cloud/sensors/looker.py +2 -3
  164. airflow/providers/google/cloud/sensors/pubsub.py +4 -5
  165. airflow/providers/google/cloud/sensors/tasks.py +2 -2
  166. airflow/providers/google/cloud/sensors/vertex_ai/feature_store.py +2 -3
  167. airflow/providers/google/cloud/sensors/workflows.py +2 -3
  168. airflow/providers/google/cloud/transfers/adls_to_gcs.py +1 -1
  169. airflow/providers/google/cloud/transfers/azure_blob_to_gcs.py +2 -2
  170. airflow/providers/google/cloud/transfers/azure_fileshare_to_gcs.py +4 -3
  171. airflow/providers/google/cloud/transfers/bigquery_to_bigquery.py +11 -8
  172. airflow/providers/google/cloud/transfers/bigquery_to_gcs.py +10 -5
  173. airflow/providers/google/cloud/transfers/bigquery_to_mssql.py +7 -3
  174. airflow/providers/google/cloud/transfers/bigquery_to_mysql.py +12 -1
  175. airflow/providers/google/cloud/transfers/bigquery_to_postgres.py +24 -10
  176. airflow/providers/google/cloud/transfers/bigquery_to_sql.py +104 -5
  177. airflow/providers/google/cloud/transfers/calendar_to_gcs.py +1 -1
  178. airflow/providers/google/cloud/transfers/cassandra_to_gcs.py +3 -3
  179. airflow/providers/google/cloud/transfers/facebook_ads_to_gcs.py +4 -4
  180. airflow/providers/google/cloud/transfers/gcs_to_bigquery.py +21 -13
  181. airflow/providers/google/cloud/transfers/gcs_to_gcs.py +4 -3
  182. airflow/providers/google/cloud/transfers/gcs_to_local.py +6 -4
  183. airflow/providers/google/cloud/transfers/gcs_to_sftp.py +11 -5
  184. airflow/providers/google/cloud/transfers/gdrive_to_gcs.py +6 -2
  185. airflow/providers/google/cloud/transfers/gdrive_to_local.py +2 -2
  186. airflow/providers/google/cloud/transfers/http_to_gcs.py +193 -0
  187. airflow/providers/google/cloud/transfers/local_to_gcs.py +2 -2
  188. airflow/providers/google/cloud/transfers/mssql_to_gcs.py +1 -1
  189. airflow/providers/google/cloud/transfers/oracle_to_gcs.py +36 -11
  190. airflow/providers/google/cloud/transfers/postgres_to_gcs.py +42 -9
  191. airflow/providers/google/cloud/transfers/s3_to_gcs.py +13 -7
  192. airflow/providers/google/cloud/transfers/salesforce_to_gcs.py +2 -2
  193. airflow/providers/google/cloud/transfers/sftp_to_gcs.py +14 -5
  194. airflow/providers/google/cloud/transfers/sheets_to_gcs.py +3 -3
  195. airflow/providers/google/cloud/transfers/sql_to_gcs.py +10 -10
  196. airflow/providers/google/cloud/triggers/bigquery.py +76 -35
  197. airflow/providers/google/cloud/triggers/cloud_build.py +1 -1
  198. airflow/providers/google/cloud/triggers/cloud_composer.py +303 -47
  199. airflow/providers/google/cloud/triggers/cloud_run.py +3 -3
  200. airflow/providers/google/cloud/triggers/cloud_storage_transfer_service.py +92 -2
  201. airflow/providers/google/cloud/triggers/dataflow.py +122 -0
  202. airflow/providers/google/cloud/triggers/datafusion.py +1 -1
  203. airflow/providers/google/cloud/triggers/dataplex.py +14 -2
  204. airflow/providers/google/cloud/triggers/dataproc.py +123 -53
  205. airflow/providers/google/cloud/triggers/kubernetes_engine.py +47 -28
  206. airflow/providers/google/cloud/triggers/mlengine.py +1 -1
  207. airflow/providers/google/cloud/triggers/pubsub.py +15 -19
  208. airflow/providers/google/cloud/triggers/vertex_ai.py +1 -1
  209. airflow/providers/google/cloud/utils/bigquery_get_data.py +1 -1
  210. airflow/providers/google/cloud/utils/credentials_provider.py +2 -2
  211. airflow/providers/google/cloud/utils/field_sanitizer.py +1 -1
  212. airflow/providers/google/cloud/utils/field_validator.py +2 -3
  213. airflow/providers/google/common/auth_backend/google_openid.py +4 -4
  214. airflow/providers/google/common/deprecated.py +2 -1
  215. airflow/providers/google/common/hooks/base_google.py +27 -9
  216. airflow/providers/google/common/hooks/operation_helpers.py +1 -1
  217. airflow/providers/google/common/links/storage.py +0 -22
  218. airflow/providers/google/common/utils/get_secret.py +31 -0
  219. airflow/providers/google/common/utils/id_token_credentials.py +3 -4
  220. airflow/providers/google/firebase/hooks/firestore.py +1 -1
  221. airflow/providers/google/firebase/operators/firestore.py +3 -3
  222. airflow/providers/google/get_provider_info.py +56 -52
  223. airflow/providers/google/go_module_utils.py +35 -3
  224. airflow/providers/google/leveldb/hooks/leveldb.py +27 -2
  225. airflow/providers/google/leveldb/operators/leveldb.py +2 -2
  226. airflow/providers/google/marketing_platform/hooks/campaign_manager.py +1 -1
  227. airflow/providers/google/marketing_platform/hooks/display_video.py +3 -109
  228. airflow/providers/google/marketing_platform/hooks/search_ads.py +1 -1
  229. airflow/providers/google/marketing_platform/links/analytics_admin.py +5 -14
  230. airflow/providers/google/marketing_platform/operators/analytics_admin.py +2 -3
  231. airflow/providers/google/marketing_platform/operators/campaign_manager.py +6 -6
  232. airflow/providers/google/marketing_platform/operators/display_video.py +28 -489
  233. airflow/providers/google/marketing_platform/operators/search_ads.py +2 -2
  234. airflow/providers/google/marketing_platform/sensors/campaign_manager.py +2 -2
  235. airflow/providers/google/marketing_platform/sensors/display_video.py +3 -64
  236. airflow/providers/google/suite/hooks/calendar.py +2 -2
  237. airflow/providers/google/suite/hooks/sheets.py +16 -2
  238. airflow/providers/google/suite/operators/sheets.py +8 -3
  239. airflow/providers/google/suite/sensors/drive.py +2 -2
  240. airflow/providers/google/suite/transfers/gcs_to_gdrive.py +3 -3
  241. airflow/providers/google/suite/transfers/gcs_to_sheets.py +1 -1
  242. airflow/providers/google/suite/transfers/local_to_drive.py +3 -3
  243. airflow/providers/google/suite/transfers/sql_to_sheets.py +5 -4
  244. airflow/providers/google/version_compat.py +15 -1
  245. {apache_airflow_providers_google-15.1.0rc1.dist-info → apache_airflow_providers_google-19.3.0.dist-info}/METADATA +90 -46
  246. apache_airflow_providers_google-19.3.0.dist-info/RECORD +331 -0
  247. apache_airflow_providers_google-19.3.0.dist-info/licenses/NOTICE +5 -0
  248. airflow/providers/google/cloud/hooks/automl.py +0 -673
  249. airflow/providers/google/cloud/hooks/life_sciences.py +0 -159
  250. airflow/providers/google/cloud/links/automl.py +0 -193
  251. airflow/providers/google/cloud/operators/automl.py +0 -1362
  252. airflow/providers/google/cloud/operators/life_sciences.py +0 -119
  253. airflow/providers/google/cloud/operators/mlengine.py +0 -112
  254. apache_airflow_providers_google-15.1.0rc1.dist-info/RECORD +0 -321
  255. {apache_airflow_providers_google-15.1.0rc1.dist-info → apache_airflow_providers_google-19.3.0.dist-info}/WHEEL +0 -0
  256. {apache_airflow_providers_google-15.1.0rc1.dist-info → apache_airflow_providers_google-19.3.0.dist-info}/entry_points.txt +0 -0
  257. {airflow/providers/google → apache_airflow_providers_google-19.3.0.dist-info/licenses}/LICENSE +0 -0
@@ -1,15 +1,5 @@
1
1
  Apache Airflow
2
2
  Copyright 2016-2025 The Apache Software Foundation
3
3
 
4
- This product includes software developed at The Apache Software
5
- Foundation (http://www.apache.org/).
6
-
7
- =======================================================================
8
-
9
- json-merge-patch:
10
- -----------------
11
-
12
- This product contains a modified portion of 'json-merge-patch' developed by Open Data Services Coop
13
- https://github.com/OpenDataServices/json-merge-patch).
14
-
15
- Copyright (c) 2015, Open Data Services Coop
4
+ This product includes software developed at
5
+ The Apache Software Foundation (http://www.apache.org/).
@@ -29,11 +29,11 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "15.1.0"
32
+ __version__ = "19.3.0"
33
33
 
34
34
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
35
- "2.9.0"
35
+ "2.11.0"
36
36
  ):
37
37
  raise RuntimeError(
38
- f"The package `apache-airflow-providers-google:{__version__}` needs Apache Airflow 2.9.0+"
38
+ f"The package `apache-airflow-providers-google:{__version__}` needs Apache Airflow 2.11.0+"
39
39
  )
@@ -27,15 +27,14 @@ from google.ads.googleads.client import GoogleAdsClient
27
27
  from google.ads.googleads.errors import GoogleAdsException
28
28
  from google.auth.exceptions import GoogleAuthError
29
29
 
30
- from airflow.exceptions import AirflowException
31
- from airflow.hooks.base import BaseHook
30
+ from airflow.providers.common.compat.sdk import AirflowException, BaseHook
32
31
  from airflow.providers.google.common.hooks.base_google import get_field
33
32
 
34
33
  if TYPE_CHECKING:
35
- from google.ads.googleads.v19.services.services.customer_service import CustomerServiceClient
36
- from google.ads.googleads.v19.services.services.google_ads_service import GoogleAdsServiceClient
37
- from google.ads.googleads.v19.services.services.google_ads_service.pagers import SearchPager
38
- from google.ads.googleads.v19.services.types.google_ads_service import GoogleAdsRow
34
+ from google.ads.googleads.v21.services.services.customer_service import CustomerServiceClient
35
+ from google.ads.googleads.v21.services.services.google_ads_service import GoogleAdsServiceClient
36
+ from google.ads.googleads.v21.services.services.google_ads_service.pagers import SearchPager
37
+ from google.ads.googleads.v21.services.types.google_ads_service import GoogleAdsRow
39
38
 
40
39
 
41
40
  class GoogleAdsHook(BaseHook):
@@ -101,6 +100,40 @@ class GoogleAdsHook(BaseHook):
101
100
  :param api_version: The Google Ads API version to use.
102
101
  """
103
102
 
103
+ conn_name_attr = "google_ads_conn_id"
104
+ default_conn_name = "google_ads_default"
105
+ conn_type = "google_ads"
106
+ hook_name = "Google Ads"
107
+
108
+ @classmethod
109
+ def get_connection_form_widgets(cls) -> dict[str, Any]:
110
+ """Return connection widgets to add to Google Ads connection form."""
111
+ from flask_appbuilder.fieldwidgets import BS3PasswordFieldWidget, BS3TextFieldWidget
112
+ from flask_babel import lazy_gettext
113
+ from wtforms import PasswordField, StringField
114
+
115
+ return {
116
+ "developer_token": StringField(lazy_gettext("Developer token"), widget=BS3TextFieldWidget()),
117
+ "client_id": StringField(lazy_gettext("OAuth2 Client ID"), widget=BS3TextFieldWidget()),
118
+ "client_secret": PasswordField(
119
+ lazy_gettext("OAuth2 Client Secret"), widget=BS3PasswordFieldWidget()
120
+ ),
121
+ "refresh_token": PasswordField(
122
+ lazy_gettext("OAuth2 Refresh Token"), widget=BS3PasswordFieldWidget()
123
+ ),
124
+ }
125
+
126
+ @classmethod
127
+ def get_ui_field_behaviour(cls) -> dict[str, Any]:
128
+ """Return custom UI field behaviour for Google Ads connection."""
129
+ return {
130
+ "hidden_fields": ["host", "login", "schema", "port"],
131
+ "relabeling": {},
132
+ "placeholders": {
133
+ "password": "Leave blank (optional)",
134
+ },
135
+ }
136
+
104
137
  def __init__(
105
138
  self,
106
139
  api_version: str | None = None,
@@ -24,12 +24,12 @@ from collections.abc import Sequence
24
24
  from tempfile import NamedTemporaryFile
25
25
  from typing import TYPE_CHECKING
26
26
 
27
- from airflow.models import BaseOperator
28
27
  from airflow.providers.google.ads.hooks.ads import GoogleAdsHook
29
28
  from airflow.providers.google.cloud.hooks.gcs import GCSHook
29
+ from airflow.providers.google.version_compat import BaseOperator
30
30
 
31
31
  if TYPE_CHECKING:
32
- from airflow.utils.context import Context
32
+ from airflow.providers.common.compat.sdk import Context
33
33
 
34
34
 
35
35
  class GoogleAdsListAccountsOperator(BaseOperator):
@@ -22,12 +22,12 @@ from operator import attrgetter
22
22
  from tempfile import NamedTemporaryFile
23
23
  from typing import TYPE_CHECKING
24
24
 
25
- from airflow.models import BaseOperator
26
25
  from airflow.providers.google.ads.hooks.ads import GoogleAdsHook
27
26
  from airflow.providers.google.cloud.hooks.gcs import GCSHook
27
+ from airflow.providers.google.version_compat import BaseOperator
28
28
 
29
29
  if TYPE_CHECKING:
30
- from airflow.utils.context import Context
30
+ from airflow.providers.common.compat.sdk import Context
31
31
 
32
32
 
33
33
  class GoogleAdsToGcsOperator(BaseOperator):
@@ -18,23 +18,13 @@ from __future__ import annotations
18
18
 
19
19
  from typing import TYPE_CHECKING
20
20
 
21
+ from airflow.providers.common.compat.sdk import Asset
21
22
  from airflow.providers.google.cloud.hooks.gcs import _parse_gcs_url
22
- from airflow.providers.google.version_compat import AIRFLOW_V_3_0_PLUS
23
23
 
24
24
  if TYPE_CHECKING:
25
25
  from urllib.parse import SplitResult
26
26
 
27
- from airflow.providers.common.compat.assets import Asset
28
27
  from airflow.providers.common.compat.openlineage.facet import Dataset as OpenLineageDataset
29
- else:
30
- try:
31
- from airflow.providers.common.compat.assets import Asset
32
- except ImportError:
33
- if AIRFLOW_V_3_0_PLUS:
34
- from airflow.sdk.definitions.asset import Asset
35
- else:
36
- # dataset is renamed to asset since Airflow 3.0
37
- from airflow.datasets import Dataset as Asset
38
28
 
39
29
 
40
30
  def create_asset(*, bucket: str, key: str, extra: dict | None = None) -> Asset:
@@ -0,0 +1,16 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
@@ -0,0 +1,161 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+ from __future__ import annotations
18
+
19
+ import os
20
+ from pathlib import Path
21
+
22
+ import structlog
23
+ from google.api_core.exceptions import NotFound
24
+
25
+ from airflow.dag_processing.bundles.base import BaseDagBundle
26
+ from airflow.providers.common.compat.sdk import AirflowException
27
+ from airflow.providers.google.cloud.hooks.gcs import GCSHook
28
+ from airflow.providers.google.common.hooks.base_google import GoogleBaseHook
29
+
30
+
31
+ class GCSDagBundle(BaseDagBundle):
32
+ """
33
+ GCS Dag bundle - exposes a directory in GCS as a Dag bundle.
34
+
35
+ This allows Airflow to load Dags directly from a GCS bucket.
36
+
37
+ :param gcp_conn_id: Airflow connection ID for GCS. Defaults to GoogleBaseHook.default_conn_name.
38
+ :param bucket_name: The name of the GCS bucket containing the Dag files.
39
+ :param prefix: Optional subdirectory within the GCS bucket where the Dags are stored.
40
+ If None, Dags are assumed to be at the root of the bucket (Optional).
41
+ """
42
+
43
+ supports_versioning = False
44
+
45
+ def __init__(
46
+ self,
47
+ *,
48
+ gcp_conn_id: str = GoogleBaseHook.default_conn_name,
49
+ bucket_name: str,
50
+ prefix: str = "",
51
+ **kwargs,
52
+ ) -> None:
53
+ super().__init__(**kwargs)
54
+ self.gcp_conn_id = gcp_conn_id
55
+ self.bucket_name = bucket_name
56
+ self.prefix = prefix
57
+ # Local path where GCS Dags are downloaded
58
+ self.gcs_dags_dir: Path = self.base_dir
59
+
60
+ log = structlog.get_logger(__name__)
61
+ self._log = log.bind(
62
+ bundle_name=self.name,
63
+ version=self.version,
64
+ bucket_name=self.bucket_name,
65
+ prefix=self.prefix,
66
+ gcp_conn_id=self.gcp_conn_id,
67
+ )
68
+ self._gcs_hook: GCSHook | None = None
69
+
70
+ def _initialize(self):
71
+ with self.lock():
72
+ if not self.gcs_dags_dir.exists():
73
+ self._log.info("Creating local Dags directory: %s", self.gcs_dags_dir)
74
+ os.makedirs(self.gcs_dags_dir)
75
+
76
+ if not self.gcs_dags_dir.is_dir():
77
+ raise NotADirectoryError(f"Local Dags path: {self.gcs_dags_dir} is not a directory.")
78
+
79
+ try:
80
+ self.gcs_hook.get_bucket(bucket_name=self.bucket_name)
81
+ except NotFound:
82
+ raise ValueError(f"GCS bucket '{self.bucket_name}' does not exist.")
83
+
84
+ if self.prefix:
85
+ # don't check when prefix is ""
86
+ if not self.gcs_hook.list(bucket_name=self.bucket_name, prefix=self.prefix):
87
+ raise ValueError(f"GCS prefix 'gs://{self.bucket_name}/{self.prefix}' does not exist.")
88
+ self.refresh()
89
+
90
+ def initialize(self) -> None:
91
+ self._initialize()
92
+ super().initialize()
93
+
94
+ @property
95
+ def gcs_hook(self):
96
+ if self._gcs_hook is None:
97
+ try:
98
+ self._gcs_hook: GCSHook = GCSHook(gcp_conn_id=self.gcp_conn_id) # Initialize GCS hook.
99
+ except AirflowException as e:
100
+ self._log.warning("Could not create GCSHook for connection %s: %s", self.gcp_conn_id, e)
101
+ return self._gcs_hook
102
+
103
+ def __repr__(self):
104
+ return (
105
+ f"<GCSDagBundle("
106
+ f"name={self.name!r}, "
107
+ f"bucket_name={self.bucket_name!r}, "
108
+ f"prefix={self.prefix!r}, "
109
+ f"version={self.version!r}"
110
+ f")>"
111
+ )
112
+
113
+ def get_current_version(self) -> str | None:
114
+ """Return the current version of the Dag bundle. Currently not supported."""
115
+ return None
116
+
117
+ @property
118
+ def path(self) -> Path:
119
+ """Return the local path to the Dag files."""
120
+ return self.gcs_dags_dir # Path where Dags are downloaded.
121
+
122
+ def refresh(self) -> None:
123
+ """Refresh the Dag bundle by re-downloading the Dags from GCS."""
124
+ if self.version:
125
+ raise ValueError("Refreshing a specific version is not supported")
126
+
127
+ with self.lock():
128
+ self._log.debug(
129
+ "Downloading Dags from gs://%s/%s to %s", self.bucket_name, self.prefix, self.gcs_dags_dir
130
+ )
131
+ self.gcs_hook.sync_to_local_dir(
132
+ bucket_name=self.bucket_name,
133
+ prefix=self.prefix,
134
+ local_dir=self.gcs_dags_dir,
135
+ delete_stale=True,
136
+ )
137
+
138
+ def view_url(self, version: str | None = None) -> str | None:
139
+ """
140
+ Return a URL for viewing the Dags in GCS. Currently, versioning is not supported.
141
+
142
+ This method is deprecated and will be removed when the minimum supported Airflow version is 3.1.
143
+ Use `view_url_template` instead.
144
+ """
145
+ return self.view_url_template()
146
+
147
+ def view_url_template(self) -> str | None:
148
+ """Return a URL for viewing the Dags in GCS. Currently, versioning is not supported."""
149
+ if self.version:
150
+ raise ValueError("GCS url with version is not supported")
151
+ if hasattr(self, "_view_url_template") and self._view_url_template:
152
+ # Because we use this method in the view_url method, we need to handle
153
+ # backward compatibility for Airflow versions that doesn't have the
154
+ # _view_url_template attribute. Should be removed when we drop support for Airflow 3.0
155
+ return self._view_url_template
156
+ # https://console.cloud.google.com/storage/browser/<bucket-name>/<prefix>
157
+ url = f"https://console.cloud.google.com/storage/browser/{self.bucket_name}"
158
+ if self.prefix:
159
+ url += f"/{self.prefix}"
160
+
161
+ return url
@@ -27,7 +27,7 @@ import tenacity
27
27
  from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault
28
28
  from google.cloud import alloydb_v1
29
29
 
30
- from airflow.exceptions import AirflowException
30
+ from airflow.providers.common.compat.sdk import AirflowException
31
31
  from airflow.providers.google.common.consts import CLIENT_INFO
32
32
  from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook
33
33