From 7a2fef501840cf95cfbda4e8a4a2af269f6b09d4 Mon Sep 17 00:00:00 2001 From: Maksim Moiseenkov Date: Fri, 16 Aug 2024 14:59:21 +0000 Subject: [PATCH 1/2] Enforce deprecation message format with EOL for google provider package --- .pre-commit-config.yaml | 1 + .../providers/google/cloud/hooks/bigquery.py | 145 +++++++++++------- .../google/cloud/hooks/cloud_build.py | 3 +- .../providers/google/cloud/hooks/dataflow.py | 20 +-- .../google/cloud/hooks/datapipeline.py | 3 +- .../google/cloud/hooks/kubernetes_engine.py | 39 ++--- .../google/cloud/hooks/life_sciences.py | 10 +- .../cloud/hooks/vertex_ai/custom_job.py | 15 +- .../cloud/hooks/vertex_ai/generative_model.py | 32 ++-- .../providers/google/cloud/links/automl.py | 35 ++--- .../google/cloud/operators/bigquery.py | 6 +- .../google/cloud/operators/dataflow.py | 6 +- .../google/cloud/operators/datafusion.py | 3 +- .../google/cloud/operators/datapipeline.py | 8 +- .../google/cloud/operators/dataproc.py | 57 ++++--- .../cloud/operators/kubernetes_engine.py | 3 +- .../google/cloud/operators/life_sciences.py | 9 +- .../google/cloud/operators/mlengine.py | 106 +++++-------- .../cloud/operators/vertex_ai/auto_ml.py | 4 +- .../cloud/operators/vertex_ai/custom_job.py | 8 +- .../operators/vertex_ai/generative_model.py | 12 +- .../google/cloud/secrets/secret_manager.py | 6 +- .../google/cloud/sensors/bigquery.py | 17 +- .../google/cloud/sensors/cloud_composer.py | 9 +- airflow/providers/google/cloud/sensors/gcs.py | 6 +- .../google/common/hooks/base_google.py | 3 +- .../marketing_platform/hooks/analytics.py | 4 +- .../marketing_platform/operators/analytics.py | 36 ++--- scripts/ci/pre_commit/check_deprecations.py | 73 ++++++++- 29 files changed, 373 insertions(+), 306 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 60249525d3689..62627c52643b4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1035,6 +1035,7 @@ repos: pass_filenames: true files: ^airflow/.*\.py$ exclude: ^.*/.*_vendor/ + additional_dependencies: ["rich>=12.4.4", "python-dateutil"] - id: lint-chart-schema name: Lint chart/values.schema.json file entry: ./scripts/ci/pre_commit/chart_schema.py diff --git a/airflow/providers/google/cloud/hooks/bigquery.py b/airflow/providers/google/cloud/hooks/bigquery.py index 1e84eb3bd75fd..bbab4c25b94fa 100644 --- a/airflow/providers/google/cloud/hooks/bigquery.py +++ b/airflow/providers/google/cloud/hooks/bigquery.py @@ -175,10 +175,9 @@ def __init__( @cached_property @deprecated( - reason=( - "`BigQueryHook.credentials_path` property is deprecated and will be removed in the future. " - "This property used for obtaining credentials path but no longer in actual use. " - ), + reason="The credentials_path property is deprecated and will be removed after 01.11.2024. " + "There is no replacement because this property used for obtaining credentials path " + "but is no longer in actual use. ", category=AirflowProviderDeprecationWarning, ) def credentials_path(self) -> str: @@ -198,7 +197,8 @@ def get_conn(self) -> BigQueryConnection: ) @deprecated( - reason=("Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_client`"), + reason="The get_service method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_client method instead.", category=AirflowProviderDeprecationWarning, ) def get_service(self) -> Resource: @@ -604,10 +604,9 @@ def delete_dataset( ) @deprecated( - reason=( - "Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_table` " - "method with passing the `table_resource` object. This gives more flexibility than this method." - ), + reason="The create_external_table method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_table method " + "with passing the table_resource object instead. This gives more flexibility than this method.", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id @@ -806,9 +805,8 @@ def update_table( return table_object.to_api_repr() @deprecated( - reason=( - "Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_table` method." - ), + reason="The patch_table method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_table method instead.", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id @@ -1017,9 +1015,9 @@ def update_dataset( return dataset @deprecated( - reason=( - "Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_dataset` method." - ), + reason="The patch_dataset method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_dataset " + "method instead.", category=AirflowProviderDeprecationWarning, ) def patch_dataset( @@ -1065,9 +1063,9 @@ def patch_dataset( return dataset @deprecated( - reason=( - "Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables` method." - ), + reason="The get_dataset_tables_list method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables " + "method instead.", category=AirflowProviderDeprecationWarning, ) def get_dataset_tables_list( @@ -1271,9 +1269,8 @@ def run_table_upsert( return table @deprecated( - reason=( - "Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.delete_table` method." - ), + reason="The run_table_delete method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.delete_table method instead.", category=AirflowProviderDeprecationWarning, ) def run_table_delete(self, deletion_dataset_table: str, ignore_if_missing: bool = False) -> None: @@ -1320,7 +1317,8 @@ def delete_table( self.log.info("Deleted table %s", table_id) @deprecated( - reason=("Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.list_rows` method."), + reason="The get_tabledata method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.list_rows method instead.", category=AirflowProviderDeprecationWarning, ) def get_tabledata( @@ -1556,7 +1554,8 @@ def poll_job_complete( return job.done(retry=retry) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.cancel_job`", + reason="The cancel_query method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.cancel_job method instead.", category=AirflowProviderDeprecationWarning, ) def cancel_query(self) -> None: @@ -1709,7 +1708,8 @@ def insert_job( return job_api_repr @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job`", + reason="The run_with_configuration method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job method instead.", category=AirflowProviderDeprecationWarning, ) def run_with_configuration(self, configuration: dict) -> str: @@ -1730,7 +1730,8 @@ def run_with_configuration(self, configuration: dict) -> str: return job.job_id @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job`", + reason="The run_load method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job method instead.", category=AirflowProviderDeprecationWarning, ) def run_load( @@ -1971,7 +1972,8 @@ def run_load( return job.job_id @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job`", + reason="The run_copy method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job method instead.", category=AirflowProviderDeprecationWarning, ) def run_copy( @@ -2057,7 +2059,8 @@ def run_copy( return job.job_id @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job`", + reason="The run_extract method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job method instead.", category=AirflowProviderDeprecationWarning, ) def run_extract( @@ -2131,7 +2134,8 @@ def run_extract( return job.job_id @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job`", + reason="The run_query method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job method instead.", category=AirflowProviderDeprecationWarning, ) def run_query( @@ -2548,7 +2552,9 @@ def __init__( self.hook = hook @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_table`", + reason="The create_empty_table method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_table " + "method instead.", category=AirflowProviderDeprecationWarning, ) def create_empty_table(self, *args, **kwargs): @@ -2561,7 +2567,9 @@ def create_empty_table(self, *args, **kwargs): return self.hook.create_empty_table(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_dataset`", + reason="The create_empty_dataset method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_dataset " + "method instead.", category=AirflowProviderDeprecationWarning, ) def create_empty_dataset(self, *args, **kwargs) -> dict[str, Any]: @@ -2574,7 +2582,9 @@ def create_empty_dataset(self, *args, **kwargs) -> dict[str, Any]: return self.hook.create_empty_dataset(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables`", + reason="The get_dataset_tables method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables " + "method instead.", category=AirflowProviderDeprecationWarning, ) def get_dataset_tables(self, *args, **kwargs) -> list[dict[str, Any]]: @@ -2587,7 +2597,9 @@ def get_dataset_tables(self, *args, **kwargs) -> list[dict[str, Any]]: return self.hook.get_dataset_tables(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.delete_dataset`", + reason="The delete_dataset method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.delete_dataset " + "method instead.", category=AirflowProviderDeprecationWarning, ) def delete_dataset(self, *args, **kwargs) -> None: @@ -2600,7 +2612,9 @@ def delete_dataset(self, *args, **kwargs) -> None: return self.hook.delete_dataset(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_external_table`", + reason="The create_external_table method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_external_table " + "method instead.", category=AirflowProviderDeprecationWarning, ) def create_external_table(self, *args, **kwargs): @@ -2613,7 +2627,8 @@ def create_external_table(self, *args, **kwargs): return self.hook.create_external_table(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.patch_table`", + reason="The patch_table method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.patch_table method instead.", category=AirflowProviderDeprecationWarning, ) def patch_table(self, *args, **kwargs) -> None: @@ -2626,7 +2641,8 @@ def patch_table(self, *args, **kwargs) -> None: return self.hook.patch_table(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_all`", + reason="The insert_all method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_all method instead.", category=AirflowProviderDeprecationWarning, ) def insert_all(self, *args, **kwargs) -> None: @@ -2639,7 +2655,9 @@ def insert_all(self, *args, **kwargs) -> None: return self.hook.insert_all(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_dataset`", + reason="The update_dataset method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_dataset " + "method instead.", category=AirflowProviderDeprecationWarning, ) def update_dataset(self, *args, **kwargs) -> dict: @@ -2652,7 +2670,8 @@ def update_dataset(self, *args, **kwargs) -> dict: return Dataset.to_api_repr(self.hook.update_dataset(*args, **kwargs)) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.patch_dataset`", + reason="The patch_dataset method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.patch_dataset method instead.", category=AirflowProviderDeprecationWarning, ) def patch_dataset(self, *args, **kwargs) -> dict: @@ -2665,7 +2684,9 @@ def patch_dataset(self, *args, **kwargs) -> dict: return self.hook.patch_dataset(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables_list`", + reason="The get_dataset_tables_list method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables_list " + "method instead.", category=AirflowProviderDeprecationWarning, ) def get_dataset_tables_list(self, *args, **kwargs) -> list[dict[str, Any]]: @@ -2678,7 +2699,9 @@ def get_dataset_tables_list(self, *args, **kwargs) -> list[dict[str, Any]]: return self.hook.get_dataset_tables_list(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_datasets_list`", + reason="The get_datasets_list method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_datasets_list " + "method instead.", category=AirflowProviderDeprecationWarning, ) def get_datasets_list(self, *args, **kwargs) -> list | HTTPIterator: @@ -2691,7 +2714,8 @@ def get_datasets_list(self, *args, **kwargs) -> list | HTTPIterator: return self.hook.get_datasets_list(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset`", + reason="The get_dataset method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset method instead.", category=AirflowProviderDeprecationWarning, ) def get_dataset(self, *args, **kwargs) -> Dataset: @@ -2704,7 +2728,9 @@ def get_dataset(self, *args, **kwargs) -> Dataset: return self.hook.get_dataset(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_grant_dataset_view_access`", + reason="The run_grant_dataset_view_access method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_grant_dataset_view_access " + "method instead.", category=AirflowProviderDeprecationWarning, ) def run_grant_dataset_view_access(self, *args, **kwargs) -> dict: @@ -2718,7 +2744,9 @@ def run_grant_dataset_view_access(self, *args, **kwargs) -> dict: return self.hook.run_grant_dataset_view_access(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_table_upsert`", + reason="The run_table_upsert method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_table_upsert " + "method instead.", category=AirflowProviderDeprecationWarning, ) def run_table_upsert(self, *args, **kwargs) -> dict: @@ -2731,7 +2759,9 @@ def run_table_upsert(self, *args, **kwargs) -> dict: return self.hook.run_table_upsert(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_table_delete`", + reason="The run_table_delete method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_table_delete " + "method instead.", category=AirflowProviderDeprecationWarning, ) def run_table_delete(self, *args, **kwargs) -> None: @@ -2744,7 +2774,8 @@ def run_table_delete(self, *args, **kwargs) -> None: return self.hook.run_table_delete(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_tabledata`", + reason="The get_tabledata method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_tabledata method instead.", category=AirflowProviderDeprecationWarning, ) def get_tabledata(self, *args, **kwargs) -> list[dict]: @@ -2757,7 +2788,8 @@ def get_tabledata(self, *args, **kwargs) -> list[dict]: return self.hook.get_tabledata(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_schema`", + reason="The get_schema method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_schema method instead.", category=AirflowProviderDeprecationWarning, ) def get_schema(self, *args, **kwargs) -> dict: @@ -2770,7 +2802,9 @@ def get_schema(self, *args, **kwargs) -> dict: return self.hook.get_schema(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.poll_job_complete`", + reason="The poll_job_complete method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.poll_job_complete " + "method instead", category=AirflowProviderDeprecationWarning, ) def poll_job_complete(self, *args, **kwargs) -> bool: @@ -2783,7 +2817,8 @@ def poll_job_complete(self, *args, **kwargs) -> bool: return self.hook.poll_job_complete(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.cancel_query`", + reason="The cancel_query method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.cancel_query method instead.", category=AirflowProviderDeprecationWarning, ) def cancel_query(self, *args, **kwargs) -> None: @@ -2796,7 +2831,9 @@ def cancel_query(self, *args, **kwargs) -> None: return self.hook.cancel_query(*args, **kwargs) # type: ignore @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_with_configuration`", + reason="The run_with_configuration method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_with_configuration " + "method instead", category=AirflowProviderDeprecationWarning, ) def run_with_configuration(self, *args, **kwargs) -> str: @@ -2809,7 +2846,8 @@ def run_with_configuration(self, *args, **kwargs) -> str: return self.hook.run_with_configuration(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_load`", + reason="The run_load method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_load method instead.", category=AirflowProviderDeprecationWarning, ) def run_load(self, *args, **kwargs) -> str: @@ -2822,7 +2860,8 @@ def run_load(self, *args, **kwargs) -> str: return self.hook.run_load(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_copy`", + reason="The run_copy method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_copy method instead", category=AirflowProviderDeprecationWarning, ) def run_copy(self, *args, **kwargs) -> str: @@ -2835,7 +2874,8 @@ def run_copy(self, *args, **kwargs) -> str: return self.hook.run_copy(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_extract`", + reason="The run_extract method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_extract method instead", category=AirflowProviderDeprecationWarning, ) def run_extract(self, *args, **kwargs) -> str | BigQueryJob: @@ -2848,7 +2888,8 @@ def run_extract(self, *args, **kwargs) -> str | BigQueryJob: return self.hook.run_extract(*args, **kwargs) @deprecated( - reason="Please use `airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_query`", + reason="The run_query method is deprecated and will be removed after 01.11.2024. " + "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_query instead.", category=AirflowProviderDeprecationWarning, ) def run_query(self, *args, **kwargs) -> str: diff --git a/airflow/providers/google/cloud/hooks/cloud_build.py b/airflow/providers/google/cloud/hooks/cloud_build.py index 2d6358a201aa7..feddae3b45784 100644 --- a/airflow/providers/google/cloud/hooks/cloud_build.py +++ b/airflow/providers/google/cloud/hooks/cloud_build.py @@ -191,7 +191,8 @@ def create_build_without_waiting_for_result( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="Please use `create_build_without_waiting_for_result`", + reason="The create_build method is deprecated and will be removed after 01.03.2025. " + "Please use create_build_without_waiting_for_result method instead.", category=AirflowProviderDeprecationWarning, ) def create_build( diff --git a/airflow/providers/google/cloud/hooks/dataflow.py b/airflow/providers/google/cloud/hooks/dataflow.py index 7f684cb61740f..1554fd4b6f776 100644 --- a/airflow/providers/google/cloud/hooks/dataflow.py +++ b/airflow/providers/google/cloud/hooks/dataflow.py @@ -594,12 +594,10 @@ def get_pipelines_conn(self) -> build: @_fallback_to_project_id_from_variables @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason=( - "This method is deprecated. " - "Please use `airflow.providers.apache.beam.hooks.beam.start.start_java_pipeline` " - "to start pipeline and `providers.google.cloud.hooks.dataflow.DataflowHook.wait_for_done` " - "to wait for the required pipeline state." - ), + reason="The start_java_dataflow method is deprecated and will be removed after 01.03.2025. " + "Please use airflow.providers.apache.beam.hooks.beam.start.start_java_pipeline method " + "to start pipeline and providers.google.cloud.hooks.dataflow.DataflowHook.wait_for_done method " + "to wait for the required pipeline state instead.", category=AirflowProviderDeprecationWarning, ) def start_java_dataflow( @@ -951,12 +949,10 @@ def extract_job_id(job: dict) -> str: @_fallback_to_project_id_from_variables @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason=( - "This method is deprecated. " - "Please use `airflow.providers.apache.beam.hooks.beam.start.start_python_pipeline` " - "to start pipeline and `providers.google.cloud.hooks.dataflow.DataflowHook.wait_for_done` " - "to wait for the required pipeline state." - ), + reason="The start_python_dataflow method is deprecated and will be removed after 01.03.2025. " + "Please use airflow.providers.apache.beam.hooks.beam.start.start_python_pipeline method " + "to start pipeline and providers.google.cloud.hooks.dataflow.DataflowHook.wait_for_done method " + "to wait for the required pipeline state instead.", category=AirflowProviderDeprecationWarning, ) def start_python_dataflow( diff --git a/airflow/providers/google/cloud/hooks/datapipeline.py b/airflow/providers/google/cloud/hooks/datapipeline.py index 0dbc2825d107c..44c059e8d6c92 100644 --- a/airflow/providers/google/cloud/hooks/datapipeline.py +++ b/airflow/providers/google/cloud/hooks/datapipeline.py @@ -34,7 +34,8 @@ @deprecated( - reason="This hook is deprecated and will be removed after 01.12.2024. Please use `DataflowHook`.", + reason="The DataPipelineHook is deprecated and will be removed after 01.12.2024. " + "Please use DataflowHook instead.", category=AirflowProviderDeprecationWarning, ) class DataPipelineHook(DataflowHook): diff --git a/airflow/providers/google/cloud/hooks/kubernetes_engine.py b/airflow/providers/google/cloud/hooks/kubernetes_engine.py index 7fc2e3184925f..d6bfff4fbec08 100644 --- a/airflow/providers/google/cloud/hooks/kubernetes_engine.py +++ b/airflow/providers/google/cloud/hooks/kubernetes_engine.py @@ -139,10 +139,8 @@ def get_cluster_manager_client(self) -> ClusterManagerClient: # To preserve backward compatibility # TODO: remove one day @deprecated( - reason=( - "The get_conn method has been deprecated. " - "You should use the get_cluster_manager_client method." - ), + reason="The get_conn method is deprecated and will be removed after 01.11.2024. " + "Please use the get_cluster_manager_client method instead.", category=AirflowProviderDeprecationWarning, ) def get_conn(self) -> container_v1.ClusterManagerClient: @@ -151,7 +149,8 @@ def get_conn(self) -> container_v1.ClusterManagerClient: # To preserve backward compatibility # TODO: remove one day @deprecated( - reason="The get_client method has been deprecated. You should use the get_conn method.", + reason="The get_client method is deprecated and will be removed after 01.11.2024. " + "Please use the get_conn method instead.", category=AirflowProviderDeprecationWarning, ) def get_client(self) -> ClusterManagerClient: @@ -580,10 +579,8 @@ def _get_config(self) -> async_client.configuration.Configuration: @deprecated( - reason=( - "The `GKEDeploymentHook` class is deprecated and will be removed after 01.10.2024, please use " - "`GKEKubernetesHook` instead." - ), + reason="The GKEDeploymentHook class is deprecated and will be removed after 01.10.2024. " + "Please use GKEKubernetesHook instead.", category=AirflowProviderDeprecationWarning, ) class GKEDeploymentHook(GKEKubernetesHook): @@ -591,10 +588,8 @@ class GKEDeploymentHook(GKEKubernetesHook): @deprecated( - reason=( - "The `GKECustomResourceHook` class is deprecated and will be removed after 01.10.2024, please use " - "`GKEKubernetesHook` instead." - ), + reason="The GKECustomResourceHook class is deprecated and will be removed after 01.10.2024. " + "Please use GKEKubernetesHook instead.", category=AirflowProviderDeprecationWarning, ) class GKECustomResourceHook(GKEKubernetesHook): @@ -602,10 +597,8 @@ class GKECustomResourceHook(GKEKubernetesHook): @deprecated( - reason=( - "The `GKEPodHook` class is deprecated and will be removed after 01.10.2024, please use " - "`GKEKubernetesHook` instead." - ), + reason="The GKEPodHook class is deprecated and will be removed after 01.10.2024. " + "Please use GKEKubernetesHook instead.", category=AirflowProviderDeprecationWarning, ) class GKEPodHook(GKEKubernetesHook): @@ -631,10 +624,8 @@ def __init__( @deprecated( - reason=( - "The `GKEJobHook` class is deprecated and will be removed after 01.10.2024, please use " - "`GKEKubernetesHook` instead." - ), + reason="The GKEJobHook class is deprecated and will be removed after 01.10.2024. " + "Please use GKEKubernetesHook instead.", category=AirflowProviderDeprecationWarning, ) class GKEJobHook(GKEKubernetesHook): @@ -642,10 +633,8 @@ class GKEJobHook(GKEKubernetesHook): @deprecated( - reason=( - "The `GKEPodAsyncHook` class is deprecated and will be removed after 01.10.2024, please use " - "`GKEKubernetesAsyncHook` instead." - ), + reason="The GKEPodAsyncHook class is deprecated and will be removed after 01.10.2024. " + "Please use GKEKubernetesAsyncHook instead.", category=AirflowProviderDeprecationWarning, ) class GKEPodAsyncHook(GKEKubernetesAsyncHook): diff --git a/airflow/providers/google/cloud/hooks/life_sciences.py b/airflow/providers/google/cloud/hooks/life_sciences.py index b4fa0de9562e3..a1c48464ddcd3 100644 --- a/airflow/providers/google/cloud/hooks/life_sciences.py +++ b/airflow/providers/google/cloud/hooks/life_sciences.py @@ -34,12 +34,10 @@ @deprecated( - reason=( - "This hook is deprecated. Consider using " - "Google Cloud Batch Operators' hook instead. " - "The Life Sciences API (beta) will be discontinued " - "on July 8, 2025 in favor of Google Cloud Batch." - ), + reason="The LifeSciencesHook is deprecated and will be removed after 08.07.2024. " + "Please use Google Cloud Batch Operators' hook instead. " + "The Life Sciences API (beta) will be discontinued " + "on July 8, 2025 in favor of Google Cloud Batch.", category=AirflowProviderDeprecationWarning, ) class LifeSciencesHook(GoogleBaseHook): diff --git a/airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py b/airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py index 3a431d01922c6..56226b6fcf9b9 100644 --- a/airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py +++ b/airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py @@ -380,7 +380,8 @@ def _run_job( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="Please use `PipelineJobHook.cancel_pipeline_job`", + reason="The cancel_pipeline_job method is deprecated and will be removed after 01.03.2025. " + "Please use PipelineJobHook.cancel_pipeline_job method instead.", category=AirflowProviderDeprecationWarning, ) def cancel_pipeline_job( @@ -509,7 +510,8 @@ def cancel_custom_job( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="Please use `PipelineJobHook.create_pipeline_job`", + reason="The create_pipeline_job method is deprecated and will be removed after 01.03.2025. " + "Please use PipelineJobHook.create_pipeline_job method instead.", category=AirflowProviderDeprecationWarning, ) def create_pipeline_job( @@ -2980,7 +2982,8 @@ def delete_custom_job( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="Please use `PipelineJobHook.get_pipeline_job`", + reason="The get_pipeline_job method is deprecated and will be removed after 01.03.2025. " + "Please use PipelineJobHook.get_pipeline_job method instead.", category=AirflowProviderDeprecationWarning, ) def get_pipeline_job( @@ -3085,7 +3088,8 @@ def get_custom_job( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="Please use `PipelineJobHook.list_pipeline_jobs`", + reason="The list_pipeline_jobs method is deprecated and will be removed after 01.03.2025. " + "Please use PipelineJobHook.list_pipeline_jobs method instead", category=AirflowProviderDeprecationWarning, ) def list_pipeline_jobs( @@ -3301,7 +3305,8 @@ def list_custom_jobs( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="Please use `PipelineJobHook.delete_pipeline_job`", + reason="The delete_pipeline_job method is deprecated and will be removed after 01.03.2025. " + "Please use PipelineJobHook.delete_pipeline_job method instead", category=AirflowProviderDeprecationWarning, ) def delete_pipeline_job( diff --git a/airflow/providers/google/cloud/hooks/vertex_ai/generative_model.py b/airflow/providers/google/cloud/hooks/vertex_ai/generative_model.py index 13c6ebe81fd5f..f571f5585cb08 100644 --- a/airflow/providers/google/cloud/hooks/vertex_ai/generative_model.py +++ b/airflow/providers/google/cloud/hooks/vertex_ai/generative_model.py @@ -67,9 +67,10 @@ def get_generative_model(self, pretrained_model: str) -> GenerativeModel: return model @deprecated( - reason=( - "The `get_generative_model_part` method is deprecated and will be removed after 01.01.2025, please include `Part` objects in `contents` parameter of `airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.generative_model_generate_content`" - ), + reason="The get_generative_model_part method is deprecated and will be removed after 01.01.2025. " + "Please use Part objects included in contents parameter of " + "airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.generative_model_generate_content " + "instead", category=AirflowProviderDeprecationWarning, ) def get_generative_model_part(self, content_gcs_path: str, content_mime_type: str | None = None) -> Part: @@ -78,9 +79,9 @@ def get_generative_model_part(self, content_gcs_path: str, content_mime_type: st return part @deprecated( - reason=( - "The `prompt_language_model` method is deprecated and will be removed after 01.01.2025, please use `airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.text_generation_model_predict` method." - ), + reason="The prompt_language_model method is deprecated and will be removed after 01.01.2025. " + "Please use airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.text_generation_model_predict " + "method instead.", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id @@ -132,9 +133,9 @@ def prompt_language_model( return response.text @deprecated( - reason=( - "The `generate_text_embeddings` method is deprecated and will be removed after 01.01.2025, please use `airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.text_embedding_model_get_embeddings` method." - ), + reason="The generate_text_embeddings method is deprecated and will be removed after 01.01.2025. " + "Please use airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.text_embedding_model_get_embeddings " + "method instead.", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id @@ -162,9 +163,9 @@ def generate_text_embeddings( return response.values @deprecated( - reason=( - "The `prompt_multimodal_model` method is deprecated and will be removed after 01.01.2025, please use `airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.generative_model_generate_content` method." - ), + reason="The prompt_multimodal_model method is deprecated and will be removed after 01.01.2025. " + "Please use airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.generative_model_generate_content " + "method instead.", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id @@ -201,9 +202,10 @@ def prompt_multimodal_model( return response.text @deprecated( - reason=( - "The `prompt_multimodal_model_with_media` method is deprecated and will be removed after 01.01.2025, please use `airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.generative_model_generate_content` method." - ), + reason="The prompt_multimodal_model_with_media method is deprecated " + "and will be removed after 01.01.2025. Please use " + "airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.generative_model_generate_content " + "method instead.", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id diff --git a/airflow/providers/google/cloud/links/automl.py b/airflow/providers/google/cloud/links/automl.py index 3e62a1db30b73..61e568dc79d30 100644 --- a/airflow/providers/google/cloud/links/automl.py +++ b/airflow/providers/google/cloud/links/automl.py @@ -48,10 +48,9 @@ @deprecated( - reason=( - "Class `AutoMLDatasetLink` has been deprecated and will be removed after 31.12.2024. " - "Please use `TranslationLegacyDatasetLink` from `airflow/providers/google/cloud/links/translate.py` instead." - ), + reason="The AutoMLDatasetLink class is deprecated and will be removed after 31.12.2024. " + "Please use TranslationLegacyDatasetLink class from " + "airflow/providers/google/cloud/links/translate.py instead.", category=AirflowProviderDeprecationWarning, ) class AutoMLDatasetLink(BaseGoogleLink): @@ -76,10 +75,9 @@ def persist( @deprecated( - reason=( - "Class `AutoMLDatasetListLink` has been deprecated and will be removed after 31.12.2024. " - "Please use `TranslationDatasetListLink` from `airflow/providers/google/cloud/links/translate.py` instead." - ), + reason="The AutoMLDatasetListLink class is deprecated and will be removed after 31.12.2024. " + "Please use TranslationDatasetListLink class from " + "airflow/providers/google/cloud/links/translate.py instead.", category=AirflowProviderDeprecationWarning, ) class AutoMLDatasetListLink(BaseGoogleLink): @@ -105,10 +103,9 @@ def persist( @deprecated( - reason=( - "Class `AutoMLModelLink` has been deprecated and will be removed after 31.12.2024. " - "Please use `TranslationLegacyModelLink` from `airflow/providers/google/cloud/links/translate.py` instead." - ), + reason="The AutoMLModelLink class is deprecated and will be removed after 31.12.2024. " + "Please use TranslationLegacyModelLink class from " + "airflow/providers/google/cloud/links/translate.py instead.", category=AirflowProviderDeprecationWarning, ) class AutoMLModelLink(BaseGoogleLink): @@ -139,10 +136,9 @@ def persist( @deprecated( - reason=( - "Class `AutoMLModelTrainLink` has been deprecated and will be removed after 31.12.2024. " - "Please use `TranslationLegacyModelTrainLink` from `airflow/providers/google/cloud/links/translate.py` instead." - ), + reason="The AutoMLModelTrainLink class is deprecated and will be removed after 31.12.2024. " + "Please use TranslationLegacyModelTrainLink class from " + "airflow/providers/google/cloud/links/translate.py instead.", category=AirflowProviderDeprecationWarning, ) class AutoMLModelTrainLink(BaseGoogleLink): @@ -170,10 +166,9 @@ def persist( @deprecated( - reason=( - "Class `AutoMLModelPredictLink` has been deprecated and will be removed after 31.12.2024. " - "Please use `TranslationLegacyModelPredictLink` from `airflow/providers/google/cloud/links/translate.py` instead." - ), + reason="The AutoMLModelPredictLink class is deprecated and will be removed after 31.12.2024. " + "Please use TranslationLegacyModelPredictLink class from " + "airflow/providers/google/cloud/links/translate.py instead.", category=AirflowProviderDeprecationWarning, ) class AutoMLModelPredictLink(BaseGoogleLink): diff --git a/airflow/providers/google/cloud/operators/bigquery.py b/airflow/providers/google/cloud/operators/bigquery.py index d55651d06b437..83a9a19229228 100644 --- a/airflow/providers/google/cloud/operators/bigquery.py +++ b/airflow/providers/google/cloud/operators/bigquery.py @@ -1203,7 +1203,8 @@ def execute_complete(self, context: Context, event: dict[str, Any]) -> Any: @deprecated( - reason="This operator is deprecated. Please use `BigQueryInsertJobOperator`.", + reason="The BigQueryExecuteQueryOperator is deprecated and will be removed after 01.11.2024. " + "Please use BigQueryInsertJobOperator instead.", category=AirflowProviderDeprecationWarning, ) class BigQueryExecuteQueryOperator(GoogleCloudBaseOperator): @@ -2298,7 +2299,8 @@ def execute(self, context: Context): @deprecated( - reason="This operator is deprecated. Please use BigQueryUpdateDatasetOperator.", + reason="The BigQueryPatchDatasetOperator is deprecated and will be removed after 01.11.2024. " + "Please use BigQueryUpdateDatasetOperator instead.", category=AirflowProviderDeprecationWarning, ) class BigQueryPatchDatasetOperator(GoogleCloudBaseOperator): diff --git a/airflow/providers/google/cloud/operators/dataflow.py b/airflow/providers/google/cloud/operators/dataflow.py index 7fed34a8bb32c..c2acebddcbc9e 100644 --- a/airflow/providers/google/cloud/operators/dataflow.py +++ b/airflow/providers/google/cloud/operators/dataflow.py @@ -174,7 +174,8 @@ def __init__( # TODO: Remove one day @deprecated( - reason="Please use `providers.apache.beam.operators.beam.BeamRunJavaPipelineOperator` instead.", + reason="The DataflowCreateJavaJobOperator class is deprecated and will be removed after 01.11.2024. " + "Please use providers.apache.beam.operators.beam.BeamRunJavaPipelineOperator class instead.", category=AirflowProviderDeprecationWarning, ) class DataflowCreateJavaJobOperator(GoogleCloudBaseOperator): @@ -1052,7 +1053,8 @@ def on_kill(self) -> None: # TODO: Remove one day @deprecated( - reason="Please use `providers.apache.beam.operators.beam.BeamRunPythonPipelineOperator` instead.", + reason="The DataflowCreatePythonJobOperator class is deprecated and will be removed after 01.11.2024. " + "Please use providers.apache.beam.operators.beam.BeamRunPythonPipelineOperator class instead.", category=AirflowProviderDeprecationWarning, ) class DataflowCreatePythonJobOperator(GoogleCloudBaseOperator): diff --git a/airflow/providers/google/cloud/operators/datafusion.py b/airflow/providers/google/cloud/operators/datafusion.py index 6b27037075246..01c70dfc0a6aa 100644 --- a/airflow/providers/google/cloud/operators/datafusion.py +++ b/airflow/providers/google/cloud/operators/datafusion.py @@ -53,7 +53,8 @@ class DataFusionPipelineLinkHelper: @staticmethod @deprecated( - reason="Please use `airflow.providers.google.cloud.utils.helpers.resource_path_to_dict` instead.", + reason="The get_project_id method is deprecated and will be removed after 01.03.2025. " + "Please use airflow.providers.google.cloud.utils.helpers.resource_path_to_dict method instead.", category=AirflowProviderDeprecationWarning, ) def get_project_id(instance): diff --git a/airflow/providers/google/cloud/operators/datapipeline.py b/airflow/providers/google/cloud/operators/datapipeline.py index ebe92f648ab28..863e064eb12fd 100644 --- a/airflow/providers/google/cloud/operators/datapipeline.py +++ b/airflow/providers/google/cloud/operators/datapipeline.py @@ -31,8 +31,8 @@ @deprecated( - reason="This operator is deprecated and will be removed after 01.12.2024. " - "Please use `DataflowCreatePipelineOperator`.", + reason="The CreateDataPipelineOperator is deprecated and will be removed after 01.12.2024. " + "Please use DataflowCreatePipelineOperator class instead.", category=AirflowProviderDeprecationWarning, ) class CreateDataPipelineOperator(DataflowCreatePipelineOperator): @@ -40,8 +40,8 @@ class CreateDataPipelineOperator(DataflowCreatePipelineOperator): @deprecated( - reason="This operator is deprecated and will be removed after 01.12.2024. " - "Please use `DataflowRunPipelineOperator`.", + reason="The RunDataPipelineOperator is deprecated and will be removed after 01.12.2024. " + "Please use DataflowRunPipelineOperator class instead.", category=AirflowProviderDeprecationWarning, ) class RunDataPipelineOperator(DataflowRunPipelineOperator): diff --git a/airflow/providers/google/cloud/operators/dataproc.py b/airflow/providers/google/cloud/operators/dataproc.py index 2384bfbd6251a..c164197fbe0e0 100644 --- a/airflow/providers/google/cloud/operators/dataproc.py +++ b/airflow/providers/google/cloud/operators/dataproc.py @@ -882,7 +882,8 @@ def execute_complete(self, context: Context, event: dict[str, Any]) -> Any: # TODO: Remove one day @deprecated( - reason="Please use `DataprocUpdateClusterOperator` instead.", + reason="The DataprocScaleClusterOperator is deprecated and will be removed after 01.03.2025. " + "Please use DataprocUpdateClusterOperator class instead.", category=AirflowProviderDeprecationWarning, ) class DataprocScaleClusterOperator(GoogleCloudBaseOperator): @@ -1505,11 +1506,10 @@ def on_kill(self) -> None: # TODO: Remove one day @deprecated( - reason=( - "Please use `DataprocSubmitJobOperator` instead. " - "You can use `generate_job` method to generate dictionary representing your job " - "and use it with the new operator." - ), + reason="The DataprocSubmitPigJobOperator is deprecated and will be removed after 01.11.2024. " + "Please use DataprocSubmitJobOperator class instead. " + "You can use `generate_job` method to generate dictionary representing your job " + "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) class DataprocSubmitPigJobOperator(DataprocJobBaseOperator): @@ -1632,11 +1632,10 @@ def execute(self, context: Context): # TODO: Remove one day @deprecated( - reason=( - "Please use `DataprocSubmitJobOperator` instead. " - "You can use `generate_job` method to generate dictionary representing your job " - "and use it with the new operator." - ), + reason="The DataprocSubmitHiveJobOperator is deprecated and will be removed after 01.11.2024. " + "Please use DataprocSubmitJobOperator class instead. " + "You can use `generate_job` method to generate dictionary representing your job " + "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) class DataprocSubmitHiveJobOperator(DataprocJobBaseOperator): @@ -1725,11 +1724,10 @@ def execute(self, context: Context): # TODO: Remove one day @deprecated( - reason=( - "Please use `DataprocSubmitJobOperator` instead. " - "You can use `generate_job` method to generate dictionary representing your job " - "and use it with the new operator." - ), + reason="The DataprocSubmitSparkSqlJobOperator is deprecated and will be removed after 01.11.2024. " + "Please use DataprocSubmitJobOperator class instead. " + "You can use `generate_job` method to generate dictionary representing your job " + "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) class DataprocSubmitSparkSqlJobOperator(DataprocJobBaseOperator): @@ -1817,11 +1815,10 @@ def execute(self, context: Context): # TODO: Remove one day @deprecated( - reason=( - "Please use `DataprocSubmitJobOperator` instead. " - "You can use `generate_job` method to generate dictionary representing your job " - "and use it with the new operator." - ), + reason="The DataprocSubmitSparkJobOperator is deprecated and will be removed after 01.11.2024. " + "Please use DataprocSubmitJobOperator class instead. " + "You can use `generate_job` method to generate dictionary representing your job " + "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) class DataprocSubmitSparkJobOperator(DataprocJobBaseOperator): @@ -1909,11 +1906,10 @@ def execute(self, context: Context): # TODO: Remove one day @deprecated( - reason=( - "Please use `DataprocSubmitJobOperator` instead. " - "You can use `generate_job` method to generate dictionary representing your job " - "and use it with the new operator." - ), + reason="The DataprocSubmitHadoopJobOperator is deprecated and will be removed after 01.11.2024. " + "Please use DataprocSubmitJobOperator class instead. " + "You can use `generate_job` method to generate dictionary representing your job " + "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) class DataprocSubmitHadoopJobOperator(DataprocJobBaseOperator): @@ -2001,11 +1997,10 @@ def execute(self, context: Context): # TODO: Remove one day @deprecated( - reason=( - "Please use `DataprocSubmitJobOperator` instead. " - "You can use `generate_job` method to generate dictionary representing your job " - "and use it with the new operator." - ), + reason="The DataprocSubmitPySparkJobOperator is deprecated and will be removed after 01.11.2024. " + "Please use DataprocSubmitJobOperator class instead. " + "You can use `generate_job` method to generate dictionary representing your job " + "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) class DataprocSubmitPySparkJobOperator(DataprocJobBaseOperator): diff --git a/airflow/providers/google/cloud/operators/kubernetes_engine.py b/airflow/providers/google/cloud/operators/kubernetes_engine.py index e4715ded3343e..2174755ec64e2 100644 --- a/airflow/providers/google/cloud/operators/kubernetes_engine.py +++ b/airflow/providers/google/cloud/operators/kubernetes_engine.py @@ -725,7 +725,8 @@ def __init__( @staticmethod @deprecated( - reason="Please use `fetch_cluster_info` instead to get the cluster info for connecting to it.", + reason="The get_gke_config_file method is deprecated and will be removed after 01.11.2024. " + "Please use `fetch_cluster_info` instead to get the cluster info for connecting to it.", category=AirflowProviderDeprecationWarning, ) def get_gke_config_file(): diff --git a/airflow/providers/google/cloud/operators/life_sciences.py b/airflow/providers/google/cloud/operators/life_sciences.py index 253f9bbf98c2e..e815e56675feb 100644 --- a/airflow/providers/google/cloud/operators/life_sciences.py +++ b/airflow/providers/google/cloud/operators/life_sciences.py @@ -34,11 +34,10 @@ @deprecated( - reason=( - "Consider using Google Cloud Batch Operators instead." - "The Life Sciences API (beta) will be discontinued " - "on July 8, 2025 in favor of Google Cloud Batch." - ), + reason="The LifeSciencesRunPipelineOperator class is deprecated and will be removed after 08.07.2025. " + "Please use Google Cloud Batch Operators instead. " + "The Life Sciences API (beta) will be discontinued " + "on July 8, 2025 in favor of Google Cloud Batch.", category=AirflowProviderDeprecationWarning, ) class LifeSciencesRunPipelineOperator(GoogleCloudBaseOperator): diff --git a/airflow/providers/google/cloud/operators/mlengine.py b/airflow/providers/google/cloud/operators/mlengine.py index 5798653ed411a..2adacee71c220 100644 --- a/airflow/providers/google/cloud/operators/mlengine.py +++ b/airflow/providers/google/cloud/operators/mlengine.py @@ -80,11 +80,9 @@ def _normalize_mlengine_job_id(job_id: str) -> str: @deprecated( - reason=( - "This operator is deprecated. All the functionality of legacy " - "MLEngine and new features are available on the Vertex AI platform. " - "Please use `CreateBatchPredictionJobOperator`" - ), + reason="The MLEngineStartBatchPredictionJobOperator is deprecated and will be removed after 01.03.2025. " + "Please use CreateBatchPredictionJobOperator class instead." + "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", category=AirflowProviderDeprecationWarning, ) class MLEngineStartBatchPredictionJobOperator(GoogleCloudBaseOperator): @@ -297,10 +295,9 @@ def check_existing_job(existing_job): @deprecated( - reason=( - "This operator is deprecated. Consider using operators for specific operations: " - "MLEngineCreateModelOperator, MLEngineGetModelOperator." - ), + reason="The MLEngineManageModelOperator is deprecated and will be removed after 01.03.2025. " + "Please use one of the following operators for specific operations: " + "MLEngineCreateModelOperator, MLEngineGetModelOperator.", category=AirflowProviderDeprecationWarning, ) class MLEngineManageModelOperator(GoogleCloudBaseOperator): @@ -372,11 +369,9 @@ def execute(self, context: Context): @deprecated( - reason=( - "This operator is deprecated. All the functionality of legacy " - "MLEngine and new features are available on the Vertex AI platform. " - "Please use appropriate VertexAI operator." - ), + reason="The MLEngineCreateModelOperator is deprecated and will be removed after 01.11.2025. " + "Please use appropriate VertexAI operator instead. " + "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", category=AirflowProviderDeprecationWarning, ) class MLEngineCreateModelOperator(GoogleCloudBaseOperator): @@ -448,11 +443,9 @@ def execute(self, context: Context): @deprecated( - reason=( - "This operator is deprecated. All the functionality of legacy " - "MLEngine and new features are available on the Vertex AI platform. " - "Please use `GetModelOperator`" - ), + reason="The MLEngineGetModelOperator is deprecated and will be removed after 01.03.2025. " + "Please use GetModelOperator class instead. " + "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", category=AirflowProviderDeprecationWarning, ) class MLEngineGetModelOperator(GoogleCloudBaseOperator): @@ -523,11 +516,9 @@ def execute(self, context: Context): @deprecated( - reason=( - "This operator is deprecated. All the functionality of legacy " - "MLEngine and new features are available on the Vertex AI platform. " - "Please use `DeleteModelOperator`" - ), + reason="The MLEngineDeleteModelOperator is deprecated and will be removed after 01.03.2025. " + "Please use DeleteModelOperator class instead. " + "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", category=AirflowProviderDeprecationWarning, ) class MLEngineDeleteModelOperator(GoogleCloudBaseOperator): @@ -606,11 +597,9 @@ def execute(self, context: Context): @deprecated( - reason=( - "This operator is deprecated. Consider using operators for specific operations: " - "MLEngineCreateVersion, MLEngineSetDefaultVersion, " - "MLEngineListVersions, MLEngineDeleteVersion." - ), + reason="The MLEngineManageVersionOperator is deprecated and will be removed after 01.03.2025. " + "Please use the following operators instead: " + "MLEngineCreateVersion, MLEngineSetDefaultVersion, MLEngineListVersions, MLEngineDeleteVersion.", category=AirflowProviderDeprecationWarning, ) class MLEngineManageVersionOperator(GoogleCloudBaseOperator): @@ -725,11 +714,9 @@ def execute(self, context: Context): @deprecated( - reason=( - "This operator is deprecated. All the functionality of legacy " - "MLEngine and new features are available on the Vertex AI platform. " - "Please use parent_model parameter for VertexAI operators instead." - ), + reason="The MLEngineCreateVersionOperator is deprecated and will be removed after 01.03.2025. " + "Please use parent_model parameter for VertexAI operators instead. " + "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", category=AirflowProviderDeprecationWarning, ) class MLEngineCreateVersionOperator(GoogleCloudBaseOperator): @@ -816,11 +803,9 @@ def execute(self, context: Context): @deprecated( - reason=( - "This operator is deprecated. All the functionality of legacy " - "MLEngine and new features are available on the Vertex AI platform. " - "Please use `SetDefaultVersionOnModelOperator`" - ), + reason="The MLEngineSetDefaultVersionOperator is deprecated and will be removed after 01.03.2025. " + "Please use SetDefaultVersionOnModelOperator class instead. " + "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", category=AirflowProviderDeprecationWarning, ) class MLEngineSetDefaultVersionOperator(GoogleCloudBaseOperator): @@ -909,11 +894,9 @@ def execute(self, context: Context): @deprecated( - reason=( - "This operator is deprecated. All the functionality of legacy " - "MLEngine and new features are available on the Vertex AI platform. " - "Please use `ListModelVersionsOperator`" - ), + reason="The MLEngineListVersionsOperator is deprecated and will be removed after 01.03.2025. " + "Please use ListModelVersionsOperator class instead. " + "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", category=AirflowProviderDeprecationWarning, ) class MLEngineListVersionsOperator(GoogleCloudBaseOperator): @@ -995,11 +978,9 @@ def execute(self, context: Context): @deprecated( - reason=( - "This operator is deprecated. All the functionality of legacy " - "MLEngine and new features are available on the Vertex AI platform. " - "Please use `DeleteModelVersionOperator`" - ), + reason="The MLEngineDeleteVersionOperator is deprecated and will be removed after 01.03.2025. " + "Please use DeleteModelVersionOperator class instead. " + "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", category=AirflowProviderDeprecationWarning, ) class MLEngineDeleteVersionOperator(GoogleCloudBaseOperator): @@ -1087,11 +1068,9 @@ def execute(self, context: Context): @deprecated( - reason=( - "This operator is deprecated. All the functionality of legacy " - "MLEngine and new features are available on the Vertex AI platform. " - "Please use `CreateCustomPythonPackageTrainingJobOperator`" - ), + reason="The MLEngineStartTrainingJobOperator is deprecated and will be removed after 01.03.2025. " + "Please use CreateCustomPythonPackageTrainingJobOperator class instead. " + "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", category=AirflowProviderDeprecationWarning, ) class MLEngineStartTrainingJobOperator(GoogleCloudBaseOperator): @@ -1426,11 +1405,9 @@ def on_kill(self) -> None: @deprecated( - reason=( - "This operator is deprecated. All the functionality of legacy " - "MLEngine and new features are available on the Vertex AI platform. " - "Please use `CancelCustomTrainingJobOperator`" - ), + reason="The MLEngineTrainingCancelJobOperator is deprecated and will be removed after 01.03.2025. " + "Please use CancelCustomTrainingJobOperator class instead. " + "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", category=AirflowProviderDeprecationWarning, ) class MLEngineTrainingCancelJobOperator(GoogleCloudBaseOperator): @@ -1481,8 +1458,8 @@ def __init__( @property @deprecated( - reason="`_project_id` is deprecated and will be removed in the future. Please use `project_id`" - " instead.", + reason="The _project_id method is deprecated and will be removed after 01.03.2025. " + "Please use project_id method instead.", category=AirflowProviderDeprecationWarning, ) def _project_id(self): @@ -1491,7 +1468,8 @@ def _project_id(self): @property @deprecated( - reason="`_job_id` is deprecated and will be removed in the future. Please use `job_id` instead.", + reason="The _job_id method is deprecated and will be removed after 01.03.2025. " + "Please use job_id method instead.", category=AirflowProviderDeprecationWarning, ) def _job_id(self): @@ -1500,8 +1478,8 @@ def _job_id(self): @property @deprecated( - reason="`_impersonation_chain` is deprecated and will be removed in the future." - " Please use `impersonation_chain` instead.", + reason="The _impersonation_chain method is deprecated and will be removed after 01.03.2025. " + "Please use impersonation_chain method instead.", category=AirflowProviderDeprecationWarning, ) def _impersonation_chain(self): diff --git a/airflow/providers/google/cloud/operators/vertex_ai/auto_ml.py b/airflow/providers/google/cloud/operators/vertex_ai/auto_ml.py index 680a91946e7fb..4092fe415f6f1 100644 --- a/airflow/providers/google/cloud/operators/vertex_ai/auto_ml.py +++ b/airflow/providers/google/cloud/operators/vertex_ai/auto_ml.py @@ -642,8 +642,8 @@ def __init__( @property @deprecated( - reason="`training_pipeline` is deprecated and will be removed in the future. " - "Please use `training_pipeline_id` instead.", + reason="The training_pipeline method is deprecated and will be removed after 01.03.2025. " + "Please use training_pipeline_id instead.", category=AirflowProviderDeprecationWarning, ) def training_pipeline(self): diff --git a/airflow/providers/google/cloud/operators/vertex_ai/custom_job.py b/airflow/providers/google/cloud/operators/vertex_ai/custom_job.py index 7b2964da8e57d..dde39e84c0d8b 100644 --- a/airflow/providers/google/cloud/operators/vertex_ai/custom_job.py +++ b/airflow/providers/google/cloud/operators/vertex_ai/custom_job.py @@ -1633,8 +1633,8 @@ def __init__( @property @deprecated( - reason="`training_pipeline` is deprecated and will be removed in the future. " - "Please use `training_pipeline_id` instead.", + reason="The training_pipeline method is deprecated and will be removed after 01.03.2025. " + "Please use training_pipeline_id method instead.", category=AirflowProviderDeprecationWarning, ) def training_pipeline(self): @@ -1643,8 +1643,8 @@ def training_pipeline(self): @property @deprecated( - reason="`custom_job` is deprecated and will be removed in the future. " - "Please use `custom_job_id` instead.", + reason="The custom_job method is deprecated and will be removed after 01.03.2025. " + "Please use custom_job_id method instead.", category=AirflowProviderDeprecationWarning, ) def custom_job(self): diff --git a/airflow/providers/google/cloud/operators/vertex_ai/generative_model.py b/airflow/providers/google/cloud/operators/vertex_ai/generative_model.py index 0aa7cbc6d9324..c8fa1f8fee0f5 100644 --- a/airflow/providers/google/cloud/operators/vertex_ai/generative_model.py +++ b/airflow/providers/google/cloud/operators/vertex_ai/generative_model.py @@ -33,7 +33,8 @@ @deprecated( - reason="This operator is deprecated and will be removed after 01.01.2025, please use `TextGenerationModelPredictOperator`.", + reason="The PromptLanguageModelOperator is deprecated and will be removed after 01.01.2025. " + "Please use TextGenerationModelPredictOperator instead.", category=AirflowProviderDeprecationWarning, ) class PromptLanguageModelOperator(GoogleCloudBaseOperator): @@ -122,7 +123,8 @@ def execute(self, context: Context): @deprecated( - reason="This operator is deprecated and will be removed after 01.01.2025, please use `TextEmbeddingModelGetEmbeddingsOperator`.", + reason="The GenerateTextEmbeddingsOperator is deprecated and will be removed after 01.01.2025. " + "Please use TextEmbeddingModelGetEmbeddingsOperator instead.", category=AirflowProviderDeprecationWarning, ) class GenerateTextEmbeddingsOperator(GoogleCloudBaseOperator): @@ -190,7 +192,8 @@ def execute(self, context: Context): @deprecated( - reason="This operator is deprecated and will be removed after 01.01.2025, please use `GenerativeModelGenerateContentOperator`.", + reason="The PromptMultimodalModelOperator is deprecated and will be removed after 01.01.2025. " + "Please use GenerativeModelGenerateContentOperator instead.", category=AirflowProviderDeprecationWarning, ) class PromptMultimodalModelOperator(GoogleCloudBaseOperator): @@ -266,7 +269,8 @@ def execute(self, context: Context): @deprecated( - reason="This operator is deprecated and will be removed after 01.01.2025, please use `GenerativeModelGenerateContentOperator`.", + reason="The PromptMultimodalModelWithMediaOperator is deprecated and will be removed after 01.01.2025. " + "Please use GenerativeModelGenerateContentOperator instead.", category=AirflowProviderDeprecationWarning, ) class PromptMultimodalModelWithMediaOperator(GoogleCloudBaseOperator): diff --git a/airflow/providers/google/cloud/secrets/secret_manager.py b/airflow/providers/google/cloud/secrets/secret_manager.py index df2a67b470582..e7440322de205 100644 --- a/airflow/providers/google/cloud/secrets/secret_manager.py +++ b/airflow/providers/google/cloud/secrets/secret_manager.py @@ -162,10 +162,8 @@ def get_conn_value(self, conn_id: str) -> str | None: return self._get_secret(self.connections_prefix, conn_id) @deprecated( - reason=( - "Method `CloudSecretManagerBackend.get_conn_uri` is deprecated and will be removed " - "in a future release. Please use method `get_conn_value` instead." - ), + reason="The method get_conn_uri is deprecated and will be removed after 01.11.2024. " + "Please use get_conn_value method instead.", category=AirflowProviderDeprecationWarning, ) def get_conn_uri(self, conn_id: str) -> str | None: diff --git a/airflow/providers/google/cloud/sensors/bigquery.py b/airflow/providers/google/cloud/sensors/bigquery.py index 203ef9361a03f..0538013d1c094 100644 --- a/airflow/providers/google/cloud/sensors/bigquery.py +++ b/airflow/providers/google/cloud/sensors/bigquery.py @@ -261,12 +261,8 @@ def execute_complete(self, context: dict[str, Any], event: dict[str, str] | None @deprecated( - reason=( - "Class `BigQueryTableExistenceAsyncSensor` is deprecated and " - "will be removed in a future release. " - "Please use `BigQueryTableExistenceSensor` and " - "set `deferrable` attribute to `True` instead" - ), + reason="The BigQueryTableExistenceAsyncSensor is deprecated and will be removed after 01.11.2024. " + "Please use BigQueryTableExistenceSensor and set deferrable attribute to True instead.", category=AirflowProviderDeprecationWarning, ) class BigQueryTableExistenceAsyncSensor(BigQueryTableExistenceSensor): @@ -303,12 +299,9 @@ def __init__(self, **kwargs): @deprecated( - reason=( - "Class `BigQueryTableExistencePartitionAsyncSensor` is deprecated and " - "will be removed in a future release. " - "Please use `BigQueryTablePartitionExistenceSensor` and " - "set `deferrable` attribute to `True` instead" - ), + reason="The BigQueryTableExistencePartitionAsyncSensor is deprecated " + "and will be removed after 01.11.2024. " + "Please use BigQueryTablePartitionExistenceSensor class and set deferrable attribute to True instead.", category=AirflowProviderDeprecationWarning, ) class BigQueryTableExistencePartitionAsyncSensor(BigQueryTablePartitionExistenceSensor): diff --git a/airflow/providers/google/cloud/sensors/cloud_composer.py b/airflow/providers/google/cloud/sensors/cloud_composer.py index aa6cb0a35d72a..0849d533de11d 100644 --- a/airflow/providers/google/cloud/sensors/cloud_composer.py +++ b/airflow/providers/google/cloud/sensors/cloud_composer.py @@ -44,10 +44,11 @@ @deprecated( reason=( - "The `CloudComposerEnvironmentSensor` operator is deprecated. " - "You can achieve the same functionality " - "by using operators in deferrable or non-deferrable mode, since every operator for Cloud " - "Composer will wait for the operation to complete." + "The CloudComposerEnvironmentSensor operator is deprecated and will be removed after 01.11.2024. " + "Please use CloudComposerCreateEnvironmentOperator, CloudComposerDeleteEnvironmentOperator or " + "CloudComposerUpdateEnvironmentOperator in deferrable or non-deferrable mode, " + "since since every operator gives user a possibility to wait (asynchronously or synchronously) " + "until the Operation is finished." ), category=AirflowProviderDeprecationWarning, ) diff --git a/airflow/providers/google/cloud/sensors/gcs.py b/airflow/providers/google/cloud/sensors/gcs.py index b953ef66eb109..def5e722ec3c4 100644 --- a/airflow/providers/google/cloud/sensors/gcs.py +++ b/airflow/providers/google/cloud/sensors/gcs.py @@ -143,10 +143,8 @@ def execute_complete(self, context: Context, event: dict[str, str]) -> bool: @deprecated( - reason=( - "Class `GCSObjectExistenceAsyncSensor` is deprecated and will be removed in a future release. " - "Please use `GCSObjectExistenceSensor` and set `deferrable` attribute to `True` instead" - ), + reason="The GCSObjectExistenceAsyncSensor is deprecated and will be removed after 01.11.2024. " + "Please use GCSObjectExistenceSensor and set deferrable attribute to True instead.", category=AirflowProviderDeprecationWarning, ) class GCSObjectExistenceAsyncSensor(GCSObjectExistenceSensor): diff --git a/airflow/providers/google/common/hooks/base_google.py b/airflow/providers/google/common/hooks/base_google.py index a55bb49f766c2..ecb07c6a4d1c8 100644 --- a/airflow/providers/google/common/hooks/base_google.py +++ b/airflow/providers/google/common/hooks/base_google.py @@ -451,7 +451,8 @@ def num_retries(self) -> int: @property @deprecated( - reason="Please use `airflow.providers.google.common.consts.CLIENT_INFO`.", + reason="The client_info method is deprecated and will be removed after 01.03.2025. " + "Please use airflow.providers.google.common.consts.CLIENT_INFO instead.", category=AirflowProviderDeprecationWarning, ) def client_info(self) -> ClientInfo: diff --git a/airflow/providers/google/marketing_platform/hooks/analytics.py b/airflow/providers/google/marketing_platform/hooks/analytics.py index d73a30637c597..ae2ffcd284489 100644 --- a/airflow/providers/google/marketing_platform/hooks/analytics.py +++ b/airflow/providers/google/marketing_platform/hooks/analytics.py @@ -28,7 +28,9 @@ @deprecated( - reason="The `GoogleAnalyticsHook` class is deprecated, please use `GoogleAnalyticsAdminHook` instead.", + reason="The GoogleAnalyticsHook class is deprecated and will be removed after 01.11.2024. " + "Please use GoogleAnalyticsAdminHook instead. " + "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsHook(GoogleBaseHook): diff --git a/airflow/providers/google/marketing_platform/operators/analytics.py b/airflow/providers/google/marketing_platform/operators/analytics.py index 1d024e35605b7..6f86f96a46c71 100644 --- a/airflow/providers/google/marketing_platform/operators/analytics.py +++ b/airflow/providers/google/marketing_platform/operators/analytics.py @@ -35,10 +35,9 @@ @deprecated( - reason=( - "The `GoogleAnalyticsListAccountsOperator` class is deprecated, please use " - "`GoogleAnalyticsAdminListAccountsOperator` instead." - ), + reason="The GoogleAnalyticsListAccountsOperator class is deprecated " + "and will be removed after 01.11.2024. Please use GoogleAnalyticsAdminListAccountsOperator instead. " + "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsListAccountsOperator(BaseOperator): @@ -102,10 +101,9 @@ def execute(self, context: Context) -> list[dict[str, Any]]: @deprecated( - reason=( - "The `GoogleAnalyticsGetAdsLinkOperator` class is deprecated, please use " - "`GoogleAnalyticsAdminGetGoogleAdsLinkOperator` instead." - ), + reason="The GoogleAnalyticsGetAdsLinkOperator class is deprecated and will be removed after 01.11.2024. " + "Please use GoogleAnalyticsAdminGetGoogleAdsLinkOperator instead. " + "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsGetAdsLinkOperator(BaseOperator): @@ -181,10 +179,10 @@ def execute(self, context: Context) -> dict[str, Any]: @deprecated( - reason=( - "The `GoogleAnalyticsRetrieveAdsLinksListOperator` class is deprecated, please use " - "`GoogleAnalyticsAdminListGoogleAdsLinksOperator` instead." - ), + reason="The GoogleAnalyticsRetrieveAdsLinksListOperator is deprecated " + "and will be removed after 01.11.2024. " + "Please use GoogleAnalyticsAdminListGoogleAdsLinksOperator` instead. " + "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsRetrieveAdsLinksListOperator(BaseOperator): @@ -255,10 +253,9 @@ def execute(self, context: Context) -> list[dict[str, Any]]: @deprecated( - reason=( - "The `GoogleAnalyticsDataImportUploadOperator` class is deprecated, please use " - "`GoogleAnalyticsAdminCreateDataStreamOperator` instead." - ), + reason="The GoogleAnalyticsDataImportUploadOperator class is deprecated " + "and will be removed after 01.11.2024. Please use GoogleAnalyticsAdminCreateDataStreamOperator instead. " + "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsDataImportUploadOperator(BaseOperator): @@ -362,10 +359,9 @@ def execute(self, context: Context) -> None: @deprecated( - reason=( - "The `GoogleAnalyticsDeletePreviousDataUploadsOperator` class is deprecated, please use " - "`GoogleAnalyticsAdminDeleteDataStreamOperator` instead." - ), + reason="The GoogleAnalyticsDeletePreviousDataUploadsOperator is deprecated " + "and will be removed after 01.11.2024. Please use GoogleAnalyticsAdminDeleteDataStreamOperator instead. " + "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsDeletePreviousDataUploadsOperator(BaseOperator): diff --git a/scripts/ci/pre_commit/check_deprecations.py b/scripts/ci/pre_commit/check_deprecations.py index aa01e56065e40..925cd4ae423fe 100755 --- a/scripts/ci/pre_commit/check_deprecations.py +++ b/scripts/ci/pre_commit/check_deprecations.py @@ -19,9 +19,18 @@ from __future__ import annotations import ast +import re import sys +from datetime import date from functools import lru_cache from pathlib import Path +from typing import Any + +from dateutil.relativedelta import relativedelta +from rich.console import Console + +console = Console(color_system="standard", width=200) + allowed_warnings: dict[str, tuple[str, ...]] = { "airflow": ( @@ -40,6 +49,63 @@ ("deprecated", "classic", "deprecated"), ] ) +end_of_life_deprecation_warnings: dict[str, tuple[str, ...]] = { + "airflow/providers/google/": ("AirflowProviderDeprecationWarning",), +} + + +def is_file_under_eol_deprecation(file_path: str, warning_class: str) -> bool: + for prefix, warnings in end_of_life_deprecation_warnings.items(): + if file_path.startswith(prefix): + return bool(warning_class in warnings) + return False + + +def validate_end_of_life_deprecation_warnings(file_path: str, decorator: Any, warning_class: str) -> int: + _errors = 0 + if not is_file_under_eol_deprecation(file_path=file_path, warning_class=warning_class): + return 0 + if category_reason := get_decorator_argument(decorator, "reason"): + reason_message: str = str(category_reason.value.value) # type: ignore[attr-defined] + reason_pattern = r"(.+?) is deprecated and will be removed after (\d{2})\.(\d{2})\.(\d{4})\. (?:Please use (.+?) |There is no replacement(.+?))" + expected_date = date.today() + relativedelta(months=6) + if expected_date.day > 1: + _date = date.today() + relativedelta(months=7) + expected_date = date(day=1, month=_date.month, year=_date.year) + expected_date_str: str = expected_date.strftime("%d.%m.%Y") + if match := re.search(reason_pattern, reason_message): + groups = match.groups() + day, month, year = groups[1], groups[2], groups[3] + try: + date(day=int(day), month=int(month), year=int(year)) + except ValueError: + _errors += 1 + console.print( + f"{file_path}:{category_reason.lineno}: " + f"[red]Deprecation message contains invalid date '{day}.{month}.{year}'.[/]\n\n" + f"[green]Expected date in the format DD.MM.YYYY " + f"(recommended: {expected_date_str}).[/]" + ) + else: + _errors += 1 + console.print( + f"{file_path}:{category_reason.lineno}: " + f"[red]Deprecation message is invalid: {reason_message}[/]\n\n" + f"[green]Please update it to one of the following formats " + f"(note that the removal date is recommended to be at least 6 months ahead):\n\n" + f"- The is deprecated and will be removed after {expected_date_str}. " + f"Please use instead .\n" + f"- The is deprecated and will be removed after {expected_date_str}. " + f"There is no replacement.[/]\n" + ) + else: + _errors += 1 + console.print(f"{file_path}: reason attribute in the @deprecated decorator was expected.") + return _errors + + +def get_decorator_argument(decorator: ast.Call, argument_name: str) -> ast.keyword | None: + return next(filter(lambda k: k and k.arg == argument_name, decorator.keywords), None) # type: ignore[arg-type] @lru_cache(maxsize=None) @@ -137,9 +203,7 @@ def check_decorators(mod: ast.Module, file: str, file_group: str) -> int: continue expected_types, warns_types = allowed_group_warnings(file_group) - category_keyword: ast.keyword | None = next( - filter(lambda k: k and k.arg == "category", decorator.keywords), None - ) + category_keyword = get_decorator_argument(decorator, "category") if category_keyword is None: errors += 1 print( @@ -160,6 +224,9 @@ def check_decorators(mod: ast.Module, file: str, file_group: str) -> int: f"{file}:{category_keyword.lineno}: " f"category={category_value}, but {expected_types}" ) + errors += validate_end_of_life_deprecation_warnings( + file_path=file, decorator=decorator, warning_class=category_value + ) elif isinstance(category_value_ast, ast.Constant): errors += 1 print( From c941b5740b8c967fefc569188594b3ded5904915 Mon Sep 17 00:00:00 2001 From: Maksim Moiseenkov Date: Fri, 23 Aug 2024 13:05:34 +0000 Subject: [PATCH 2/2] A custom @deprecated decorator for Google prvider package. --- .../providers/google/cloud/hooks/bigquery.py | 173 +++++------ .../google/cloud/hooks/cloud_build.py | 6 +- .../providers/google/cloud/hooks/dataflow.py | 14 +- .../google/cloud/hooks/datapipeline.py | 7 +- .../google/cloud/hooks/kubernetes_engine.py | 30 +- .../google/cloud/hooks/life_sciences.py | 10 +- .../google/cloud/hooks/secret_manager.py | 6 +- .../cloud/hooks/vertex_ai/custom_job.py | 22 +- .../cloud/hooks/vertex_ai/generative_model.py | 35 +-- .../providers/google/cloud/links/automl.py | 30 +- .../google/cloud/operators/bigquery.py | 12 +- .../google/cloud/operators/dataflow.py | 10 +- .../google/cloud/operators/datafusion.py | 6 +- .../google/cloud/operators/datapipeline.py | 11 +- .../google/cloud/operators/dataproc.py | 46 +-- .../cloud/operators/kubernetes_engine.py | 6 +- .../google/cloud/operators/life_sciences.py | 9 +- .../google/cloud/operators/mlengine.py | 85 +++-- .../cloud/operators/vertex_ai/auto_ml.py | 6 +- .../cloud/operators/vertex_ai/custom_job.py | 10 +- .../operators/vertex_ai/generative_model.py | 18 +- .../google/cloud/secrets/secret_manager.py | 6 +- .../google/cloud/sensors/bigquery.py | 14 +- .../google/cloud/sensors/cloud_composer.py | 16 +- airflow/providers/google/cloud/sensors/gcs.py | 7 +- airflow/providers/google/common/deprecated.py | 176 +++++++++++ .../google/common/hooks/base_google.py | 6 +- .../marketing_platform/hooks/analytics.py | 8 +- .../marketing_platform/operators/analytics.py | 34 +- scripts/ci/pre_commit/check_deprecations.py | 46 +-- .../google/cloud/hooks/test_bigquery.py | 51 --- .../google/cloud/hooks/test_cloud_build.py | 4 +- .../google/cloud/hooks/test_dataflow.py | 24 +- .../google/cloud/hooks/test_secret_manager.py | 18 +- .../google/cloud/operators/test_bigquery.py | 29 +- .../google/cloud/operators/test_mlengine.py | 292 ++++-------------- .../vertex_ai/test_generative_model.py | 20 +- .../google/cloud/sensors/test_bigquery.py | 30 +- .../cloud/sensors/test_cloud_composer.py | 12 +- .../google/cloud/sensors/test_gcs.py | 11 +- .../utils/test_mlengine_operator_utils.py | 12 +- .../google/common/test_deprecated.py | 264 ++++++++++++++++ .../hooks/test_analytics.py | 7 +- .../operators/test_analytics.py | 30 +- 44 files changed, 878 insertions(+), 791 deletions(-) create mode 100644 airflow/providers/google/common/deprecated.py create mode 100644 tests/providers/google/common/test_deprecated.py diff --git a/airflow/providers/google/cloud/hooks/bigquery.py b/airflow/providers/google/cloud/hooks/bigquery.py index bbab4c25b94fa..8e330b17d5cab 100644 --- a/airflow/providers/google/cloud/hooks/bigquery.py +++ b/airflow/providers/google/cloud/hooks/bigquery.py @@ -32,7 +32,6 @@ from typing import TYPE_CHECKING, Any, Iterable, Mapping, NoReturn, Sequence, Union, cast from aiohttp import ClientSession as ClientSession -from deprecated import deprecated from gcloud.aio.bigquery import Job, Table as Table_async from google.cloud.bigquery import ( DEFAULT_RETRY, @@ -66,6 +65,7 @@ from airflow.providers.google.cloud.utils.bigquery import bq_cast from airflow.providers.google.cloud.utils.credentials_provider import _get_scopes from airflow.providers.google.common.consts import CLIENT_INFO +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import ( PROVIDE_PROJECT_ID, GoogleBaseAsyncHook, @@ -175,9 +175,8 @@ def __init__( @cached_property @deprecated( - reason="The credentials_path property is deprecated and will be removed after 01.11.2024. " - "There is no replacement because this property used for obtaining credentials path " - "but is no longer in actual use. ", + planned_removal_date="November 01, 2024", + reason="This property is no longer in actual use. ", category=AirflowProviderDeprecationWarning, ) def credentials_path(self) -> str: @@ -197,8 +196,8 @@ def get_conn(self) -> BigQueryConnection: ) @deprecated( - reason="The get_service method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_client method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_client.", category=AirflowProviderDeprecationWarning, ) def get_service(self) -> Resource: @@ -604,9 +603,10 @@ def delete_dataset( ) @deprecated( - reason="The create_external_table method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_table method " - "with passing the table_resource object instead. This gives more flexibility than this method.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_table", + instructions="Use the replacement method with passing the `table_resource` object. " + "This gives more flexibility.", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id @@ -805,8 +805,8 @@ def update_table( return table_object.to_api_repr() @deprecated( - reason="The patch_table method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_table method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_table", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id @@ -1015,9 +1015,8 @@ def update_dataset( return dataset @deprecated( - reason="The patch_dataset method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_dataset " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_dataset", category=AirflowProviderDeprecationWarning, ) def patch_dataset( @@ -1063,9 +1062,8 @@ def patch_dataset( return dataset @deprecated( - reason="The get_dataset_tables_list method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables", category=AirflowProviderDeprecationWarning, ) def get_dataset_tables_list( @@ -1269,8 +1267,8 @@ def run_table_upsert( return table @deprecated( - reason="The run_table_delete method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.delete_table method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.delete_table", category=AirflowProviderDeprecationWarning, ) def run_table_delete(self, deletion_dataset_table: str, ignore_if_missing: bool = False) -> None: @@ -1317,8 +1315,8 @@ def delete_table( self.log.info("Deleted table %s", table_id) @deprecated( - reason="The get_tabledata method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.list_rows method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.list_rows", category=AirflowProviderDeprecationWarning, ) def get_tabledata( @@ -1554,8 +1552,8 @@ def poll_job_complete( return job.done(retry=retry) @deprecated( - reason="The cancel_query method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.cancel_job method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.cancel_job", category=AirflowProviderDeprecationWarning, ) def cancel_query(self) -> None: @@ -1708,8 +1706,8 @@ def insert_job( return job_api_repr @deprecated( - reason="The run_with_configuration method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job", category=AirflowProviderDeprecationWarning, ) def run_with_configuration(self, configuration: dict) -> str: @@ -1730,8 +1728,8 @@ def run_with_configuration(self, configuration: dict) -> str: return job.job_id @deprecated( - reason="The run_load method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job", category=AirflowProviderDeprecationWarning, ) def run_load( @@ -1972,8 +1970,8 @@ def run_load( return job.job_id @deprecated( - reason="The run_copy method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job", category=AirflowProviderDeprecationWarning, ) def run_copy( @@ -2059,8 +2057,8 @@ def run_copy( return job.job_id @deprecated( - reason="The run_extract method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job", category=AirflowProviderDeprecationWarning, ) def run_extract( @@ -2134,8 +2132,8 @@ def run_extract( return job.job_id @deprecated( - reason="The run_query method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job", category=AirflowProviderDeprecationWarning, ) def run_query( @@ -2552,9 +2550,8 @@ def __init__( self.hook = hook @deprecated( - reason="The create_empty_table method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_table " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_table", category=AirflowProviderDeprecationWarning, ) def create_empty_table(self, *args, **kwargs): @@ -2567,9 +2564,8 @@ def create_empty_table(self, *args, **kwargs): return self.hook.create_empty_table(*args, **kwargs) @deprecated( - reason="The create_empty_dataset method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_dataset " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_empty_dataset", category=AirflowProviderDeprecationWarning, ) def create_empty_dataset(self, *args, **kwargs) -> dict[str, Any]: @@ -2582,9 +2578,8 @@ def create_empty_dataset(self, *args, **kwargs) -> dict[str, Any]: return self.hook.create_empty_dataset(*args, **kwargs) @deprecated( - reason="The get_dataset_tables method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables", category=AirflowProviderDeprecationWarning, ) def get_dataset_tables(self, *args, **kwargs) -> list[dict[str, Any]]: @@ -2597,9 +2592,8 @@ def get_dataset_tables(self, *args, **kwargs) -> list[dict[str, Any]]: return self.hook.get_dataset_tables(*args, **kwargs) @deprecated( - reason="The delete_dataset method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.delete_dataset " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.delete_dataset", category=AirflowProviderDeprecationWarning, ) def delete_dataset(self, *args, **kwargs) -> None: @@ -2612,9 +2606,8 @@ def delete_dataset(self, *args, **kwargs) -> None: return self.hook.delete_dataset(*args, **kwargs) @deprecated( - reason="The create_external_table method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_external_table " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.create_external_table", category=AirflowProviderDeprecationWarning, ) def create_external_table(self, *args, **kwargs): @@ -2627,8 +2620,8 @@ def create_external_table(self, *args, **kwargs): return self.hook.create_external_table(*args, **kwargs) @deprecated( - reason="The patch_table method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.patch_table method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.patch_table", category=AirflowProviderDeprecationWarning, ) def patch_table(self, *args, **kwargs) -> None: @@ -2641,8 +2634,8 @@ def patch_table(self, *args, **kwargs) -> None: return self.hook.patch_table(*args, **kwargs) @deprecated( - reason="The insert_all method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_all method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_all", category=AirflowProviderDeprecationWarning, ) def insert_all(self, *args, **kwargs) -> None: @@ -2655,9 +2648,8 @@ def insert_all(self, *args, **kwargs) -> None: return self.hook.insert_all(*args, **kwargs) @deprecated( - reason="The update_dataset method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_dataset " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.update_dataset", category=AirflowProviderDeprecationWarning, ) def update_dataset(self, *args, **kwargs) -> dict: @@ -2670,8 +2662,8 @@ def update_dataset(self, *args, **kwargs) -> dict: return Dataset.to_api_repr(self.hook.update_dataset(*args, **kwargs)) @deprecated( - reason="The patch_dataset method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.patch_dataset method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.patch_dataset", category=AirflowProviderDeprecationWarning, ) def patch_dataset(self, *args, **kwargs) -> dict: @@ -2684,9 +2676,8 @@ def patch_dataset(self, *args, **kwargs) -> dict: return self.hook.patch_dataset(*args, **kwargs) @deprecated( - reason="The get_dataset_tables_list method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables_list " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset_tables_list", category=AirflowProviderDeprecationWarning, ) def get_dataset_tables_list(self, *args, **kwargs) -> list[dict[str, Any]]: @@ -2699,9 +2690,8 @@ def get_dataset_tables_list(self, *args, **kwargs) -> list[dict[str, Any]]: return self.hook.get_dataset_tables_list(*args, **kwargs) @deprecated( - reason="The get_datasets_list method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_datasets_list " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_datasets_list", category=AirflowProviderDeprecationWarning, ) def get_datasets_list(self, *args, **kwargs) -> list | HTTPIterator: @@ -2714,8 +2704,8 @@ def get_datasets_list(self, *args, **kwargs) -> list | HTTPIterator: return self.hook.get_datasets_list(*args, **kwargs) @deprecated( - reason="The get_dataset method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_dataset", category=AirflowProviderDeprecationWarning, ) def get_dataset(self, *args, **kwargs) -> Dataset: @@ -2728,9 +2718,8 @@ def get_dataset(self, *args, **kwargs) -> Dataset: return self.hook.get_dataset(*args, **kwargs) @deprecated( - reason="The run_grant_dataset_view_access method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_grant_dataset_view_access " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_grant_dataset_view_access", category=AirflowProviderDeprecationWarning, ) def run_grant_dataset_view_access(self, *args, **kwargs) -> dict: @@ -2744,9 +2733,8 @@ def run_grant_dataset_view_access(self, *args, **kwargs) -> dict: return self.hook.run_grant_dataset_view_access(*args, **kwargs) @deprecated( - reason="The run_table_upsert method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_table_upsert " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_table_upsert", category=AirflowProviderDeprecationWarning, ) def run_table_upsert(self, *args, **kwargs) -> dict: @@ -2759,9 +2747,8 @@ def run_table_upsert(self, *args, **kwargs) -> dict: return self.hook.run_table_upsert(*args, **kwargs) @deprecated( - reason="The run_table_delete method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_table_delete " - "method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_table_delete", category=AirflowProviderDeprecationWarning, ) def run_table_delete(self, *args, **kwargs) -> None: @@ -2774,8 +2761,8 @@ def run_table_delete(self, *args, **kwargs) -> None: return self.hook.run_table_delete(*args, **kwargs) @deprecated( - reason="The get_tabledata method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_tabledata method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_tabledata", category=AirflowProviderDeprecationWarning, ) def get_tabledata(self, *args, **kwargs) -> list[dict]: @@ -2788,8 +2775,8 @@ def get_tabledata(self, *args, **kwargs) -> list[dict]: return self.hook.get_tabledata(*args, **kwargs) @deprecated( - reason="The get_schema method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_schema method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.get_schema", category=AirflowProviderDeprecationWarning, ) def get_schema(self, *args, **kwargs) -> dict: @@ -2802,9 +2789,8 @@ def get_schema(self, *args, **kwargs) -> dict: return self.hook.get_schema(*args, **kwargs) @deprecated( - reason="The poll_job_complete method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.poll_job_complete " - "method instead", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.poll_job_complete", category=AirflowProviderDeprecationWarning, ) def poll_job_complete(self, *args, **kwargs) -> bool: @@ -2817,8 +2803,8 @@ def poll_job_complete(self, *args, **kwargs) -> bool: return self.hook.poll_job_complete(*args, **kwargs) @deprecated( - reason="The cancel_query method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.cancel_query method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.cancel_query", category=AirflowProviderDeprecationWarning, ) def cancel_query(self, *args, **kwargs) -> None: @@ -2831,9 +2817,8 @@ def cancel_query(self, *args, **kwargs) -> None: return self.hook.cancel_query(*args, **kwargs) # type: ignore @deprecated( - reason="The run_with_configuration method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_with_configuration " - "method instead", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_with_configuration", category=AirflowProviderDeprecationWarning, ) def run_with_configuration(self, *args, **kwargs) -> str: @@ -2846,8 +2831,8 @@ def run_with_configuration(self, *args, **kwargs) -> str: return self.hook.run_with_configuration(*args, **kwargs) @deprecated( - reason="The run_load method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_load method instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_load", category=AirflowProviderDeprecationWarning, ) def run_load(self, *args, **kwargs) -> str: @@ -2860,8 +2845,8 @@ def run_load(self, *args, **kwargs) -> str: return self.hook.run_load(*args, **kwargs) @deprecated( - reason="The run_copy method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_copy method instead", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_copy", category=AirflowProviderDeprecationWarning, ) def run_copy(self, *args, **kwargs) -> str: @@ -2874,8 +2859,8 @@ def run_copy(self, *args, **kwargs) -> str: return self.hook.run_copy(*args, **kwargs) @deprecated( - reason="The run_extract method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_extract method instead", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_extract", category=AirflowProviderDeprecationWarning, ) def run_extract(self, *args, **kwargs) -> str | BigQueryJob: @@ -2888,8 +2873,8 @@ def run_extract(self, *args, **kwargs) -> str | BigQueryJob: return self.hook.run_extract(*args, **kwargs) @deprecated( - reason="The run_query method is deprecated and will be removed after 01.11.2024. " - "Please use airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_query instead.", + planned_removal_date="November 01, 2024", + use_instead="airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.run_query", category=AirflowProviderDeprecationWarning, ) def run_query(self, *args, **kwargs) -> str: diff --git a/airflow/providers/google/cloud/hooks/cloud_build.py b/airflow/providers/google/cloud/hooks/cloud_build.py index feddae3b45784..e4531b7f8d2c6 100644 --- a/airflow/providers/google/cloud/hooks/cloud_build.py +++ b/airflow/providers/google/cloud/hooks/cloud_build.py @@ -21,7 +21,6 @@ from typing import TYPE_CHECKING, Sequence -from deprecated import deprecated from google.api_core.client_options import ClientOptions from google.api_core.exceptions import AlreadyExists from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault @@ -29,6 +28,7 @@ from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning from airflow.providers.google.common.consts import CLIENT_INFO +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook if TYPE_CHECKING: @@ -191,8 +191,8 @@ def create_build_without_waiting_for_result( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="The create_build method is deprecated and will be removed after 01.03.2025. " - "Please use create_build_without_waiting_for_result method instead.", + planned_removal_date="March 01, 2025", + use_instead="create_build_without_waiting_for_result", category=AirflowProviderDeprecationWarning, ) def create_build( diff --git a/airflow/providers/google/cloud/hooks/dataflow.py b/airflow/providers/google/cloud/hooks/dataflow.py index 1554fd4b6f776..588d56abd5746 100644 --- a/airflow/providers/google/cloud/hooks/dataflow.py +++ b/airflow/providers/google/cloud/hooks/dataflow.py @@ -30,7 +30,6 @@ from copy import deepcopy from typing import TYPE_CHECKING, Any, Callable, Generator, Sequence, TypeVar, cast -from deprecated import deprecated from google.cloud.dataflow_v1beta3 import ( GetJobRequest, Job, @@ -51,6 +50,7 @@ from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning from airflow.providers.apache.beam.hooks.beam import BeamHook, BeamRunnerType, beam_options_to_args +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import ( PROVIDE_PROJECT_ID, GoogleBaseAsyncHook, @@ -594,8 +594,10 @@ def get_pipelines_conn(self) -> build: @_fallback_to_project_id_from_variables @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="The start_java_dataflow method is deprecated and will be removed after 01.03.2025. " - "Please use airflow.providers.apache.beam.hooks.beam.start.start_java_pipeline method " + planned_removal_date="March 01, 2025", + use_instead="airflow.providers.apache.beam.hooks.beam.start.start_java_pipeline, " + "providers.google.cloud.hooks.dataflow.DataflowHook.wait_for_done", + instructions="Please use airflow.providers.apache.beam.hooks.beam.start.start_java_pipeline " "to start pipeline and providers.google.cloud.hooks.dataflow.DataflowHook.wait_for_done method " "to wait for the required pipeline state instead.", category=AirflowProviderDeprecationWarning, @@ -949,8 +951,10 @@ def extract_job_id(job: dict) -> str: @_fallback_to_project_id_from_variables @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="The start_python_dataflow method is deprecated and will be removed after 01.03.2025. " - "Please use airflow.providers.apache.beam.hooks.beam.start.start_python_pipeline method " + planned_removal_date="March 01, 2025", + use_instead="airflow.providers.apache.beam.hooks.beam.start.start_python_pipeline method, " + "providers.google.cloud.hooks.dataflow.DataflowHook.wait_for_done", + instructions="Please use airflow.providers.apache.beam.hooks.beam.start.start_python_pipeline method " "to start pipeline and providers.google.cloud.hooks.dataflow.DataflowHook.wait_for_done method " "to wait for the required pipeline state instead.", category=AirflowProviderDeprecationWarning, diff --git a/airflow/providers/google/cloud/hooks/datapipeline.py b/airflow/providers/google/cloud/hooks/datapipeline.py index 44c059e8d6c92..4d408c919b30b 100644 --- a/airflow/providers/google/cloud/hooks/datapipeline.py +++ b/airflow/providers/google/cloud/hooks/datapipeline.py @@ -21,10 +21,9 @@ from typing import TYPE_CHECKING -from deprecated import deprecated - from airflow.exceptions import AirflowProviderDeprecationWarning from airflow.providers.google.cloud.hooks.dataflow import DataflowHook +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import GoogleBaseHook if TYPE_CHECKING: @@ -34,8 +33,8 @@ @deprecated( - reason="The DataPipelineHook is deprecated and will be removed after 01.12.2024. " - "Please use DataflowHook instead.", + planned_removal_date="December 01, 2024", + use_instead="DataflowHook", category=AirflowProviderDeprecationWarning, ) class DataPipelineHook(DataflowHook): diff --git a/airflow/providers/google/cloud/hooks/kubernetes_engine.py b/airflow/providers/google/cloud/hooks/kubernetes_engine.py index d6bfff4fbec08..c8af049dc01e6 100644 --- a/airflow/providers/google/cloud/hooks/kubernetes_engine.py +++ b/airflow/providers/google/cloud/hooks/kubernetes_engine.py @@ -24,7 +24,6 @@ import time from typing import TYPE_CHECKING, Sequence -from deprecated import deprecated from google.api_core.exceptions import NotFound from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault from google.auth.transport import requests as google_requests @@ -43,6 +42,7 @@ from airflow.providers.cncf.kubernetes.hooks.kubernetes import AsyncKubernetesHook, KubernetesHook from airflow.providers.cncf.kubernetes.kube_client import _enable_tcp_keepalive from airflow.providers.google.common.consts import CLIENT_INFO +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import ( PROVIDE_PROJECT_ID, GoogleBaseAsyncHook, @@ -139,8 +139,8 @@ def get_cluster_manager_client(self) -> ClusterManagerClient: # To preserve backward compatibility # TODO: remove one day @deprecated( - reason="The get_conn method is deprecated and will be removed after 01.11.2024. " - "Please use the get_cluster_manager_client method instead.", + planned_removal_date="November 01, 2024", + use_instead="get_cluster_manager_client", category=AirflowProviderDeprecationWarning, ) def get_conn(self) -> container_v1.ClusterManagerClient: @@ -149,8 +149,8 @@ def get_conn(self) -> container_v1.ClusterManagerClient: # To preserve backward compatibility # TODO: remove one day @deprecated( - reason="The get_client method is deprecated and will be removed after 01.11.2024. " - "Please use the get_conn method instead.", + planned_removal_date="November 01, 2024", + use_instead="get_cluster_manager_client", category=AirflowProviderDeprecationWarning, ) def get_client(self) -> ClusterManagerClient: @@ -579,8 +579,8 @@ def _get_config(self) -> async_client.configuration.Configuration: @deprecated( - reason="The GKEDeploymentHook class is deprecated and will be removed after 01.10.2024. " - "Please use GKEKubernetesHook instead.", + planned_removal_date="October 01, 2024", + use_instead="GKEKubernetesHook", category=AirflowProviderDeprecationWarning, ) class GKEDeploymentHook(GKEKubernetesHook): @@ -588,8 +588,8 @@ class GKEDeploymentHook(GKEKubernetesHook): @deprecated( - reason="The GKECustomResourceHook class is deprecated and will be removed after 01.10.2024. " - "Please use GKEKubernetesHook instead.", + planned_removal_date="October 01, 2024", + use_instead="GKEKubernetesHook", category=AirflowProviderDeprecationWarning, ) class GKECustomResourceHook(GKEKubernetesHook): @@ -597,8 +597,8 @@ class GKECustomResourceHook(GKEKubernetesHook): @deprecated( - reason="The GKEPodHook class is deprecated and will be removed after 01.10.2024. " - "Please use GKEKubernetesHook instead.", + planned_removal_date="October 01, 2024", + use_instead="GKEKubernetesHook", category=AirflowProviderDeprecationWarning, ) class GKEPodHook(GKEKubernetesHook): @@ -624,8 +624,8 @@ def __init__( @deprecated( - reason="The GKEJobHook class is deprecated and will be removed after 01.10.2024. " - "Please use GKEKubernetesHook instead.", + planned_removal_date="October 01, 2024", + use_instead="GKEKubernetesHook", category=AirflowProviderDeprecationWarning, ) class GKEJobHook(GKEKubernetesHook): @@ -633,8 +633,8 @@ class GKEJobHook(GKEKubernetesHook): @deprecated( - reason="The GKEPodAsyncHook class is deprecated and will be removed after 01.10.2024. " - "Please use GKEKubernetesAsyncHook instead.", + planned_removal_date="October 01, 2024", + use_instead="GKEKubernetesAsyncHook", category=AirflowProviderDeprecationWarning, ) class GKEPodAsyncHook(GKEKubernetesAsyncHook): diff --git a/airflow/providers/google/cloud/hooks/life_sciences.py b/airflow/providers/google/cloud/hooks/life_sciences.py index a1c48464ddcd3..e46a4cebae990 100644 --- a/airflow/providers/google/cloud/hooks/life_sciences.py +++ b/airflow/providers/google/cloud/hooks/life_sciences.py @@ -23,10 +23,10 @@ from typing import Sequence import google.api_core.path_template -from deprecated import deprecated from googleapiclient.discovery import build from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import GoogleBaseHook # Time to sleep between active checks of the operation results @@ -34,10 +34,10 @@ @deprecated( - reason="The LifeSciencesHook is deprecated and will be removed after 08.07.2024. " - "Please use Google Cloud Batch Operators' hook instead. " - "The Life Sciences API (beta) will be discontinued " - "on July 8, 2025 in favor of Google Cloud Batch.", + planned_removal_date="March 01, 2025", + use_instead="Google Cloud Batch Operators' hook", + reason="The Life Sciences API (beta) will be discontinued on July 8, 2025 " + "in favor of Google Cloud Batch.", category=AirflowProviderDeprecationWarning, ) class LifeSciencesHook(GoogleBaseHook): diff --git a/airflow/providers/google/cloud/hooks/secret_manager.py b/airflow/providers/google/cloud/hooks/secret_manager.py index a7977a55f14bc..69c90a3034a38 100644 --- a/airflow/providers/google/cloud/hooks/secret_manager.py +++ b/airflow/providers/google/cloud/hooks/secret_manager.py @@ -22,7 +22,6 @@ from functools import cached_property from typing import TYPE_CHECKING, Sequence -from deprecated import deprecated from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault from google.cloud.secretmanager_v1 import ( AccessSecretVersionResponse, @@ -35,6 +34,7 @@ from airflow.exceptions import AirflowProviderDeprecationWarning from airflow.providers.google.cloud._internal_client.secret_manager_client import _SecretManagerClient from airflow.providers.google.common.consts import CLIENT_INFO +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook if TYPE_CHECKING: @@ -43,8 +43,8 @@ @deprecated( - reason="The SecretsManagerHook is deprecated and will be removed after 01.11.2024. " - "Please use GoogleCloudSecretManagerHook instead.", + planned_removal_date="November 01, 2024", + use_instead="GoogleCloudSecretManagerHook", category=AirflowProviderDeprecationWarning, ) class SecretsManagerHook(GoogleBaseHook): diff --git a/airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py b/airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py index 56226b6fcf9b9..9a9674c201b19 100644 --- a/airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py +++ b/airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py @@ -22,7 +22,6 @@ import asyncio from typing import TYPE_CHECKING, Any, Sequence -from deprecated import deprecated from google.api_core.client_options import ClientOptions from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault from google.cloud.aiplatform import ( @@ -44,6 +43,7 @@ from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning from airflow.providers.google.common.consts import CLIENT_INFO +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import GoogleBaseAsyncHook, GoogleBaseHook if TYPE_CHECKING: @@ -380,8 +380,8 @@ def _run_job( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="The cancel_pipeline_job method is deprecated and will be removed after 01.03.2025. " - "Please use PipelineJobHook.cancel_pipeline_job method instead.", + planned_removal_date="March 01, 2025", + use_instead="PipelineJobHook.cancel_pipeline_job", category=AirflowProviderDeprecationWarning, ) def cancel_pipeline_job( @@ -510,8 +510,8 @@ def cancel_custom_job( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="The create_pipeline_job method is deprecated and will be removed after 01.03.2025. " - "Please use PipelineJobHook.create_pipeline_job method instead.", + planned_removal_date="March 01, 2025", + use_instead="PipelineJobHook.create_pipeline_job", category=AirflowProviderDeprecationWarning, ) def create_pipeline_job( @@ -2982,8 +2982,8 @@ def delete_custom_job( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="The get_pipeline_job method is deprecated and will be removed after 01.03.2025. " - "Please use PipelineJobHook.get_pipeline_job method instead.", + planned_removal_date="March 01, 2025", + use_instead="PipelineJobHook.get_pipeline_job", category=AirflowProviderDeprecationWarning, ) def get_pipeline_job( @@ -3088,8 +3088,8 @@ def get_custom_job( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="The list_pipeline_jobs method is deprecated and will be removed after 01.03.2025. " - "Please use PipelineJobHook.list_pipeline_jobs method instead", + planned_removal_date="March 01, 2025", + use_instead="PipelineJobHook.list_pipeline_jobs", category=AirflowProviderDeprecationWarning, ) def list_pipeline_jobs( @@ -3305,8 +3305,8 @@ def list_custom_jobs( @GoogleBaseHook.fallback_to_default_project_id @deprecated( - reason="The delete_pipeline_job method is deprecated and will be removed after 01.03.2025. " - "Please use PipelineJobHook.delete_pipeline_job method instead", + planned_removal_date="March 01, 2025", + use_instead="PipelineJobHook.delete_pipeline_job", category=AirflowProviderDeprecationWarning, ) def delete_pipeline_job( diff --git a/airflow/providers/google/cloud/hooks/vertex_ai/generative_model.py b/airflow/providers/google/cloud/hooks/vertex_ai/generative_model.py index f571f5585cb08..eaf306a1f04e6 100644 --- a/airflow/providers/google/cloud/hooks/vertex_ai/generative_model.py +++ b/airflow/providers/google/cloud/hooks/vertex_ai/generative_model.py @@ -23,12 +23,12 @@ from typing import TYPE_CHECKING, Sequence import vertexai -from deprecated import deprecated from vertexai.generative_models import GenerativeModel, Part from vertexai.language_models import TextEmbeddingModel, TextGenerationModel from vertexai.preview.tuning import sft from airflow.exceptions import AirflowProviderDeprecationWarning +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook if TYPE_CHECKING: @@ -67,10 +67,10 @@ def get_generative_model(self, pretrained_model: str) -> GenerativeModel: return model @deprecated( - reason="The get_generative_model_part method is deprecated and will be removed after 01.01.2025. " - "Please use Part objects included in contents parameter of " - "airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.generative_model_generate_content " - "instead", + planned_removal_date="January 01, 2025", + use_instead="Part objects included in contents parameter of " + "airflow.providers.google.cloud.hooks.generative_model." + "GenerativeModelHook.generative_model_generate_content", category=AirflowProviderDeprecationWarning, ) def get_generative_model_part(self, content_gcs_path: str, content_mime_type: str | None = None) -> Part: @@ -79,9 +79,9 @@ def get_generative_model_part(self, content_gcs_path: str, content_mime_type: st return part @deprecated( - reason="The prompt_language_model method is deprecated and will be removed after 01.01.2025. " - "Please use airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.text_generation_model_predict " - "method instead.", + planned_removal_date="January 01, 2025", + use_instead="airflow.providers.google.cloud.hooks.generative_model." + "GenerativeModelHook.text_generation_model_predict", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id @@ -133,9 +133,9 @@ def prompt_language_model( return response.text @deprecated( - reason="The generate_text_embeddings method is deprecated and will be removed after 01.01.2025. " - "Please use airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.text_embedding_model_get_embeddings " - "method instead.", + planned_removal_date="January 01, 2025", + use_instead="airflow.providers.google.cloud.hooks.generative_model." + "GenerativeModelHook.text_embedding_model_get_embeddings", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id @@ -163,9 +163,9 @@ def generate_text_embeddings( return response.values @deprecated( - reason="The prompt_multimodal_model method is deprecated and will be removed after 01.01.2025. " - "Please use airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.generative_model_generate_content " - "method instead.", + planned_removal_date="January 01, 2025", + use_instead="airflow.providers.google.cloud.hooks.generative_model." + "GenerativeModelHook.generative_model_generate_content", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id @@ -202,10 +202,9 @@ def prompt_multimodal_model( return response.text @deprecated( - reason="The prompt_multimodal_model_with_media method is deprecated " - "and will be removed after 01.01.2025. Please use " - "airflow.providers.google.cloud.hooks.generative_model.GenerativeModelHook.generative_model_generate_content " - "method instead.", + planned_removal_date="January 01, 2025", + use_instead="airflow.providers.google.cloud.hooks.generative_model." + "GenerativeModelHook.generative_model_generate_content", category=AirflowProviderDeprecationWarning, ) @GoogleBaseHook.fallback_to_default_project_id diff --git a/airflow/providers/google/cloud/links/automl.py b/airflow/providers/google/cloud/links/automl.py index 61e568dc79d30..6acdba096deea 100644 --- a/airflow/providers/google/cloud/links/automl.py +++ b/airflow/providers/google/cloud/links/automl.py @@ -21,10 +21,9 @@ from typing import TYPE_CHECKING -from deprecated import deprecated - from airflow.exceptions import AirflowProviderDeprecationWarning from airflow.providers.google.cloud.links.base import BaseGoogleLink +from airflow.providers.google.common.deprecated import deprecated if TYPE_CHECKING: from airflow.utils.context import Context @@ -48,9 +47,8 @@ @deprecated( - reason="The AutoMLDatasetLink class is deprecated and will be removed after 31.12.2024. " - "Please use TranslationLegacyDatasetLink class from " - "airflow/providers/google/cloud/links/translate.py instead.", + planned_removal_date="December 31, 2024", + use_instead="TranslationLegacyDatasetLink class from airflow/providers/google/cloud/links/translate.py", category=AirflowProviderDeprecationWarning, ) class AutoMLDatasetLink(BaseGoogleLink): @@ -75,9 +73,8 @@ def persist( @deprecated( - reason="The AutoMLDatasetListLink class is deprecated and will be removed after 31.12.2024. " - "Please use TranslationDatasetListLink class from " - "airflow/providers/google/cloud/links/translate.py instead.", + planned_removal_date="December 31, 2024", + use_instead="TranslationDatasetListLink class from airflow/providers/google/cloud/links/translate.py", category=AirflowProviderDeprecationWarning, ) class AutoMLDatasetListLink(BaseGoogleLink): @@ -103,9 +100,8 @@ def persist( @deprecated( - reason="The AutoMLModelLink class is deprecated and will be removed after 31.12.2024. " - "Please use TranslationLegacyModelLink class from " - "airflow/providers/google/cloud/links/translate.py instead.", + planned_removal_date="December 31, 2024", + use_instead="TranslationLegacyModelLink class from airflow/providers/google/cloud/links/translate.py", category=AirflowProviderDeprecationWarning, ) class AutoMLModelLink(BaseGoogleLink): @@ -136,9 +132,9 @@ def persist( @deprecated( - reason="The AutoMLModelTrainLink class is deprecated and will be removed after 31.12.2024. " - "Please use TranslationLegacyModelTrainLink class from " - "airflow/providers/google/cloud/links/translate.py instead.", + planned_removal_date="December 31, 2024", + use_instead="TranslationLegacyModelTrainLink class from " + "airflow/providers/google/cloud/links/translate.py", category=AirflowProviderDeprecationWarning, ) class AutoMLModelTrainLink(BaseGoogleLink): @@ -166,9 +162,9 @@ def persist( @deprecated( - reason="The AutoMLModelPredictLink class is deprecated and will be removed after 31.12.2024. " - "Please use TranslationLegacyModelPredictLink class from " - "airflow/providers/google/cloud/links/translate.py instead.", + planned_removal_date="December 31, 2024", + use_instead="TranslationLegacyModelPredictLink class from " + "airflow/providers/google/cloud/links/translate.py", category=AirflowProviderDeprecationWarning, ) class AutoMLModelPredictLink(BaseGoogleLink): diff --git a/airflow/providers/google/cloud/operators/bigquery.py b/airflow/providers/google/cloud/operators/bigquery.py index 83a9a19229228..1637f51d8f89e 100644 --- a/airflow/providers/google/cloud/operators/bigquery.py +++ b/airflow/providers/google/cloud/operators/bigquery.py @@ -27,7 +27,6 @@ from typing import TYPE_CHECKING, Any, Iterable, Sequence, SupportsAbs import attr -from deprecated import deprecated from google.api_core.exceptions import Conflict from google.cloud.bigquery import DEFAULT_RETRY, CopyJob, ExtractJob, LoadJob, QueryJob, Row from google.cloud.bigquery.table import RowIterator @@ -57,6 +56,7 @@ BigQueryValueCheckTrigger, ) from airflow.providers.google.cloud.utils.bigquery import convert_job_id +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID from airflow.utils.helpers import exactly_one @@ -1203,8 +1203,8 @@ def execute_complete(self, context: Context, event: dict[str, Any]) -> Any: @deprecated( - reason="The BigQueryExecuteQueryOperator is deprecated and will be removed after 01.11.2024. " - "Please use BigQueryInsertJobOperator instead.", + planned_removal_date="November 01, 2024", + use_instead="BigQueryInsertJobOperator", category=AirflowProviderDeprecationWarning, ) class BigQueryExecuteQueryOperator(GoogleCloudBaseOperator): @@ -1416,7 +1416,7 @@ def execute(self, context: Context): raise AirflowException(f"argument 'sql' of type {type(str)} is neither a string nor an iterable") project_id = self.hook.project_id if project_id: - job_id_path = convert_job_id(job_id=self.job_id, project_id=project_id, location=self.location) + job_id_path = convert_job_id(job_id=self.job_id, project_id=project_id, location=self.location) # type: ignore[arg-type] context["task_instance"].xcom_push(key="job_id_path", value=job_id_path) return self.job_id @@ -2299,8 +2299,8 @@ def execute(self, context: Context): @deprecated( - reason="The BigQueryPatchDatasetOperator is deprecated and will be removed after 01.11.2024. " - "Please use BigQueryUpdateDatasetOperator instead.", + planned_removal_date="November 01, 2024", + use_instead="BigQueryUpdateDatasetOperator", category=AirflowProviderDeprecationWarning, ) class BigQueryPatchDatasetOperator(GoogleCloudBaseOperator): diff --git a/airflow/providers/google/cloud/operators/dataflow.py b/airflow/providers/google/cloud/operators/dataflow.py index c2acebddcbc9e..625356d50e0ad 100644 --- a/airflow/providers/google/cloud/operators/dataflow.py +++ b/airflow/providers/google/cloud/operators/dataflow.py @@ -27,7 +27,6 @@ from functools import cached_property from typing import TYPE_CHECKING, Any, Sequence -from deprecated import deprecated from googleapiclient.errors import HttpError from airflow.configuration import conf @@ -43,6 +42,7 @@ from airflow.providers.google.cloud.operators.cloud_base import GoogleCloudBaseOperator from airflow.providers.google.cloud.triggers.dataflow import TemplateJobStartTrigger from airflow.providers.google.common.consts import GOOGLE_DEFAULT_DEFERRABLE_METHOD_NAME +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID from airflow.version import version @@ -174,8 +174,8 @@ def __init__( # TODO: Remove one day @deprecated( - reason="The DataflowCreateJavaJobOperator class is deprecated and will be removed after 01.11.2024. " - "Please use providers.apache.beam.operators.beam.BeamRunJavaPipelineOperator class instead.", + planned_removal_date="November 01, 2024", + use_instead="providers.apache.beam.operators.beam.BeamRunJavaPipelineOperator", category=AirflowProviderDeprecationWarning, ) class DataflowCreateJavaJobOperator(GoogleCloudBaseOperator): @@ -1053,8 +1053,8 @@ def on_kill(self) -> None: # TODO: Remove one day @deprecated( - reason="The DataflowCreatePythonJobOperator class is deprecated and will be removed after 01.11.2024. " - "Please use providers.apache.beam.operators.beam.BeamRunPythonPipelineOperator class instead.", + planned_removal_date="November 01, 2024", + use_instead="providers.apache.beam.operators.beam.BeamRunPythonPipelineOperator", category=AirflowProviderDeprecationWarning, ) class DataflowCreatePythonJobOperator(GoogleCloudBaseOperator): diff --git a/airflow/providers/google/cloud/operators/datafusion.py b/airflow/providers/google/cloud/operators/datafusion.py index 01c70dfc0a6aa..4960432e85988 100644 --- a/airflow/providers/google/cloud/operators/datafusion.py +++ b/airflow/providers/google/cloud/operators/datafusion.py @@ -21,7 +21,6 @@ import time from typing import TYPE_CHECKING, Any, Sequence -from deprecated import deprecated from google.api_core.retry import exponential_sleep_generator from googleapiclient.errors import HttpError @@ -37,6 +36,7 @@ from airflow.providers.google.cloud.triggers.datafusion import DataFusionStartPipelineTrigger from airflow.providers.google.cloud.utils.datafusion import DataFusionPipelineType from airflow.providers.google.cloud.utils.helpers import resource_path_to_dict +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID if TYPE_CHECKING: @@ -53,8 +53,8 @@ class DataFusionPipelineLinkHelper: @staticmethod @deprecated( - reason="The get_project_id method is deprecated and will be removed after 01.03.2025. " - "Please use airflow.providers.google.cloud.utils.helpers.resource_path_to_dict method instead.", + planned_removal_date="March 01, 2025", + use_instead="airflow.providers.google.cloud.utils.helpers.resource_path_to_dict", category=AirflowProviderDeprecationWarning, ) def get_project_id(instance): diff --git a/airflow/providers/google/cloud/operators/datapipeline.py b/airflow/providers/google/cloud/operators/datapipeline.py index 863e064eb12fd..d9188d1658531 100644 --- a/airflow/providers/google/cloud/operators/datapipeline.py +++ b/airflow/providers/google/cloud/operators/datapipeline.py @@ -19,20 +19,19 @@ from __future__ import annotations -from deprecated import deprecated - from airflow.exceptions import AirflowProviderDeprecationWarning from airflow.providers.google.cloud.hooks.dataflow import DEFAULT_DATAFLOW_LOCATION from airflow.providers.google.cloud.operators.dataflow import ( DataflowCreatePipelineOperator, DataflowRunPipelineOperator, ) +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID @deprecated( - reason="The CreateDataPipelineOperator is deprecated and will be removed after 01.12.2024. " - "Please use DataflowCreatePipelineOperator class instead.", + planned_removal_date="December 01, 2024", + use_instead="DataflowCreatePipelineOperator", category=AirflowProviderDeprecationWarning, ) class CreateDataPipelineOperator(DataflowCreatePipelineOperator): @@ -40,8 +39,8 @@ class CreateDataPipelineOperator(DataflowCreatePipelineOperator): @deprecated( - reason="The RunDataPipelineOperator is deprecated and will be removed after 01.12.2024. " - "Please use DataflowRunPipelineOperator class instead.", + planned_removal_date="December 01, 2024", + use_instead="DataflowRunPipelineOperator", category=AirflowProviderDeprecationWarning, ) class RunDataPipelineOperator(DataflowRunPipelineOperator): diff --git a/airflow/providers/google/cloud/operators/dataproc.py b/airflow/providers/google/cloud/operators/dataproc.py index c164197fbe0e0..38a364036c0e2 100644 --- a/airflow/providers/google/cloud/operators/dataproc.py +++ b/airflow/providers/google/cloud/operators/dataproc.py @@ -33,7 +33,6 @@ from functools import cached_property from typing import TYPE_CHECKING, Any, Sequence -from deprecated import deprecated from google.api_core.exceptions import AlreadyExists, NotFound from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault from google.api_core.retry import Retry, exponential_sleep_generator @@ -64,6 +63,7 @@ DataprocSubmitTrigger, ) from airflow.providers.google.cloud.utils.dataproc import DataprocOperationType +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID from airflow.utils import timezone @@ -882,8 +882,8 @@ def execute_complete(self, context: Context, event: dict[str, Any]) -> Any: # TODO: Remove one day @deprecated( - reason="The DataprocScaleClusterOperator is deprecated and will be removed after 01.03.2025. " - "Please use DataprocUpdateClusterOperator class instead.", + planned_removal_date="March 01, 2025", + use_instead="DataprocUpdateClusterOperator", category=AirflowProviderDeprecationWarning, ) class DataprocScaleClusterOperator(GoogleCloudBaseOperator): @@ -1504,11 +1504,10 @@ def on_kill(self) -> None: self.hook.cancel_job(project_id=self.project_id, job_id=self.dataproc_job_id, region=self.region) -# TODO: Remove one day @deprecated( - reason="The DataprocSubmitPigJobOperator is deprecated and will be removed after 01.11.2024. " - "Please use DataprocSubmitJobOperator class instead. " - "You can use `generate_job` method to generate dictionary representing your job " + planned_removal_date="November 01, 2024", + use_instead="DataprocSubmitJobOperator", + instructions="You can use `generate_job` method to generate dictionary representing your job " "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) @@ -1630,11 +1629,14 @@ def execute(self, context: Context): super().execute(context) +# TODO: Remove one day + + # TODO: Remove one day @deprecated( - reason="The DataprocSubmitHiveJobOperator is deprecated and will be removed after 01.11.2024. " - "Please use DataprocSubmitJobOperator class instead. " - "You can use `generate_job` method to generate dictionary representing your job " + planned_removal_date="November 01, 2024", + use_instead="DataprocSubmitJobOperator", + instructions="You can use `generate_job` method to generate dictionary representing your job " "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) @@ -1724,9 +1726,9 @@ def execute(self, context: Context): # TODO: Remove one day @deprecated( - reason="The DataprocSubmitSparkSqlJobOperator is deprecated and will be removed after 01.11.2024. " - "Please use DataprocSubmitJobOperator class instead. " - "You can use `generate_job` method to generate dictionary representing your job " + planned_removal_date="November 01, 2024", + use_instead="DataprocSubmitJobOperator", + instructions="You can use `generate_job` method to generate dictionary representing your job " "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) @@ -1815,9 +1817,9 @@ def execute(self, context: Context): # TODO: Remove one day @deprecated( - reason="The DataprocSubmitSparkJobOperator is deprecated and will be removed after 01.11.2024. " - "Please use DataprocSubmitJobOperator class instead. " - "You can use `generate_job` method to generate dictionary representing your job " + planned_removal_date="November 01, 2024", + use_instead="DataprocSubmitJobOperator", + instructions="You can use `generate_job` method to generate dictionary representing your job " "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) @@ -1906,9 +1908,9 @@ def execute(self, context: Context): # TODO: Remove one day @deprecated( - reason="The DataprocSubmitHadoopJobOperator is deprecated and will be removed after 01.11.2024. " - "Please use DataprocSubmitJobOperator class instead. " - "You can use `generate_job` method to generate dictionary representing your job " + planned_removal_date="November 01, 2024", + use_instead="DataprocSubmitJobOperator", + instructions="You can use `generate_job` method to generate dictionary representing your job " "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) @@ -1997,9 +1999,9 @@ def execute(self, context: Context): # TODO: Remove one day @deprecated( - reason="The DataprocSubmitPySparkJobOperator is deprecated and will be removed after 01.11.2024. " - "Please use DataprocSubmitJobOperator class instead. " - "You can use `generate_job` method to generate dictionary representing your job " + planned_removal_date="November 01, 2024", + use_instead="DataprocSubmitJobOperator", + instructions="You can use `generate_job` method to generate dictionary representing your job " "and use it with the new operator.", category=AirflowProviderDeprecationWarning, ) diff --git a/airflow/providers/google/cloud/operators/kubernetes_engine.py b/airflow/providers/google/cloud/operators/kubernetes_engine.py index 2174755ec64e2..c19bc4ff50851 100644 --- a/airflow/providers/google/cloud/operators/kubernetes_engine.py +++ b/airflow/providers/google/cloud/operators/kubernetes_engine.py @@ -25,7 +25,6 @@ import requests import yaml -from deprecated import deprecated from google.api_core.exceptions import AlreadyExists from google.cloud.container_v1.types import Cluster from kubernetes.client import V1JobList, models as k8s @@ -57,6 +56,7 @@ GKEOperationTrigger, GKEStartPodTrigger, ) +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID from airflow.providers_manager import ProvidersManager from airflow.utils.timezone import utcnow @@ -725,8 +725,8 @@ def __init__( @staticmethod @deprecated( - reason="The get_gke_config_file method is deprecated and will be removed after 01.11.2024. " - "Please use `fetch_cluster_info` instead to get the cluster info for connecting to it.", + planned_removal_date="November 01, 2024", + use_instead="fetch_cluster_info", category=AirflowProviderDeprecationWarning, ) def get_gke_config_file(): diff --git a/airflow/providers/google/cloud/operators/life_sciences.py b/airflow/providers/google/cloud/operators/life_sciences.py index e815e56675feb..d79aae83bd349 100644 --- a/airflow/providers/google/cloud/operators/life_sciences.py +++ b/airflow/providers/google/cloud/operators/life_sciences.py @@ -21,12 +21,11 @@ from typing import TYPE_CHECKING, Sequence -from deprecated import deprecated - from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning from airflow.providers.google.cloud.hooks.life_sciences import LifeSciencesHook from airflow.providers.google.cloud.links.life_sciences import LifeSciencesLink from airflow.providers.google.cloud.operators.cloud_base import GoogleCloudBaseOperator +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID if TYPE_CHECKING: @@ -34,9 +33,9 @@ @deprecated( - reason="The LifeSciencesRunPipelineOperator class is deprecated and will be removed after 08.07.2025. " - "Please use Google Cloud Batch Operators instead. " - "The Life Sciences API (beta) will be discontinued " + planned_removal_date="July 08, 2025", + use_instead="Google Cloud Batch Operators", + reason="The Life Sciences API (beta) will be discontinued " "on July 8, 2025 in favor of Google Cloud Batch.", category=AirflowProviderDeprecationWarning, ) diff --git a/airflow/providers/google/cloud/operators/mlengine.py b/airflow/providers/google/cloud/operators/mlengine.py index 2adacee71c220..4da055075e9a7 100644 --- a/airflow/providers/google/cloud/operators/mlengine.py +++ b/airflow/providers/google/cloud/operators/mlengine.py @@ -24,7 +24,6 @@ import time from typing import TYPE_CHECKING, Any, Sequence -from deprecated import deprecated from googleapiclient.errors import HttpError from airflow.configuration import conf @@ -39,6 +38,7 @@ ) from airflow.providers.google.cloud.operators.cloud_base import GoogleCloudBaseOperator from airflow.providers.google.cloud.triggers.mlengine import MLEngineStartTrainingJobTrigger +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID if TYPE_CHECKING: @@ -80,9 +80,9 @@ def _normalize_mlengine_job_id(job_id: str) -> str: @deprecated( - reason="The MLEngineStartBatchPredictionJobOperator is deprecated and will be removed after 01.03.2025. " - "Please use CreateBatchPredictionJobOperator class instead." - "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", + planned_removal_date="March 01, 2025", + use_instead="CreateBatchPredictionJobOperator", + reason="All the functionality of legacy MLEngine and new features are available on the Vertex AI.", category=AirflowProviderDeprecationWarning, ) class MLEngineStartBatchPredictionJobOperator(GoogleCloudBaseOperator): @@ -295,9 +295,8 @@ def check_existing_job(existing_job): @deprecated( - reason="The MLEngineManageModelOperator is deprecated and will be removed after 01.03.2025. " - "Please use one of the following operators for specific operations: " - "MLEngineCreateModelOperator, MLEngineGetModelOperator.", + planned_removal_date="March 01, 2025", + use_instead="MLEngineCreateModelOperator, MLEngineGetModelOperator", category=AirflowProviderDeprecationWarning, ) class MLEngineManageModelOperator(GoogleCloudBaseOperator): @@ -369,9 +368,9 @@ def execute(self, context: Context): @deprecated( - reason="The MLEngineCreateModelOperator is deprecated and will be removed after 01.11.2025. " - "Please use appropriate VertexAI operator instead. " - "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", + planned_removal_date="November 01, 2025", + use_instead="appropriate VertexAI operator", + reason="All the functionality of legacy MLEngine and new features are available on the Vertex AI.", category=AirflowProviderDeprecationWarning, ) class MLEngineCreateModelOperator(GoogleCloudBaseOperator): @@ -443,9 +442,9 @@ def execute(self, context: Context): @deprecated( - reason="The MLEngineGetModelOperator is deprecated and will be removed after 01.03.2025. " - "Please use GetModelOperator class instead. " - "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", + planned_removal_date="March 01, 2025", + use_instead="GetModelOperator", + reason="All the functionality of legacy MLEngine and new features are available on the Vertex AI.", category=AirflowProviderDeprecationWarning, ) class MLEngineGetModelOperator(GoogleCloudBaseOperator): @@ -516,9 +515,9 @@ def execute(self, context: Context): @deprecated( - reason="The MLEngineDeleteModelOperator is deprecated and will be removed after 01.03.2025. " - "Please use DeleteModelOperator class instead. " - "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", + planned_removal_date="March 01, 2025", + use_instead="DeleteModelOperator", + reason="All the functionality of legacy MLEngine and new features are available on the Vertex AI.", category=AirflowProviderDeprecationWarning, ) class MLEngineDeleteModelOperator(GoogleCloudBaseOperator): @@ -597,9 +596,9 @@ def execute(self, context: Context): @deprecated( - reason="The MLEngineManageVersionOperator is deprecated and will be removed after 01.03.2025. " - "Please use the following operators instead: " - "MLEngineCreateVersion, MLEngineSetDefaultVersion, MLEngineListVersions, MLEngineDeleteVersion.", + planned_removal_date="March 01, 2025", + use_instead="MLEngineCreateVersion, MLEngineSetDefaultVersion, MLEngineListVersions, " + "MLEngineDeleteVersion", category=AirflowProviderDeprecationWarning, ) class MLEngineManageVersionOperator(GoogleCloudBaseOperator): @@ -714,9 +713,9 @@ def execute(self, context: Context): @deprecated( - reason="The MLEngineCreateVersionOperator is deprecated and will be removed after 01.03.2025. " - "Please use parent_model parameter for VertexAI operators instead. " - "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", + planned_removal_date="March 01, 2025", + use_instead="parent_model parameter for VertexAI operators", + reason="All the functionality of legacy MLEngine and new features are available on the Vertex AI.", category=AirflowProviderDeprecationWarning, ) class MLEngineCreateVersionOperator(GoogleCloudBaseOperator): @@ -803,9 +802,9 @@ def execute(self, context: Context): @deprecated( - reason="The MLEngineSetDefaultVersionOperator is deprecated and will be removed after 01.03.2025. " - "Please use SetDefaultVersionOnModelOperator class instead. " - "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", + planned_removal_date="March 01, 2025", + use_instead="SetDefaultVersionOnModelOperator", + reason="All the functionality of legacy MLEngine and new features are available on the Vertex AI.", category=AirflowProviderDeprecationWarning, ) class MLEngineSetDefaultVersionOperator(GoogleCloudBaseOperator): @@ -894,9 +893,9 @@ def execute(self, context: Context): @deprecated( - reason="The MLEngineListVersionsOperator is deprecated and will be removed after 01.03.2025. " - "Please use ListModelVersionsOperator class instead. " - "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", + planned_removal_date="March 01, 2025", + use_instead="istModelVersionsOperator", + reason="All the functionality of legacy MLEngine and new features are available on the Vertex AI.", category=AirflowProviderDeprecationWarning, ) class MLEngineListVersionsOperator(GoogleCloudBaseOperator): @@ -978,9 +977,9 @@ def execute(self, context: Context): @deprecated( - reason="The MLEngineDeleteVersionOperator is deprecated and will be removed after 01.03.2025. " - "Please use DeleteModelVersionOperator class instead. " - "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", + planned_removal_date="March 01, 2025", + use_instead="DeleteModelVersionOperator", + reason="All the functionality of legacy MLEngine and new features are available on the Vertex AI.", category=AirflowProviderDeprecationWarning, ) class MLEngineDeleteVersionOperator(GoogleCloudBaseOperator): @@ -1068,9 +1067,9 @@ def execute(self, context: Context): @deprecated( - reason="The MLEngineStartTrainingJobOperator is deprecated and will be removed after 01.03.2025. " - "Please use CreateCustomPythonPackageTrainingJobOperator class instead. " - "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", + planned_removal_date="March 01, 2025", + use_instead="CreateCustomPythonPackageTrainingJobOperator", + reason="All the functionality of legacy MLEngine and new features are available on the Vertex AI.", category=AirflowProviderDeprecationWarning, ) class MLEngineStartTrainingJobOperator(GoogleCloudBaseOperator): @@ -1405,9 +1404,9 @@ def on_kill(self) -> None: @deprecated( - reason="The MLEngineTrainingCancelJobOperator is deprecated and will be removed after 01.03.2025. " - "Please use CancelCustomTrainingJobOperator class instead. " - "All the functionality of legacy MLEngine and new features are available on the Vertex AI platform.", + planned_removal_date="March 01, 2025", + use_instead="CancelCustomTrainingJobOperator", + reason="All the functionality of legacy MLEngine and new features are available on the Vertex AI.", category=AirflowProviderDeprecationWarning, ) class MLEngineTrainingCancelJobOperator(GoogleCloudBaseOperator): @@ -1458,8 +1457,8 @@ def __init__( @property @deprecated( - reason="The _project_id method is deprecated and will be removed after 01.03.2025. " - "Please use project_id method instead.", + planned_removal_date="March 01, 2025", + use_instead="project_id", category=AirflowProviderDeprecationWarning, ) def _project_id(self): @@ -1468,8 +1467,8 @@ def _project_id(self): @property @deprecated( - reason="The _job_id method is deprecated and will be removed after 01.03.2025. " - "Please use job_id method instead.", + planned_removal_date="March 01, 2025", + use_instead="job_id", category=AirflowProviderDeprecationWarning, ) def _job_id(self): @@ -1478,8 +1477,8 @@ def _job_id(self): @property @deprecated( - reason="The _impersonation_chain method is deprecated and will be removed after 01.03.2025. " - "Please use impersonation_chain method instead.", + planned_removal_date="March 01, 2025", + use_instead="impersonation_chain", category=AirflowProviderDeprecationWarning, ) def _impersonation_chain(self): diff --git a/airflow/providers/google/cloud/operators/vertex_ai/auto_ml.py b/airflow/providers/google/cloud/operators/vertex_ai/auto_ml.py index 4092fe415f6f1..76319b892edec 100644 --- a/airflow/providers/google/cloud/operators/vertex_ai/auto_ml.py +++ b/airflow/providers/google/cloud/operators/vertex_ai/auto_ml.py @@ -22,7 +22,6 @@ from typing import TYPE_CHECKING, Sequence -from deprecated import deprecated from google.api_core.exceptions import NotFound from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault from google.cloud.aiplatform import datasets @@ -37,6 +36,7 @@ VertexAITrainingPipelinesLink, ) from airflow.providers.google.cloud.operators.cloud_base import GoogleCloudBaseOperator +from airflow.providers.google.common.deprecated import deprecated if TYPE_CHECKING: from google.api_core.retry import Retry @@ -642,8 +642,8 @@ def __init__( @property @deprecated( - reason="The training_pipeline method is deprecated and will be removed after 01.03.2025. " - "Please use training_pipeline_id instead.", + planned_removal_date="March 01, 2025", + use_instead="training_pipeline_id", category=AirflowProviderDeprecationWarning, ) def training_pipeline(self): diff --git a/airflow/providers/google/cloud/operators/vertex_ai/custom_job.py b/airflow/providers/google/cloud/operators/vertex_ai/custom_job.py index dde39e84c0d8b..854101a72e34d 100644 --- a/airflow/providers/google/cloud/operators/vertex_ai/custom_job.py +++ b/airflow/providers/google/cloud/operators/vertex_ai/custom_job.py @@ -23,7 +23,6 @@ from functools import cached_property from typing import TYPE_CHECKING, Any, Sequence -from deprecated import deprecated from google.api_core.exceptions import NotFound from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault from google.cloud.aiplatform.models import Model @@ -44,6 +43,7 @@ CustomPythonPackageTrainingJobTrigger, CustomTrainingJobTrigger, ) +from airflow.providers.google.common.deprecated import deprecated if TYPE_CHECKING: from google.api_core.retry import Retry @@ -1633,8 +1633,8 @@ def __init__( @property @deprecated( - reason="The training_pipeline method is deprecated and will be removed after 01.03.2025. " - "Please use training_pipeline_id method instead.", + planned_removal_date="March 01, 2025", + use_instead="training_pipeline_id", category=AirflowProviderDeprecationWarning, ) def training_pipeline(self): @@ -1643,8 +1643,8 @@ def training_pipeline(self): @property @deprecated( - reason="The custom_job method is deprecated and will be removed after 01.03.2025. " - "Please use custom_job_id method instead.", + planned_removal_date="March 01, 2025", + use_instead="custom_job_id", category=AirflowProviderDeprecationWarning, ) def custom_job(self): diff --git a/airflow/providers/google/cloud/operators/vertex_ai/generative_model.py b/airflow/providers/google/cloud/operators/vertex_ai/generative_model.py index c8fa1f8fee0f5..13e76cd17c7c6 100644 --- a/airflow/providers/google/cloud/operators/vertex_ai/generative_model.py +++ b/airflow/providers/google/cloud/operators/vertex_ai/generative_model.py @@ -21,20 +21,20 @@ from typing import TYPE_CHECKING, Sequence -from deprecated import deprecated from google.cloud.aiplatform_v1 import types from airflow.exceptions import AirflowProviderDeprecationWarning from airflow.providers.google.cloud.hooks.vertex_ai.generative_model import GenerativeModelHook from airflow.providers.google.cloud.operators.cloud_base import GoogleCloudBaseOperator +from airflow.providers.google.common.deprecated import deprecated if TYPE_CHECKING: from airflow.utils.context import Context @deprecated( - reason="The PromptLanguageModelOperator is deprecated and will be removed after 01.01.2025. " - "Please use TextGenerationModelPredictOperator instead.", + planned_removal_date="January 01, 2025", + use_instead="TextGenerationModelPredictOperator", category=AirflowProviderDeprecationWarning, ) class PromptLanguageModelOperator(GoogleCloudBaseOperator): @@ -123,8 +123,8 @@ def execute(self, context: Context): @deprecated( - reason="The GenerateTextEmbeddingsOperator is deprecated and will be removed after 01.01.2025. " - "Please use TextEmbeddingModelGetEmbeddingsOperator instead.", + planned_removal_date="January 01, 2025", + use_instead="TextEmbeddingModelGetEmbeddingsOperator", category=AirflowProviderDeprecationWarning, ) class GenerateTextEmbeddingsOperator(GoogleCloudBaseOperator): @@ -192,8 +192,8 @@ def execute(self, context: Context): @deprecated( - reason="The PromptMultimodalModelOperator is deprecated and will be removed after 01.01.2025. " - "Please use GenerativeModelGenerateContentOperator instead.", + planned_removal_date="January 01, 2025", + use_instead="GenerativeModelGenerateContentOperator", category=AirflowProviderDeprecationWarning, ) class PromptMultimodalModelOperator(GoogleCloudBaseOperator): @@ -269,8 +269,8 @@ def execute(self, context: Context): @deprecated( - reason="The PromptMultimodalModelWithMediaOperator is deprecated and will be removed after 01.01.2025. " - "Please use GenerativeModelGenerateContentOperator instead.", + planned_removal_date="January 01, 2025", + use_instead="GenerativeModelGenerateContentOperator", category=AirflowProviderDeprecationWarning, ) class PromptMultimodalModelWithMediaOperator(GoogleCloudBaseOperator): diff --git a/airflow/providers/google/cloud/secrets/secret_manager.py b/airflow/providers/google/cloud/secrets/secret_manager.py index e7440322de205..dde659020a82a 100644 --- a/airflow/providers/google/cloud/secrets/secret_manager.py +++ b/airflow/providers/google/cloud/secrets/secret_manager.py @@ -21,7 +21,6 @@ import logging from typing import Sequence -from deprecated import deprecated from google.auth.exceptions import DefaultCredentialsError from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning @@ -30,6 +29,7 @@ _get_target_principal_and_delegates, get_credentials_and_project_id, ) +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID from airflow.secrets import BaseSecretsBackend from airflow.utils.log.logging_mixin import LoggingMixin @@ -162,8 +162,8 @@ def get_conn_value(self, conn_id: str) -> str | None: return self._get_secret(self.connections_prefix, conn_id) @deprecated( - reason="The method get_conn_uri is deprecated and will be removed after 01.11.2024. " - "Please use get_conn_value method instead.", + planned_removal_date="November 01, 2024", + use_instead="get_conn_value", category=AirflowProviderDeprecationWarning, ) def get_conn_uri(self, conn_id: str) -> str | None: diff --git a/airflow/providers/google/cloud/sensors/bigquery.py b/airflow/providers/google/cloud/sensors/bigquery.py index 0538013d1c094..7a866c7b0ac6f 100644 --- a/airflow/providers/google/cloud/sensors/bigquery.py +++ b/airflow/providers/google/cloud/sensors/bigquery.py @@ -23,8 +23,6 @@ from datetime import timedelta from typing import TYPE_CHECKING, Any, Sequence -from deprecated import deprecated - from airflow.configuration import conf from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning from airflow.providers.google.cloud.hooks.bigquery import BigQueryHook @@ -32,6 +30,7 @@ BigQueryTableExistenceTrigger, BigQueryTablePartitionExistenceTrigger, ) +from airflow.providers.google.common.deprecated import deprecated from airflow.sensors.base import BaseSensorOperator if TYPE_CHECKING: @@ -261,8 +260,9 @@ def execute_complete(self, context: dict[str, Any], event: dict[str, str] | None @deprecated( - reason="The BigQueryTableExistenceAsyncSensor is deprecated and will be removed after 01.11.2024. " - "Please use BigQueryTableExistenceSensor and set deferrable attribute to True instead.", + planned_removal_date="November 01, 2024", + use_instead="BigQueryTableExistenceSensor", + instructions="Please use BigQueryTableExistenceSensor and set deferrable attribute to True.", category=AirflowProviderDeprecationWarning, ) class BigQueryTableExistenceAsyncSensor(BigQueryTableExistenceSensor): @@ -299,9 +299,9 @@ def __init__(self, **kwargs): @deprecated( - reason="The BigQueryTableExistencePartitionAsyncSensor is deprecated " - "and will be removed after 01.11.2024. " - "Please use BigQueryTablePartitionExistenceSensor class and set deferrable attribute to True instead.", + planned_removal_date="November 01, 2024", + use_instead="BigQueryTablePartitionExistenceSensor", + instructions="Please use BigQueryTablePartitionExistenceSensor and set deferrable attribute to True.", category=AirflowProviderDeprecationWarning, ) class BigQueryTableExistencePartitionAsyncSensor(BigQueryTablePartitionExistenceSensor): diff --git a/airflow/providers/google/cloud/sensors/cloud_composer.py b/airflow/providers/google/cloud/sensors/cloud_composer.py index 0849d533de11d..40703c02fe2ae 100644 --- a/airflow/providers/google/cloud/sensors/cloud_composer.py +++ b/airflow/providers/google/cloud/sensors/cloud_composer.py @@ -24,7 +24,6 @@ from typing import TYPE_CHECKING, Any, Iterable, Sequence from dateutil import parser -from deprecated import deprecated from google.cloud.orchestration.airflow.service_v1.types import ExecuteAirflowCommandResponse from airflow.configuration import conf @@ -35,6 +34,7 @@ CloudComposerExecutionTrigger, ) from airflow.providers.google.common.consts import GOOGLE_DEFAULT_DEFERRABLE_METHOD_NAME +from airflow.providers.google.common.deprecated import deprecated from airflow.sensors.base import BaseSensorOperator from airflow.utils.state import TaskInstanceState @@ -43,13 +43,13 @@ @deprecated( - reason=( - "The CloudComposerEnvironmentSensor operator is deprecated and will be removed after 01.11.2024. " - "Please use CloudComposerCreateEnvironmentOperator, CloudComposerDeleteEnvironmentOperator or " - "CloudComposerUpdateEnvironmentOperator in deferrable or non-deferrable mode, " - "since since every operator gives user a possibility to wait (asynchronously or synchronously) " - "until the Operation is finished." - ), + planned_removal_date="November 01, 2024", + use_instead="CloudComposerCreateEnvironmentOperator, CloudComposerDeleteEnvironmentOperator, " + "CloudComposerUpdateEnvironmentOperator", + instructions="Please use CloudComposerCreateEnvironmentOperator, CloudComposerDeleteEnvironmentOperator " + "or CloudComposerUpdateEnvironmentOperator in deferrable or non-deferrable mode, " + "since since every operator gives user a possibility to wait (asynchronously or synchronously) " + "until the Operation is finished.", category=AirflowProviderDeprecationWarning, ) class CloudComposerEnvironmentSensor(BaseSensorOperator): diff --git a/airflow/providers/google/cloud/sensors/gcs.py b/airflow/providers/google/cloud/sensors/gcs.py index def5e722ec3c4..0d01f663fa37f 100644 --- a/airflow/providers/google/cloud/sensors/gcs.py +++ b/airflow/providers/google/cloud/sensors/gcs.py @@ -24,7 +24,6 @@ from datetime import datetime, timedelta from typing import TYPE_CHECKING, Any, Callable, Sequence -from deprecated import deprecated from google.cloud.storage.retry import DEFAULT_RETRY from airflow.configuration import conf @@ -36,6 +35,7 @@ GCSPrefixBlobTrigger, GCSUploadSessionTrigger, ) +from airflow.providers.google.common.deprecated import deprecated from airflow.sensors.base import BaseSensorOperator, poke_mode_only if TYPE_CHECKING: @@ -143,8 +143,9 @@ def execute_complete(self, context: Context, event: dict[str, str]) -> bool: @deprecated( - reason="The GCSObjectExistenceAsyncSensor is deprecated and will be removed after 01.11.2024. " - "Please use GCSObjectExistenceSensor and set deferrable attribute to True instead.", + planned_removal_date="November 01, 2024", + use_instead="GCSObjectExistenceSensor", + instructions="Please use GCSObjectExistenceSensor and set deferrable attribute to True.", category=AirflowProviderDeprecationWarning, ) class GCSObjectExistenceAsyncSensor(GCSObjectExistenceSensor): diff --git a/airflow/providers/google/common/deprecated.py b/airflow/providers/google/common/deprecated.py new file mode 100644 index 0000000000000..8da1618d9f716 --- /dev/null +++ b/airflow/providers/google/common/deprecated.py @@ -0,0 +1,176 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import inspect +import re +from datetime import date, datetime +from typing import Any, Callable + +from deprecated import deprecated as standard_deprecated +from deprecated.classic import ClassicAdapter + + +class AirflowDeprecationAdapter(ClassicAdapter): + """ + Build a detailed deprecation message based on the wrapped object type and other provided details. + + :param planned_removal_date: The date after which the deprecated object should be removed. + The recommended date is six months ahead from today. The expected date format is `Month DD, YYYY`, + for example: `August 22, 2024`. + This parameter is required if the `planned_removal_release` parameter is not set. + :param planned_removal_release: The package name and the version in which the deprecated object is + expected to be removed. The expected format is `==`, for example + `apache-airflow==2.10.0` or `apache-airflow-providers-google==10.22.0`. + This parameter is required if the `planned_removal_date` parameter is not set. + :param use_instead: Optional. Replacement of the deprecated object. + :param reason: Optional. The detailed reason for the deprecated object. + :param instructions: Optional. The detailed instructions for migrating from the deprecated object. + :param category: Optional. The warning category to be used for the deprecation warning. + """ + + def __init__( + self, + planned_removal_date: str | None = None, + planned_removal_release: str | None = None, + use_instead: str | None = None, + reason: str | None = None, + instructions: str | None = None, + category: type[DeprecationWarning] = DeprecationWarning, + **kwargs: Any, + ): + super().__init__(**kwargs) + self.planned_removal_date: date | None = self._validate_date(planned_removal_date) + self.planned_removal_release: str | None = self._validate_removal_release(planned_removal_release) + self.use_instead: str | None = use_instead + self.reason: str = reason or "" + self.instructions: str | None = instructions + self.category: type[DeprecationWarning] = category + self._validate_fields() + + def get_deprecated_msg(self, wrapped: Callable, instance: Any): + """ + Generate a deprecation message for wrapped callable. + + :param wrapped: Deprecated entity. + :param instance: The instance to which the callable belongs. (not used) + :return: A formatted deprecation message with all the details. + """ + entity_type = self.entity_type(entity=wrapped) + entity_path = self.entity_path(entity=wrapped) + sunset = self.sunset_message() + replacement = self.replacement_message() + msg = f"The {entity_type} `{entity_path}` is deprecated and will be removed {sunset}. {replacement}" + if self.reason: + msg += f" The reason is: {self.reason}" + if self.instructions: + msg += f" Instructions: {self.instructions}" + return msg + + @staticmethod + def _validate_date(value: str | None) -> date | None: + if value: + try: + return datetime.strptime(value, "%B %d, %Y").date() + except ValueError as ex: + error_message = ( + f"Invalid date '{value}'. " + f"The expected format is 'Month DD, YYYY', for example 'August 22, 2024'." + ) + raise ValueError(error_message) from ex + return None + + @staticmethod + def _validate_removal_release(value: str | None) -> str | None: + if value: + pattern = r"^apache-airflow(-providers-[a-zA-Z-]+)?==\d+\.\d+\.\d+.*$" + if not bool(re.match(pattern, value)): + raise ValueError( + f"`{value}` must follow the format 'apache-airflow(-providers-)=='." + ) + return value + + def _validate_fields(self): + msg = "Only one of two parameters must be set: `planned_removal_date` or 'planned_removal_release'." + if self.planned_removal_release and self.planned_removal_date: + raise ValueError(f"{msg} You specified both.") + + @staticmethod + def entity_type(entity: Callable) -> str: + return "class" if inspect.isclass(entity) else "function (or method)" + + @staticmethod + def entity_path(entity: Callable) -> str: + module_name = getattr(entity, "__module__", "") + qualified_name = getattr(entity, "__qualname__", "") + full_path = f"{module_name}.{qualified_name}".strip(".") + + if module_name and full_path: + return full_path + return str(entity) + + def sunset_message(self) -> str: + if self.planned_removal_date: + return f"after {self.planned_removal_date.strftime('%B %d, %Y')}" + if self.planned_removal_release: + return f"since version {self.planned_removal_release}" + return "in the future" + + def replacement_message(self): + if self.use_instead: + replacements = ", ".join(f"`{replacement}`" for replacement in self.use_instead.split(", ")) + return f"Please use {replacements} instead." + return "There is no replacement." + + +def deprecated( + *args, + planned_removal_date: str | None = None, + planned_removal_release: str | None = None, + use_instead: str | None = None, + reason: str | None = None, + instructions: str | None = None, + adapter_cls: type[AirflowDeprecationAdapter] = AirflowDeprecationAdapter, + **kwargs, +): + """ + Mark a class, method or a function deprecated. + + :param planned_removal_date: The date after which the deprecated object should be removed. + The recommended date is six months ahead from today. The expected date format is `Month DD, YYYY`, + for example: `August 22, 2024`. + This parameter is required if the `planned_removal_release` parameter is not set. + :param planned_removal_release: The package name and the version in which the deprecated object is + expected to be removed. The expected format is `==`, for example + `apache-airflow==2.10.0` or `apache-airflow-providers-google==10.22.0`. + This parameter is required if the `planned_removal_date` parameter is not set. + :param use_instead: Optional. Replacement of the deprecated object. + :param reason: Optional. The detailed reason for the deprecated object. + :param instructions: Optional. The detailed instructions for migrating from the deprecated object. + :param adapter_cls: Optional. Adapter class that is used to get the deprecation message + This should be a subclass of `AirflowDeprecationAdapter`. + """ + _kwargs = { + **kwargs, + "planned_removal_date": planned_removal_date, + "planned_removal_release": planned_removal_release, + "use_instead": use_instead, + "reason": reason, + "instructions": instructions, + "adapter_cls": adapter_cls, + } + return standard_deprecated(*args, **_kwargs) diff --git a/airflow/providers/google/common/hooks/base_google.py b/airflow/providers/google/common/hooks/base_google.py index ecb07c6a4d1c8..c55ac27aa0ec4 100644 --- a/airflow/providers/google/common/hooks/base_google.py +++ b/airflow/providers/google/common/hooks/base_google.py @@ -36,7 +36,6 @@ import requests import tenacity from asgiref.sync import sync_to_async -from deprecated import deprecated from gcloud.aio.auth.token import Token, TokenResponse from google.api_core.exceptions import Forbidden, ResourceExhausted, TooManyRequests from google.auth import _cloud_sdk, compute_engine # type: ignore[attr-defined] @@ -57,6 +56,7 @@ get_credentials_and_project_id, ) from airflow.providers.google.common.consts import CLIENT_INFO +from airflow.providers.google.common.deprecated import deprecated from airflow.utils.process_utils import patch_environ if TYPE_CHECKING: @@ -451,8 +451,8 @@ def num_retries(self) -> int: @property @deprecated( - reason="The client_info method is deprecated and will be removed after 01.03.2025. " - "Please use airflow.providers.google.common.consts.CLIENT_INFO instead.", + planned_removal_date="March 01, 2025", + use_instead="airflow.providers.google.common.consts.CLIENT_INFO", category=AirflowProviderDeprecationWarning, ) def client_info(self) -> ClientInfo: diff --git a/airflow/providers/google/marketing_platform/hooks/analytics.py b/airflow/providers/google/marketing_platform/hooks/analytics.py index ae2ffcd284489..0011be9474b5e 100644 --- a/airflow/providers/google/marketing_platform/hooks/analytics.py +++ b/airflow/providers/google/marketing_platform/hooks/analytics.py @@ -19,18 +19,18 @@ from typing import Any -from deprecated import deprecated from googleapiclient.discovery import Resource, build from googleapiclient.http import MediaFileUpload from airflow.exceptions import AirflowProviderDeprecationWarning +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.common.hooks.base_google import GoogleBaseHook @deprecated( - reason="The GoogleAnalyticsHook class is deprecated and will be removed after 01.11.2024. " - "Please use GoogleAnalyticsAdminHook instead. " - "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", + planned_removal_date="November 01, 2024", + use_instead="GoogleAnalyticsAdminHook", + reason="The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsHook(GoogleBaseHook): diff --git a/airflow/providers/google/marketing_platform/operators/analytics.py b/airflow/providers/google/marketing_platform/operators/analytics.py index 6f86f96a46c71..d3838989c6d05 100644 --- a/airflow/providers/google/marketing_platform/operators/analytics.py +++ b/airflow/providers/google/marketing_platform/operators/analytics.py @@ -23,11 +23,10 @@ from tempfile import NamedTemporaryFile from typing import TYPE_CHECKING, Any, Sequence -from deprecated import deprecated - from airflow.exceptions import AirflowProviderDeprecationWarning from airflow.models import BaseOperator from airflow.providers.google.cloud.hooks.gcs import GCSHook +from airflow.providers.google.common.deprecated import deprecated from airflow.providers.google.marketing_platform.hooks.analytics import GoogleAnalyticsHook if TYPE_CHECKING: @@ -35,9 +34,9 @@ @deprecated( - reason="The GoogleAnalyticsListAccountsOperator class is deprecated " - "and will be removed after 01.11.2024. Please use GoogleAnalyticsAdminListAccountsOperator instead. " - "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", + planned_removal_date="November 01, 2024", + use_instead="GoogleAnalyticsAdminListAccountsOperator", + reason="The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsListAccountsOperator(BaseOperator): @@ -101,9 +100,9 @@ def execute(self, context: Context) -> list[dict[str, Any]]: @deprecated( - reason="The GoogleAnalyticsGetAdsLinkOperator class is deprecated and will be removed after 01.11.2024. " - "Please use GoogleAnalyticsAdminGetGoogleAdsLinkOperator instead. " - "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", + planned_removal_date="November 01, 2024", + use_instead="GoogleAnalyticsAdminGetGoogleAdsLinkOperator", + reason="The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsGetAdsLinkOperator(BaseOperator): @@ -179,10 +178,9 @@ def execute(self, context: Context) -> dict[str, Any]: @deprecated( - reason="The GoogleAnalyticsRetrieveAdsLinksListOperator is deprecated " - "and will be removed after 01.11.2024. " - "Please use GoogleAnalyticsAdminListGoogleAdsLinksOperator` instead. " - "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", + planned_removal_date="November 01, 2024", + use_instead="GoogleAnalyticsAdminListGoogleAdsLinksOperator", + reason="The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsRetrieveAdsLinksListOperator(BaseOperator): @@ -253,9 +251,9 @@ def execute(self, context: Context) -> list[dict[str, Any]]: @deprecated( - reason="The GoogleAnalyticsDataImportUploadOperator class is deprecated " - "and will be removed after 01.11.2024. Please use GoogleAnalyticsAdminCreateDataStreamOperator instead. " - "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", + planned_removal_date="November 01, 2024", + use_instead="GoogleAnalyticsAdminCreateDataStreamOperator", + reason="The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsDataImportUploadOperator(BaseOperator): @@ -359,9 +357,9 @@ def execute(self, context: Context) -> None: @deprecated( - reason="The GoogleAnalyticsDeletePreviousDataUploadsOperator is deprecated " - "and will be removed after 01.11.2024. Please use GoogleAnalyticsAdminDeleteDataStreamOperator instead. " - "The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", + planned_removal_date="November 01, 2024", + use_instead="GoogleAnalyticsAdminDeleteDataStreamOperator", + reason="The Google Analytics API v3 has sunset and is no longer available as of July 1, 2024.", category=AirflowProviderDeprecationWarning, ) class GoogleAnalyticsDeletePreviousDataUploadsOperator(BaseOperator): diff --git a/scripts/ci/pre_commit/check_deprecations.py b/scripts/ci/pre_commit/check_deprecations.py index 925cd4ae423fe..9c827c4baafe2 100755 --- a/scripts/ci/pre_commit/check_deprecations.py +++ b/scripts/ci/pre_commit/check_deprecations.py @@ -19,7 +19,6 @@ from __future__ import annotations import ast -import re import sys from datetime import date from functools import lru_cache @@ -47,6 +46,8 @@ # `Deprecated` package decorators ("deprecated", "deprecated"), ("deprecated", "classic", "deprecated"), + # Experimental Google Provider's decorator with structured deprecation details + ("airflow", "providers", "google", "common", "deprecated", "deprecated"), ] ) end_of_life_deprecation_warnings: dict[str, tuple[str, ...]] = { @@ -65,42 +66,23 @@ def validate_end_of_life_deprecation_warnings(file_path: str, decorator: Any, wa _errors = 0 if not is_file_under_eol_deprecation(file_path=file_path, warning_class=warning_class): return 0 - if category_reason := get_decorator_argument(decorator, "reason"): - reason_message: str = str(category_reason.value.value) # type: ignore[attr-defined] - reason_pattern = r"(.+?) is deprecated and will be removed after (\d{2})\.(\d{2})\.(\d{4})\. (?:Please use (.+?) |There is no replacement(.+?))" + + if not get_decorator_argument(decorator, "planned_removal_date"): expected_date = date.today() + relativedelta(months=6) if expected_date.day > 1: _date = date.today() + relativedelta(months=7) expected_date = date(day=1, month=_date.month, year=_date.year) - expected_date_str: str = expected_date.strftime("%d.%m.%Y") - if match := re.search(reason_pattern, reason_message): - groups = match.groups() - day, month, year = groups[1], groups[2], groups[3] - try: - date(day=int(day), month=int(month), year=int(year)) - except ValueError: - _errors += 1 - console.print( - f"{file_path}:{category_reason.lineno}: " - f"[red]Deprecation message contains invalid date '{day}.{month}.{year}'.[/]\n\n" - f"[green]Expected date in the format DD.MM.YYYY " - f"(recommended: {expected_date_str}).[/]" - ) - else: - _errors += 1 - console.print( - f"{file_path}:{category_reason.lineno}: " - f"[red]Deprecation message is invalid: {reason_message}[/]\n\n" - f"[green]Please update it to one of the following formats " - f"(note that the removal date is recommended to be at least 6 months ahead):\n\n" - f"- The is deprecated and will be removed after {expected_date_str}. " - f"Please use instead .\n" - f"- The is deprecated and will be removed after {expected_date_str}. " - f"There is no replacement.[/]\n" - ) - else: + expected_date_str: str = expected_date.strftime("%B %d, %Y") + _errors += 1 - console.print(f"{file_path}: reason attribute in the @deprecated decorator was expected.") + console.print( + f"{file_path}:{decorator.lineno}: " + "The 'planned_removal_date' parameter is missing in the `@deprecated(...)` call.\n" + "Please provide the date in the format 'Month DD, YYYY' " + "after which the deprecated object should be removed.\n" + "The recommended date is at least six months ahead: " + f"'planned_removal_date=\"{expected_date_str}\"'" + ) return _errors diff --git a/tests/providers/google/cloud/hooks/test_bigquery.py b/tests/providers/google/cloud/hooks/test_bigquery.py index bfbc03c94fb7b..fcee80d224e96 100644 --- a/tests/providers/google/cloud/hooks/test_bigquery.py +++ b/tests/providers/google/cloud/hooks/test_bigquery.py @@ -17,7 +17,6 @@ # under the License. from __future__ import annotations -import re from datetime import datetime from unittest import mock from unittest.mock import AsyncMock @@ -35,7 +34,6 @@ from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning from airflow.providers.google.cloud.hooks.bigquery import ( BigQueryAsyncHook, - BigQueryCursor, BigQueryHook, BigQueryTableAsyncHook, _api_resource_configs_duplication_check, @@ -2108,55 +2106,6 @@ def test_run_load_with_kms(self, mock_insert): ) -class TestBigQueryBaseCursorMethodsDeprecationWarning: - @pytest.mark.parametrize( - "func_name", - [ - "create_empty_table", - "create_empty_dataset", - "get_dataset_tables", - "delete_dataset", - "create_external_table", - "patch_table", - "insert_all", - "update_dataset", - "patch_dataset", - "get_dataset_tables_list", - "get_datasets_list", - "get_dataset", - "run_grant_dataset_view_access", - "run_table_upsert", - "run_table_delete", - "get_tabledata", - "get_schema", - "poll_job_complete", - "cancel_query", - "run_with_configuration", - "run_load", - "run_copy", - "run_extract", - "run_query", - ], - ) - @mock.patch("airflow.providers.google.cloud.hooks.bigquery.BigQueryHook") - def test_deprecation_warning(self, mock_bq_hook, func_name): - args, kwargs = [1], {"param1": "val1"} - new_path = re.escape(f"airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.{func_name}") - message_pattern = rf"Call to deprecated method {func_name}\.\s+\(Please use `{new_path}`\)" - message_regex = re.compile(message_pattern, re.MULTILINE) - - mocked_func = getattr(mock_bq_hook, func_name) - bq_cursor = BigQueryCursor(mock.MagicMock(), PROJECT_ID, mock_bq_hook) - func = getattr(bq_cursor, func_name) - - with pytest.warns(AirflowProviderDeprecationWarning, match=message_regex): - _ = func(*args, **kwargs) - - mocked_func.assert_called_once_with(*args, **kwargs) - - assert re.search(f".*:func:`~{new_path}`.*", func.__doc__) - - @pytest.mark.db_test class TestBigQueryWithLabelsAndDescription(_BigQueryBaseTestClass): @mock.patch("airflow.providers.google.cloud.hooks.bigquery.BigQueryHook.insert_job") diff --git a/tests/providers/google/cloud/hooks/test_cloud_build.py b/tests/providers/google/cloud/hooks/test_cloud_build.py index 69c123a210748..7672d460d0fb2 100644 --- a/tests/providers/google/cloud/hooks/test_cloud_build.py +++ b/tests/providers/google/cloud/hooks/test_cloud_build.py @@ -102,7 +102,7 @@ def test_create_build_with_wait(self, get_conn, wait_time, mock_get_id_from_oper wait_time.return_value = 0 - with pytest.warns(AirflowProviderDeprecationWarning, match="Call to deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.hook.create_build(build=BUILD, project_id=PROJECT_ID) get_conn.return_value.create_build.assert_called_once_with( @@ -123,7 +123,7 @@ def test_create_build_without_wait(self, get_conn, mock_get_id_from_operation): get_conn.return_value.run_build_trigger.return_value = mock.MagicMock() mock_get_id_from_operation.return_value = BUILD_ID - with pytest.warns(AirflowProviderDeprecationWarning, match="Call to deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.hook.create_build(build=BUILD, project_id=PROJECT_ID, wait=False) mock_operation = get_conn.return_value.create_build diff --git a/tests/providers/google/cloud/hooks/test_dataflow.py b/tests/providers/google/cloud/hooks/test_dataflow.py index 39251362880db..104ee374ce1c7 100644 --- a/tests/providers/google/cloud/hooks/test_dataflow.py +++ b/tests/providers/google/cloud/hooks/test_dataflow.py @@ -237,7 +237,7 @@ def test_start_python_dataflow(self, mock_callback_on_job_id, mock_dataflow_wait py_requirements = ["pandas", "numpy"] job_name = f"{JOB_NAME}-{MOCK_UUID_PREFIX}" - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_python_dataflow( job_name=JOB_NAME, variables=DATAFLOW_VARIABLES_PY, @@ -282,7 +282,7 @@ def test_start_python_dataflow_with_custom_region_as_variable( passed_variables = copy.deepcopy(DATAFLOW_VARIABLES_PY) passed_variables["region"] = TEST_LOCATION - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_python_dataflow( job_name=JOB_NAME, variables=passed_variables, @@ -326,7 +326,7 @@ def test_start_python_dataflow_with_custom_region_as_parameter( passed_variables = copy.deepcopy(DATAFLOW_VARIABLES_PY) - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_python_dataflow( job_name=JOB_NAME, variables=passed_variables, @@ -371,7 +371,7 @@ def test_start_python_dataflow_with_no_custom_region_or_region( passed_variables = copy.deepcopy(DATAFLOW_VARIABLES_PY) - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_python_dataflow( job_name=JOB_NAME, variables=passed_variables, @@ -416,7 +416,7 @@ def test_start_python_dataflow_with_multiple_extra_packages( passed_variables = copy.deepcopy(DATAFLOW_VARIABLES_PY) passed_variables["extra-package"] = ["a.whl", "b.whl"] - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_python_dataflow( job_name=JOB_NAME, variables=passed_variables, @@ -459,7 +459,7 @@ def test_start_python_dataflow_with_custom_interpreter( on_new_job_id_callback = MagicMock() job_name = f"{JOB_NAME}-{MOCK_UUID_PREFIX}" - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_python_dataflow( job_name=JOB_NAME, variables=DATAFLOW_VARIABLES_PY, @@ -513,7 +513,7 @@ def test_start_python_dataflow_with_non_empty_py_requirements_and_without_system on_new_job_id_callback = MagicMock() job_name = f"{JOB_NAME}-{MOCK_UUID_PREFIX}" - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_python_dataflow( job_name=JOB_NAME, variables=DATAFLOW_VARIABLES_PY, @@ -553,7 +553,7 @@ def test_start_python_dataflow_with_empty_py_requirements_and_without_system_pac mock_uuid.return_value = MOCK_UUID on_new_job_id_callback = MagicMock() with pytest.raises(AirflowException, match=r"Invalid method invocation\."): - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_python_dataflow( job_name=JOB_NAME, variables=DATAFLOW_VARIABLES_PY, @@ -575,7 +575,7 @@ def test_start_java_dataflow(self, mock_callback_on_job_id, mock_dataflow_wait_f on_new_job_id_callback = MagicMock() job_name = f"{JOB_NAME}-{MOCK_UUID_PREFIX}" - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_java_dataflow( job_name=JOB_NAME, variables=DATAFLOW_VARIABLES_JAVA, @@ -615,7 +615,7 @@ def test_start_java_dataflow_with_multiple_values_in_variables( passed_variables: dict[str, Any] = copy.deepcopy(DATAFLOW_VARIABLES_JAVA) passed_variables["mock-option"] = ["a.whl", "b.whl"] - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_java_dataflow( job_name=JOB_NAME, variables=passed_variables, @@ -655,7 +655,7 @@ def test_start_java_dataflow_with_custom_region_as_variable( passed_variables: dict[str, Any] = copy.deepcopy(DATAFLOW_VARIABLES_JAVA) passed_variables["region"] = TEST_LOCATION - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_java_dataflow( job_name=JOB_NAME, variables=passed_variables, @@ -692,7 +692,7 @@ def test_start_java_dataflow_with_custom_region_as_parameter( on_new_job_id_callback = MagicMock() job_name = f"{JOB_NAME}-{MOCK_UUID_PREFIX}" - with pytest.warns(AirflowProviderDeprecationWarning, match="This method is deprecated"): + with pytest.warns(AirflowProviderDeprecationWarning): self.dataflow_hook.start_java_dataflow( job_name=JOB_NAME, variables=DATAFLOW_VARIABLES_JAVA, diff --git a/tests/providers/google/cloud/hooks/test_secret_manager.py b/tests/providers/google/cloud/hooks/test_secret_manager.py index 8be41e5795cdc..a800f1f785b8c 100644 --- a/tests/providers/google/cloud/hooks/test_secret_manager.py +++ b/tests/providers/google/cloud/hooks/test_secret_manager.py @@ -43,11 +43,7 @@ class TestSecretsManagerHook: def test_delegate_to_runtime_error(self): with pytest.raises(RuntimeError): - with pytest.warns( - AirflowProviderDeprecationWarning, - match="The SecretsManagerHook is deprecated and will be removed after 01.11.2024. " - "Please use GoogleCloudSecretManagerHook instead.", - ): + with pytest.warns(AirflowProviderDeprecationWarning): SecretsManagerHook(gcp_conn_id="GCP_CONN_ID", delegate_to="delegate_to") @patch(INTERNAL_CLIENT_PACKAGE + "._SecretManagerClient.client", return_value=MagicMock()) @@ -59,11 +55,7 @@ def test_delegate_to_runtime_error(self): def test_get_missing_key(self, mock_get_credentials, mock_client): mock_client.secret_version_path.return_value = "full-path" mock_client.access_secret_version.side_effect = NotFound("test-msg") - with pytest.warns( - AirflowProviderDeprecationWarning, - match="The SecretsManagerHook is deprecated and will be removed after 01.11.2024. " - "Please use GoogleCloudSecretManagerHook instead.", - ): + with pytest.warns(AirflowProviderDeprecationWarning): secrets_manager_hook = SecretsManagerHook(gcp_conn_id="test") mock_get_credentials.assert_called_once_with() secret = secrets_manager_hook.get_secret(secret_id="secret") @@ -82,11 +74,7 @@ def test_get_existing_key(self, mock_get_credentials, mock_client): test_response = AccessSecretVersionResponse() test_response.payload.data = b"result" mock_client.access_secret_version.return_value = test_response - with pytest.warns( - AirflowProviderDeprecationWarning, - match="The SecretsManagerHook is deprecated and will be removed after 01.11.2024. " - "Please use GoogleCloudSecretManagerHook instead.", - ): + with pytest.warns(AirflowProviderDeprecationWarning): secrets_manager_hook = SecretsManagerHook(gcp_conn_id="test") mock_get_credentials.assert_called_once_with() secret = secrets_manager_hook.get_secret(secret_id="secret") diff --git a/tests/providers/google/cloud/operators/test_bigquery.py b/tests/providers/google/cloud/operators/test_bigquery.py index d049986750da5..ab9e8e6ac019f 100644 --- a/tests/providers/google/cloud/operators/test_bigquery.py +++ b/tests/providers/google/cloud/operators/test_bigquery.py @@ -485,11 +485,7 @@ class TestBigQueryPatchDatasetOperator: @mock.patch("airflow.providers.google.cloud.operators.bigquery.BigQueryHook") def test_execute(self, mock_hook): dataset_resource = {"friendlyName": "Test DS"} - deprecation_message = ( - r"Call to deprecated class BigQueryPatchDatasetOperator\. " - r"\(This operator is deprecated\. Please use BigQueryUpdateDatasetOperator\.\)" - ) - with pytest.warns(AirflowProviderDeprecationWarning, match=deprecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): operator = BigQueryPatchDatasetOperator( dataset_resource=dataset_resource, task_id=TASK_ID, @@ -525,11 +521,6 @@ def test_execute(self, mock_hook): @pytest.mark.db_test class TestBigQueryOperator: - deprecation_message = ( - r"Call to deprecated class BigQueryExecuteQueryOperator\. " - r"\(This operator is deprecated\. Please use `BigQueryInsertJobOperator`\.\)" - ) - def teardown_method(self): clear_db_xcom() clear_db_runs() @@ -540,7 +531,7 @@ def teardown_method(self): def test_execute(self, mock_hook): encryption_configuration = {"key": "kk"} - with pytest.warns(AirflowProviderDeprecationWarning, match=self.deprecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): operator = BigQueryExecuteQueryOperator( task_id=TASK_ID, sql="Select * from test_table", @@ -602,7 +593,7 @@ def test_execute(self, mock_hook): @mock.patch("airflow.providers.google.cloud.operators.bigquery.BigQueryHook") def test_execute_list(self, mock_hook): - with pytest.warns(AirflowProviderDeprecationWarning, match=self.deprecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): operator = BigQueryExecuteQueryOperator( task_id=TASK_ID, sql=[ @@ -675,7 +666,7 @@ def test_execute_list(self, mock_hook): @mock.patch("airflow.providers.google.cloud.operators.bigquery.BigQueryHook") def test_execute_bad_type(self, mock_hook): - with pytest.warns(AirflowProviderDeprecationWarning, match=self.deprecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): operator = BigQueryExecuteQueryOperator( task_id=TASK_ID, sql=1, @@ -703,7 +694,7 @@ def test_execute_bad_type(self, mock_hook): @mock.patch("airflow.providers.google.cloud.operators.bigquery.BigQueryHook") def test_bigquery_operator_defaults(self, mock_hook, create_task_instance_of_operator, session): - with pytest.warns(AirflowProviderDeprecationWarning, match=self.deprecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( BigQueryExecuteQueryOperator, dag_id=TEST_DAG_ID, @@ -746,7 +737,7 @@ def test_bigquery_operator_extra_serialized_field_when_single_query( create_task_instance_of_operator, session, ): - with pytest.warns(AirflowProviderDeprecationWarning, match=self.deprecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( BigQueryExecuteQueryOperator, dag_id=TEST_DAG_ID, @@ -784,7 +775,7 @@ def test_bigquery_operator_extra_serialized_field_when_multiple_queries( dag_maker, create_task_instance_of_operator, ): - with pytest.warns(AirflowProviderDeprecationWarning, match=self.deprecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( BigQueryExecuteQueryOperator, dag_id=TEST_DAG_ID, @@ -829,7 +820,7 @@ def test_bigquery_operator_extra_serialized_field_when_multiple_queries( def test_bigquery_operator_extra_link_when_missing_job_id( self, mock_hook, create_task_instance_of_operator ): - with pytest.warns(AirflowProviderDeprecationWarning, match=self.deprecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( BigQueryExecuteQueryOperator, dag_id=TEST_DAG_ID, @@ -847,7 +838,7 @@ def test_bigquery_operator_extra_link_when_single_query( create_task_instance_of_operator, session, ): - with pytest.warns(AirflowProviderDeprecationWarning, match=self.deprecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( BigQueryExecuteQueryOperator, dag_id=TEST_DAG_ID, @@ -869,7 +860,7 @@ def test_bigquery_operator_extra_link_when_single_query( def test_bigquery_operator_extra_link_when_multiple_query( self, mock_hook, create_task_instance_of_operator, session ): - with pytest.warns(AirflowProviderDeprecationWarning, match=self.deprecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( BigQueryExecuteQueryOperator, dag_id=TEST_DAG_ID, diff --git a/tests/providers/google/cloud/operators/test_mlengine.py b/tests/providers/google/cloud/operators/test_mlengine.py index b36aa728df02c..98208accead04 100644 --- a/tests/providers/google/cloud/operators/test_mlengine.py +++ b/tests/providers/google/cloud/operators/test_mlengine.py @@ -64,10 +64,6 @@ "runtimeVersion": "1.6", } MLENGINE_AI_PATH = "airflow.providers.google.cloud.operators.mlengine.{}" -DEPRECATION_MESSAGE = ( - r"This operator is deprecated\. All the functionality of legacy " - r"MLEngine and new features are available on the Vertex AI platform\. " -) class TestMLEngineStartBatchPredictionJobOperator: @@ -123,10 +119,7 @@ def test_success_with_model(self, mock_hook): ) hook_instance.create_job.return_value = success_message - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): prediction_task = MLEngineStartBatchPredictionJobOperator( job_id="test_prediction", project_id="test-project", @@ -169,10 +162,7 @@ def test_success_with_version(self, mock_hook): ) hook_instance.create_job.return_value = success_message - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): prediction_task = MLEngineStartBatchPredictionJobOperator( job_id="test_prediction", project_id="test-project", @@ -210,10 +200,7 @@ def test_success_with_uri(self, mock_hook): resp=httplib2.Response({"status": 404}), content=b"some bytes" ) hook_instance.create_job.return_value = success_message - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): prediction_task = MLEngineStartBatchPredictionJobOperator( job_id="test_prediction", project_id="test-project", @@ -243,10 +230,7 @@ def test_invalid_model_origin(self): task_args = self.BATCH_PREDICTION_DEFAULT_ARGS.copy() task_args["uri"] = "gs://fake-uri/saved_model" task_args["model_name"] = "fake_model" - with pytest.raises(AirflowException) as ctx, pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.raises(AirflowException) as ctx, pytest.warns(AirflowProviderDeprecationWarning): MLEngineStartBatchPredictionJobOperator(**task_args).execute(None) assert "Ambiguous model origin: Both uri and model/version name are provided." == str(ctx.value) @@ -255,20 +239,14 @@ def test_invalid_model_origin(self): task_args["uri"] = "gs://fake-uri/saved_model" task_args["model_name"] = "fake_model" task_args["version_name"] = "fake_version" - with pytest.raises(AirflowException) as ctx, pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.raises(AirflowException) as ctx, pytest.warns(AirflowProviderDeprecationWarning): MLEngineStartBatchPredictionJobOperator(**task_args).execute(None) assert "Ambiguous model origin: Both uri and model/version name are provided." == str(ctx.value) # Test that a version is given without a model task_args = self.BATCH_PREDICTION_DEFAULT_ARGS.copy() task_args["version_name"] = "bare_version" - with pytest.raises(AirflowException) as ctx, pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.raises(AirflowException) as ctx, pytest.warns(AirflowProviderDeprecationWarning): MLEngineStartBatchPredictionJobOperator(**task_args).execute(None) assert ( "Missing model: Batch prediction expects a model " @@ -277,10 +255,7 @@ def test_invalid_model_origin(self): # Test that none of uri, model, model/version is given task_args = self.BATCH_PREDICTION_DEFAULT_ARGS.copy() - with pytest.raises(AirflowException) as ctx, pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.raises(AirflowException) as ctx, pytest.warns(AirflowProviderDeprecationWarning): MLEngineStartBatchPredictionJobOperator(**task_args).execute(None) assert ( "Missing model origin: Batch prediction expects a " @@ -297,10 +272,7 @@ def test_http_error(self, mock_hook): hook_instance.create_job.side_effect = HttpError( resp=httplib2.Response({"status": http_error_code}), content=b"Forbidden" ) - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): prediction_task = MLEngineStartBatchPredictionJobOperator( job_id="test_prediction", project_id="test-project", @@ -326,20 +298,14 @@ def test_failed_job_error(self, mock_hook): task_args = self.BATCH_PREDICTION_DEFAULT_ARGS.copy() task_args["uri"] = "a uri" - with pytest.raises(RuntimeError) as ctx, pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.raises(RuntimeError) as ctx, pytest.warns(AirflowProviderDeprecationWarning): MLEngineStartBatchPredictionJobOperator(**task_args).execute(None) assert "A failure message" == str(ctx.value) @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineStartBatchPredictionJobOperator, # Templated fields @@ -386,10 +352,7 @@ def test_success_cancel_training_job(self, mock_hook): hook_instance = mock_hook.return_value hook_instance.cancel_job.return_value = success_response - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): cancel_training_op = MLEngineTrainingCancelJobOperator(**self.TRAINING_DEFAULT_ARGS) cancel_training_op.execute(context=MagicMock()) @@ -410,10 +373,7 @@ def test_http_error(self, mock_hook): hook_instance.cancel_job.side_effect = HttpError( resp=httplib2.Response({"status": http_error_code}), content=b"Forbidden" ) - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): cancel_training_op = MLEngineTrainingCancelJobOperator(**self.TRAINING_DEFAULT_ARGS) with pytest.raises(HttpError) as ctx: cancel_training_op.execute(context=MagicMock()) @@ -431,10 +391,7 @@ def test_http_error(self, mock_hook): @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineTrainingCancelJobOperator, # Templated fields @@ -456,14 +413,9 @@ def test_templating(self, create_task_instance_of_operator, session): class TestMLEngineModelOperator: - deprecation_message = "This operator is deprecated. Consider using operators for specific operations:" - @patch(MLENGINE_AI_PATH.format("MLEngineHook")) def test_success_create_model(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=self.deprecation_message, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineManageModelOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -485,10 +437,7 @@ def test_success_create_model(self, mock_hook): @patch(MLENGINE_AI_PATH.format("MLEngineHook")) def test_success_get_model(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=self.deprecation_message, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineManageModelOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -511,10 +460,7 @@ def test_success_get_model(self, mock_hook): @patch(MLENGINE_AI_PATH.format("MLEngineHook")) def test_fail(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=self.deprecation_message, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineManageModelOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -527,10 +473,7 @@ def test_fail(self, mock_hook): @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=self.deprecation_message, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineManageModelOperator, # Templated fields @@ -554,10 +497,7 @@ def test_templating(self, create_task_instance_of_operator, session): class TestMLEngineCreateModelOperator: @patch(MLENGINE_AI_PATH.format("MLEngineHook")) def test_success_create_model(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineCreateModelOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -578,10 +518,7 @@ def test_success_create_model(self, mock_hook): @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineCreateModelOperator, # Templated fields @@ -605,10 +542,7 @@ def test_templating(self, create_task_instance_of_operator, session): class TestMLEngineGetModelOperator: @patch(MLENGINE_AI_PATH.format("MLEngineHook")) def test_success_get_model(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineGetModelOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -630,10 +564,7 @@ def test_success_get_model(self, mock_hook): @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineGetModelOperator, # Templated fields @@ -657,10 +588,7 @@ def test_templating(self, create_task_instance_of_operator, session): class TestMLEngineDeleteModelOperator: @patch(MLENGINE_AI_PATH.format("MLEngineHook")) def test_success_delete_model(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineDeleteModelOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -682,10 +610,7 @@ def test_success_delete_model(self, mock_hook): @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineDeleteModelOperator, # Templated fields @@ -707,7 +632,6 @@ def test_templating(self, create_task_instance_of_operator, session): class TestMLEngineVersionOperator: - deprecation_message = "This operator is deprecated. Consider using operators for specific operations:" VERSION_DEFAULT_ARGS = { "project_id": "test-project", "model_name": "test-model", @@ -719,10 +643,7 @@ def test_success_create_version(self, mock_hook): success_response = {"name": "some-name", "done": True} hook_instance = mock_hook.return_value hook_instance.create_version.return_value = success_response - with pytest.warns( - AirflowProviderDeprecationWarning, - match=self.deprecation_message, - ): + with pytest.warns(AirflowProviderDeprecationWarning): training_op = MLEngineManageVersionOperator(version=TEST_VERSION, **self.VERSION_DEFAULT_ARGS) training_op.execute(None) @@ -738,10 +659,7 @@ def test_success_create_version(self, mock_hook): @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=self.deprecation_message, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineManageVersionOperator, # Templated fields @@ -769,10 +687,7 @@ def test_templating(self, create_task_instance_of_operator, session): class TestMLEngineCreateVersion: @patch(MLENGINE_AI_PATH.format("MLEngineHook")) def test_success(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineCreateVersionOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -793,10 +708,7 @@ def test_success(self, mock_hook): ) def test_missing_model_name(self): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineCreateVersionOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -808,10 +720,7 @@ def test_missing_model_name(self): task.execute(context=MagicMock()) def test_missing_version(self): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineCreateVersionOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -824,10 +733,7 @@ def test_missing_version(self): @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineCreateVersionOperator, # Templated fields @@ -853,10 +759,7 @@ def test_templating(self, create_task_instance_of_operator, session): class TestMLEngineSetDefaultVersion: @patch(MLENGINE_AI_PATH.format("MLEngineHook")) def test_success(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineSetDefaultVersionOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -877,10 +780,7 @@ def test_success(self, mock_hook): ) def test_missing_model_name(self): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineSetDefaultVersionOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -892,10 +792,7 @@ def test_missing_model_name(self): task.execute(context=MagicMock()) def test_missing_version_name(self): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineSetDefaultVersionOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -908,10 +805,7 @@ def test_missing_version_name(self): @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineSetDefaultVersionOperator, # Templated fields @@ -937,10 +831,7 @@ def test_templating(self, create_task_instance_of_operator, session): class TestMLEngineListVersions: @patch(MLENGINE_AI_PATH.format("MLEngineHook")) def test_success(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineListVersionsOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -961,10 +852,7 @@ def test_success(self, mock_hook): ) def test_missing_model_name(self): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineListVersionsOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -976,10 +864,7 @@ def test_missing_model_name(self): @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineListVersionsOperator, # Templated fields @@ -1003,10 +888,7 @@ def test_templating(self, create_task_instance_of_operator, session): class TestMLEngineDeleteVersion: @patch(MLENGINE_AI_PATH.format("MLEngineHook")) def test_success(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineDeleteVersionOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -1027,10 +909,7 @@ def test_success(self, mock_hook): ) def test_missing_version_name(self): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineDeleteVersionOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -1042,10 +921,7 @@ def test_missing_version_name(self): task.execute(context=MagicMock()) def test_missing_model_name(self): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): task = MLEngineDeleteVersionOperator( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -1058,10 +934,7 @@ def test_missing_model_name(self): @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineDeleteVersionOperator, # Templated fields @@ -1114,10 +987,7 @@ def test_create_training_job_should_execute_successfully(self, mock_hook, mock_w mock_hook.return_value.create_job_without_waiting_result.return_value = "test_training" mock_wait_for_job.return_value = {"state": "SUCCEEDED"} - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): training_op = MLEngineStartTrainingJobOperator(deferrable=False, **self.TRAINING_DEFAULT_ARGS) training_op.execute(MagicMock()) @@ -1151,10 +1021,7 @@ def test_create_training_job_with_master_config_should_execute_successfully( mock_wait_for_job.return_value = {"state": "SUCCEEDED"} mock_hook.return_value.create_job_without_waiting_result.return_value = success_response - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): training_op = MLEngineStartTrainingJobOperator( runtime_version="1.6", python_version="3.5", @@ -1210,10 +1077,7 @@ def test_create_training_job_with_master_image_should_execute_successfully( mock_wait_for_job.return_value = {"state": "SUCCEEDED"} mock_hook.return_value.create_job_without_waiting_result.return_value = response - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): training_op = MLEngineStartTrainingJobOperator(**arguments) training_op.execute(MagicMock()) @@ -1280,10 +1144,7 @@ def test_create_training_job_with_optional_args_should_execute_successfully( mock_wait_for_job.return_value = {"state": "SUCCEEDED"} mock_hook.return_value.create_job_without_waiting_result.return_value = success_response - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): training_op = MLEngineStartTrainingJobOperator( runtime_version="1.6", python_version="3.5", @@ -1314,10 +1175,7 @@ def test_create_training_job_when_http_error_409_should_execute_successfully( mock_hook.return_value.get_job.return_value = {"job_id": "test_training"} mock_wait_for_job.return_value = {"state": "SUCCEEDED"} - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): training_op = MLEngineStartTrainingJobOperator(**self.TRAINING_DEFAULT_ARGS) training_op.execute(MagicMock()) @@ -1332,10 +1190,7 @@ def test_create_training_job_should_throw_exception_when_http_error_403(self, mo resp=httplib2.Response({"status": "403"}), content=b"content" ) - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): training_op = MLEngineStartTrainingJobOperator(**self.TRAINING_DEFAULT_ARGS) with pytest.raises(HttpError): training_op.execute(MagicMock()) @@ -1353,10 +1208,7 @@ def test_create_training_job_should_throw_exception_when_job_failed(self, mock_h mock_wait_for_job.return_value = {"state": "FAILED", "errorMessage": "A failure message"} mock_hook.return_value.create_job_without_waiting_result.return_value = failure_response - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): training_op = MLEngineStartTrainingJobOperator(**self.TRAINING_DEFAULT_ARGS) with pytest.raises(RuntimeError) as ctx: training_op.execute(MagicMock()) @@ -1372,10 +1224,7 @@ def test_create_training_job_should_throw_exception_when_job_failed(self, mock_h @pytest.mark.db_test def test_templating(self, create_task_instance_of_operator, session): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): ti = create_task_instance_of_operator( MLEngineStartTrainingJobOperator, # Templated fields @@ -1441,10 +1290,7 @@ def test_async_create_training_job_should_execute_successfully(mock_hook): """ mock_hook.return_value.create_job_without_waiting_result.return_value = "test_training" - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = MLEngineStartTrainingJobOperator( task_id=TEST_TASK_ID, project_id=TEST_GCP_PROJECT_ID, @@ -1471,10 +1317,7 @@ def test_async_create_training_job_should_execute_successfully(mock_hook): def test_async_create_training_job_should_throw_exception(): """Tests that an AirflowException is raised in case of error event""" - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = MLEngineStartTrainingJobOperator( task_id=TEST_TASK_ID, project_id=TEST_GCP_PROJECT_ID, @@ -1519,10 +1362,7 @@ def create_context(task): def test_async_create_training_job_logging_should_execute_successfully(): """Asserts that logging occurs as expected""" - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = MLEngineStartTrainingJobOperator( task_id=TEST_TASK_ID, project_id=TEST_GCP_PROJECT_ID, @@ -1552,10 +1392,7 @@ def test_async_create_training_job_with_conflict_should_execute_successfully(moc ) mock_hook.return_value.get_job.return_value = {"job_id": "test_training"} - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = MLEngineStartTrainingJobOperator( task_id=TEST_TASK_ID, project_id=TEST_GCP_PROJECT_ID, @@ -1581,10 +1418,7 @@ def test_async_create_training_job_with_conflict_should_execute_successfully(moc def test_async_create_training_job_should_throw_exception_if_job_id_none(): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = MLEngineStartTrainingJobOperator( task_id=TEST_TASK_ID, project_id=TEST_GCP_PROJECT_ID, @@ -1606,10 +1440,7 @@ def test_async_create_training_job_should_throw_exception_if_job_id_none(): def test_async_create_training_job_should_throw_exception_if_project_id_none(): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = MLEngineStartTrainingJobOperator( task_id=TEST_TASK_ID, project_id=None, @@ -1629,10 +1460,7 @@ def test_async_create_training_job_should_throw_exception_if_project_id_none(): def test_async_create_training_job_should_throw_exception_if_custom_none(): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = MLEngineStartTrainingJobOperator( task_id=TEST_TASK_ID, project_id=TEST_PROJECT_ID, @@ -1654,10 +1482,7 @@ def test_async_create_training_job_should_throw_exception_if_custom_none(): def test_async_create_training_job_should_throw_exception_if_package_none(): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = MLEngineStartTrainingJobOperator( task_id=TEST_TASK_ID, project_id=TEST_PROJECT_ID, @@ -1681,10 +1506,7 @@ def test_async_create_training_job_should_throw_exception_if_package_none(): def test_async_create_training_job_should_throw_exception_if_uris_none(): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = MLEngineStartTrainingJobOperator( task_id=TEST_TASK_ID, project_id=TEST_PROJECT_ID, diff --git a/tests/providers/google/cloud/operators/vertex_ai/test_generative_model.py b/tests/providers/google/cloud/operators/vertex_ai/test_generative_model.py index cdf1bc5f2a7cc..eb6b6f946ec49 100644 --- a/tests/providers/google/cloud/operators/vertex_ai/test_generative_model.py +++ b/tests/providers/google/cloud/operators/vertex_ai/test_generative_model.py @@ -80,10 +80,7 @@ def test_deprecation_warning(self): @mock.patch(VERTEX_AI_PATH.format("generative_model.GenerativeModelHook")) def test_execute(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=r"Call to deprecated class PromptLanguageModelOperator. \(This operator is deprecated and will be removed after 01.01.2025, please use `TextGenerationModelPredictOperator`.\)", - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = PromptLanguageModelOperator( task_id=TASK_ID, project_id=GCP_PROJECT, @@ -133,10 +130,7 @@ def test_deprecation_warning(self): @mock.patch(VERTEX_AI_PATH.format("generative_model.GenerativeModelHook")) def test_execute(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=r"Call to deprecated class GenerateTextEmbeddingsOperator. \(This operator is deprecated and will be removed after 01.01.2025, please use `TextEmbeddingModelGetEmbeddingsOperator`.\)", - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = GenerateTextEmbeddingsOperator( task_id=TASK_ID, project_id=GCP_PROJECT, @@ -187,10 +181,7 @@ def test_deprecation_warning(self): @mock.patch(VERTEX_AI_PATH.format("generative_model.GenerativeModelHook")) def test_execute(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=r"Call to deprecated class PromptMultimodalModelOperator. \(This operator is deprecated and will be removed after 01.01.2025, please use `GenerativeModelGenerateContentOperator`.\)", - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = PromptMultimodalModelOperator( task_id=TASK_ID, project_id=GCP_PROJECT, @@ -249,10 +240,7 @@ def test_deprecation_warning(self): @mock.patch(VERTEX_AI_PATH.format("generative_model.GenerativeModelHook")) def test_execute(self, mock_hook): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=r"Call to deprecated class PromptMultimodalModelWithMediaOperator. \(This operator is deprecated and will be removed after 01.01.2025, please use `GenerativeModelGenerateContentOperator`.\)", - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = PromptMultimodalModelWithMediaOperator( task_id=TASK_ID, project_id=GCP_PROJECT, diff --git a/tests/providers/google/cloud/sensors/test_bigquery.py b/tests/providers/google/cloud/sensors/test_bigquery.py index 0fd22b3d78062..b30edee765200 100644 --- a/tests/providers/google/cloud/sensors/test_bigquery.py +++ b/tests/providers/google/cloud/sensors/test_bigquery.py @@ -261,20 +261,13 @@ def context(): class TestBigQueryTableExistenceAsyncSensor: - depcrecation_message = ( - "Class `BigQueryTableExistenceAsyncSensor` is deprecated and " - "will be removed in a future release. " - "Please use `BigQueryTableExistenceSensor` and " - "set `deferrable` attribute to `True` instead" - ) - @mock.patch("airflow.providers.google.cloud.sensors.bigquery.BigQueryHook") def test_big_query_table_existence_sensor_async(self, mock_hook): """ Asserts that a task is deferred and a BigQueryTableExistenceTrigger will be fired when the BigQueryTableExistenceAsyncSensor is executed. """ - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = BigQueryTableExistenceAsyncSensor( task_id="check_table_exists", project_id=TEST_PROJECT_ID, @@ -290,7 +283,7 @@ def test_big_query_table_existence_sensor_async(self, mock_hook): def test_big_query_table_existence_sensor_async_execute_failure(self): """Tests that an expected_exception is raised in case of error event""" - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = BigQueryTableExistenceAsyncSensor( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -302,7 +295,7 @@ def test_big_query_table_existence_sensor_async_execute_failure(self): def test_big_query_table_existence_sensor_async_execute_complete(self): """Asserts that logging occurs as expected""" - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = BigQueryTableExistenceAsyncSensor( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -318,7 +311,7 @@ def test_big_query_sensor_async_execute_complete_event_none( self, ): """Asserts that logging occurs as expected""" - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = BigQueryTableExistenceAsyncSensor( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -330,20 +323,13 @@ def test_big_query_sensor_async_execute_complete_event_none( class TestBigQueryTableExistencePartitionAsyncSensor: - depcrecation_message = ( - "Class `BigQueryTableExistencePartitionAsyncSensor` is deprecated and " - "will be removed in a future release. " - "Please use `BigQueryTablePartitionExistenceSensor` and " - "set `deferrable` attribute to `True` instead" - ) - @mock.patch("airflow.providers.google.cloud.sensors.bigquery.BigQueryHook") def test_big_query_table_existence_partition_sensor_async(self, mock_hook): """ Asserts that a task is deferred and a BigQueryTablePartitionExistenceTrigger will be fired when the BigQueryTableExistencePartitionAsyncSensor is executed. """ - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = BigQueryTableExistencePartitionAsyncSensor( task_id="test_task_id", project_id=TEST_PROJECT_ID, @@ -360,7 +346,7 @@ def test_big_query_table_existence_partition_sensor_async(self, mock_hook): def test_big_query_table_existence_partition_sensor_async_execute_failure(self): """Tests that an expected exception is raised in case of error event""" - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = BigQueryTableExistencePartitionAsyncSensor( task_id="test_task_id", project_id=TEST_PROJECT_ID, @@ -373,7 +359,7 @@ def test_big_query_table_existence_partition_sensor_async_execute_failure(self): def test_big_query_table_existence_partition_sensor_async_execute_complete_event_none(self): """Asserts that logging occurs as expected""" - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = BigQueryTableExistencePartitionAsyncSensor( task_id="task-id", project_id=TEST_PROJECT_ID, @@ -386,7 +372,7 @@ def test_big_query_table_existence_partition_sensor_async_execute_complete_event def test_big_query_table_existence_partition_sensor_async_execute_complete(self): """Asserts that logging occurs as expected""" - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = BigQueryTableExistencePartitionAsyncSensor( task_id="task-id", project_id=TEST_PROJECT_ID, diff --git a/tests/providers/google/cloud/sensors/test_cloud_composer.py b/tests/providers/google/cloud/sensors/test_cloud_composer.py index 4c1ba79d2544c..1e21898ae6c26 100644 --- a/tests/providers/google/cloud/sensors/test_cloud_composer.py +++ b/tests/providers/google/cloud/sensors/test_cloud_composer.py @@ -57,12 +57,6 @@ "output_end": True, "exit_info": {"exit_code": 0, "error": ""}, } -DEPRECATION_MESSAGE = ( - "The `CloudComposerEnvironmentSensor` operator is deprecated. " - "You can achieve the same functionality " - "by using operators in deferrable or non-deferrable mode, since every operator for Cloud " - "Composer will wait for the operation to complete." -) class TestCloudComposerEnvironmentSensor: @@ -72,7 +66,7 @@ def test_cloud_composer_existence_sensor_async(self): Asserts that a task is deferred and a CloudComposerExecutionTrigger will be fired when the CloudComposerEnvironmentSensor is executed. """ - with pytest.warns(AirflowProviderDeprecationWarning, match=DEPRECATION_MESSAGE): + with pytest.warns(AirflowProviderDeprecationWarning): task = CloudComposerEnvironmentSensor( task_id="task_id", project_id=TEST_PROJECT_ID, @@ -89,7 +83,7 @@ def test_cloud_composer_existence_sensor_async_execute_failure( self, ): """Tests that an expected exception is raised in case of error event.""" - with pytest.warns(AirflowProviderDeprecationWarning, match=DEPRECATION_MESSAGE): + with pytest.warns(AirflowProviderDeprecationWarning): task = CloudComposerEnvironmentSensor( task_id="task_id", project_id=TEST_PROJECT_ID, @@ -101,7 +95,7 @@ def test_cloud_composer_existence_sensor_async_execute_failure( def test_cloud_composer_existence_sensor_async_execute_complete(self): """Asserts that logging occurs as expected""" - with pytest.warns(AirflowProviderDeprecationWarning, match=DEPRECATION_MESSAGE): + with pytest.warns(AirflowProviderDeprecationWarning): task = CloudComposerEnvironmentSensor( task_id="task_id", project_id=TEST_PROJECT_ID, diff --git a/tests/providers/google/cloud/sensors/test_gcs.py b/tests/providers/google/cloud/sensors/test_gcs.py index f738d6bbba41f..a00cecc264ab5 100644 --- a/tests/providers/google/cloud/sensors/test_gcs.py +++ b/tests/providers/google/cloud/sensors/test_gcs.py @@ -209,18 +209,13 @@ def test_gcs_object_existence_sensor_execute_complete_return_value(self): class TestGoogleCloudStorageObjectAsyncSensor: - depcrecation_message = ( - "Class `GCSObjectExistenceAsyncSensor` is deprecated and will be removed in a future release. " - "Please use `GCSObjectExistenceSensor` and set `deferrable` attribute to `True` instead" - ) - @mock.patch("airflow.providers.google.cloud.sensors.gcs.GCSHook") def test_gcs_object_existence_async_sensor(self, mock_hook): """ Asserts that a task is deferred and a GCSBlobTrigger will be fired when the GCSObjectExistenceAsyncSensor is executed. """ - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = GCSObjectExistenceAsyncSensor( task_id="task-id", bucket=TEST_BUCKET, @@ -234,7 +229,7 @@ def test_gcs_object_existence_async_sensor(self, mock_hook): def test_gcs_object_existence_async_sensor_execute_failure(self): """Tests that an AirflowException is raised in case of error event""" - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = GCSObjectExistenceAsyncSensor( task_id="task-id", bucket=TEST_BUCKET, @@ -246,7 +241,7 @@ def test_gcs_object_existence_async_sensor_execute_failure(self): def test_gcs_object_existence_async_sensor_execute_complete(self): """Asserts that logging occurs as expected""" - with pytest.warns(AirflowProviderDeprecationWarning, match=self.depcrecation_message): + with pytest.warns(AirflowProviderDeprecationWarning): task = GCSObjectExistenceAsyncSensor( task_id="task-id", bucket=TEST_BUCKET, diff --git a/tests/providers/google/cloud/utils/test_mlengine_operator_utils.py b/tests/providers/google/cloud/utils/test_mlengine_operator_utils.py index 38d328a248d80..47c7d8d3ec3d1 100644 --- a/tests/providers/google/cloud/utils/test_mlengine_operator_utils.py +++ b/tests/providers/google/cloud/utils/test_mlengine_operator_utils.py @@ -30,7 +30,6 @@ from airflow.providers.apache.beam.operators.beam import BeamRunPythonPipelineOperator from airflow.providers.google.cloud.hooks.gcs import GCSHook from airflow.providers.google.cloud.utils.mlengine_operator_utils import create_evaluate_ops -from tests.providers.google.cloud.operators.test_mlengine import DEPRECATION_MESSAGE TASK_PREFIX = "test-task-prefix" TASK_PREFIX_PREDICTION = TASK_PREFIX + "-prediction" @@ -95,7 +94,7 @@ class TestMlengineOperatorUtils: @mock.patch.object(PythonOperator, "set_upstream") @mock.patch.object(BeamRunPythonPipelineOperator, "set_upstream") def test_create_evaluate_ops(self, mock_beam_pipeline, mock_python): - with pytest.warns(AirflowProviderDeprecationWarning, match=DEPRECATION_MESSAGE): + with pytest.warns(AirflowProviderDeprecationWarning): result = create_evaluate_ops( task_prefix=TASK_PREFIX, data_format=DATA_FORMAT, @@ -141,7 +140,7 @@ def test_create_evaluate_ops(self, mock_beam_pipeline, mock_python): @mock.patch.object(PythonOperator, "set_upstream") @mock.patch.object(BeamRunPythonPipelineOperator, "set_upstream") def test_create_evaluate_ops_model_and_version_name(self, mock_beam_pipeline, mock_python): - with pytest.warns(AirflowProviderDeprecationWarning, match=DEPRECATION_MESSAGE): + with pytest.warns(AirflowProviderDeprecationWarning): result = create_evaluate_ops( task_prefix=TASK_PREFIX, data_format=DATA_FORMAT, @@ -189,7 +188,7 @@ def test_create_evaluate_ops_model_and_version_name(self, mock_beam_pipeline, mo @mock.patch.object(PythonOperator, "set_upstream") @mock.patch.object(BeamRunPythonPipelineOperator, "set_upstream") def test_create_evaluate_ops_dag(self, mock_dataflow, mock_python): - with pytest.warns(AirflowProviderDeprecationWarning, match=DEPRECATION_MESSAGE): + with pytest.warns(AirflowProviderDeprecationWarning): result = create_evaluate_ops( task_prefix=TASK_PREFIX, data_format=DATA_FORMAT, @@ -235,10 +234,7 @@ def test_create_evaluate_ops_dag(self, mock_dataflow, mock_python): @mock.patch.object(PythonOperator, "set_upstream") @mock.patch.object(BeamRunPythonPipelineOperator, "set_upstream") def test_apply_validate_fn(self, mock_beam_pipeline, mock_python, mock_download): - with pytest.warns( - AirflowProviderDeprecationWarning, - match=DEPRECATION_MESSAGE, - ): + with pytest.warns(AirflowProviderDeprecationWarning): result = create_evaluate_ops( task_prefix=TASK_PREFIX, data_format=DATA_FORMAT, diff --git a/tests/providers/google/common/test_deprecated.py b/tests/providers/google/common/test_deprecated.py new file mode 100644 index 0000000000000..3c8d2095554c8 --- /dev/null +++ b/tests/providers/google/common/test_deprecated.py @@ -0,0 +1,264 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +from datetime import date +from unittest import mock + +import pytest + +from airflow.providers.google.common.deprecated import AirflowDeprecationAdapter, deprecated + +ADAPTER_PATH = "airflow.providers.google.common.deprecated" +ADAPTER_CLASS_PATH = f"{ADAPTER_PATH}.AirflowDeprecationAdapter" + + +class TestAirflowDeprecationAdapter: + @mock.patch(f"{ADAPTER_CLASS_PATH}._validate_fields") + @mock.patch(f"{ADAPTER_CLASS_PATH}._validate_removal_release") + @mock.patch(f"{ADAPTER_CLASS_PATH}._validate_date") + def test_init(self, mock_validate_date, mock_validate_removal_release, mock_validate_fields): + mock_date = mock_validate_date.return_value + mock_release = mock_validate_removal_release.return_value + + given_date = "August 22, 2024" + given_release = None + adapter = AirflowDeprecationAdapter(planned_removal_date=given_date) + + mock_validate_date.assert_called_once_with(given_date) + mock_validate_removal_release.assert_called_once_with(given_release) + mock_validate_fields.assert_called_once_with() + assert adapter.planned_removal_date == mock_date + assert adapter.planned_removal_release == mock_release + + @mock.patch(f"{ADAPTER_PATH}.datetime") + def test_validate_date(self, mock_datetime): + value = "August 22, 2024" + expected_date = date(2024, 8, 22) + mock_datetime.strptime.return_value.date.return_value = expected_date + + actual_date = AirflowDeprecationAdapter._validate_date(value) + + assert actual_date == expected_date + mock_datetime.strptime.assert_called_once_with(value, "%B %d, %Y") + + @mock.patch(f"{ADAPTER_PATH}.datetime") + def test_validate_date_none(self, mock_datetime): + value = None + + actual_date = AirflowDeprecationAdapter._validate_date(value) + + assert actual_date is None + assert not mock_datetime.strptime.called + + @pytest.mark.parametrize( + "invalid_date", + [ + "August 55, 2024", + "NotAugust 22, 2024", + "2024-08-22", + "Not a date at all", + ], + ) + def test_validate_date_error(self, invalid_date): + expected_error_message = ( + f"Invalid date '{invalid_date}'. " + f"The expected format is 'Month DD, YYYY', for example 'August 22, 2024'." + ) + with pytest.raises(ValueError, match=expected_error_message): + AirflowDeprecationAdapter(planned_removal_date=invalid_date) + + @pytest.mark.parametrize( + "release_string", + [ + "apache-airflow==1.2.3", + "apache-airflow-providers-test==1.2.3", + ], + ) + def test_validate_removal_release(self, release_string): + assert AirflowDeprecationAdapter._validate_removal_release(release_string) == release_string + + def test_validate_removal_release_none(self): + assert AirflowDeprecationAdapter._validate_removal_release(None) is None + + @pytest.mark.parametrize( + "release_string", + [ + "invalid-release-string", + "apache-airflow==2", + "apache-airflow-providers-test==2", + ], + ) + def test_validate_removal_version_error(self, release_string): + msg = ( + f"\\`{release_string}\\` must follow the format " + f"\\'apache-airflow\\(-providers-\\)==\\'." + ) + with pytest.raises(ValueError, match=msg): + AirflowDeprecationAdapter._validate_removal_release(release_string) + + @pytest.mark.parametrize( + "kwargs", + [ + {"planned_removal_date": "August 22, 2024"}, + {"planned_removal_release": "apache-airflow-providers-test==1.2.3"}, + ], + ) + def test_validate_fields(self, kwargs): + adapter = AirflowDeprecationAdapter(**kwargs) + assert adapter is not None + + def test_validate_fields_error_both_removal_date_and_release(self): + error_message = ( + "Only one of two parameters must be set: `planned_removal_date` or 'planned_removal_release'. " + "You specified both." + ) + with pytest.raises(ValueError, match=error_message): + AirflowDeprecationAdapter( + planned_removal_date="August 22, 2024", + planned_removal_release="apache-airflow==1.2.3", + ) + + @pytest.mark.parametrize( + "entity, expected_type", + [ + (AirflowDeprecationAdapter, "class"), + (AirflowDeprecationAdapter.get_deprecated_msg, "function (or method)"), + ], + ) + def test_entity_type(self, entity, expected_type): + assert AirflowDeprecationAdapter.entity_type(entity) == expected_type + + @pytest.mark.parametrize( + "module_path, qualified_name, _str, expected_path", + [ + ("test-module", "test-qualified-name", "test-str", "test-module.test-qualified-name"), + ("test-module", "", "test-str", "test-module"), + ("", "test-qualified-name", "test-str", "test-str"), + ("", "", "test-str", "test-str"), + ], + ) + def test_entity_path(self, module_path, qualified_name, _str, expected_path): + mock_entity = mock.MagicMock( + __module__=module_path, + __qualname__=qualified_name, + __str__=mock.MagicMock(return_value=_str), + ) + assert AirflowDeprecationAdapter.entity_path(mock_entity) == expected_path + + @pytest.mark.parametrize( + "planned_removal_date, planned_removal_release, expected_message", + [ + ("August 22, 2024", None, "after August 22, 2024"), + (None, "apache-airflow==1.2.3", "since version apache-airflow==1.2.3"), + ( + None, + "apache-airflow-providers-test==1.2.3", + "since version apache-airflow-providers-test==1.2.3", + ), + (None, None, "in the future"), + ], + ) + def test_sunset_message(self, planned_removal_date, planned_removal_release, expected_message): + adapter = AirflowDeprecationAdapter( + planned_removal_date=planned_removal_date, + planned_removal_release=planned_removal_release, + ) + assert adapter.sunset_message() == expected_message + + @pytest.mark.parametrize( + "use_instead, expected_message", + [ + (None, "There is no replacement."), + ("replacement", "Please use `replacement` instead."), + ("r1, r2", "Please use `r1`, `r2` instead."), + ], + ) + def test_replacement_message(self, use_instead, expected_message): + adapter = AirflowDeprecationAdapter(use_instead=use_instead) + assert adapter.replacement_message() == expected_message + + @pytest.mark.parametrize( + "reason, instructions", + [ + ("Test reason", "Test instructions"), + ("Test reason", None), + (None, "Test instructions"), + (None, None), + ], + ) + @mock.patch(f"{ADAPTER_CLASS_PATH}.entity_type") + @mock.patch(f"{ADAPTER_CLASS_PATH}.entity_path") + @mock.patch(f"{ADAPTER_CLASS_PATH}.sunset_message") + @mock.patch(f"{ADAPTER_CLASS_PATH}.replacement_message") + def get_deprecated_msg( + self, + mock_replacement_message, + mock_sunset_message, + mock_entity_path, + mock_entity_type, + reason, + instructions, + ): + replacement = mock_replacement_message.return_value + sunset = mock_sunset_message.return_value + entity_path = mock_entity_path.return_value + entity_type = mock_entity_type.return_value + + expected_message = ( + f"The {entity_type} `{entity_path}` is deprecated and will be removed {sunset}. {replacement}" + ) + if reason: + expected_message += f" The reason is: {reason}" + if instructions: + expected_message += f" Instructions: {instructions}" + + mock_wrapped = mock.MagicMock() + adapter = AirflowDeprecationAdapter(reason=mock_wrapped, instructions=instructions) + + assert adapter.get_deprecated_msg(mock.MagicMock(), mock.MagicMock()) == expected_message + mock_entity_type.assert_called_once_with(entity=mock_wrapped) + mock_entity_path.assert_called_once_with(entity=mock_wrapped) + mock_sunset_message.assert_called_once_with() + mock_replacement_message.assert_called_once_with() + + +@mock.patch(f"{ADAPTER_PATH}.standard_deprecated") +def test_deprecated(mock_standard_deprecated): + mock_planned_removal_date = mock.MagicMock() + mock_planned_removal_release = mock.MagicMock() + mock_use_instead = mock.MagicMock() + mock_reason = mock.MagicMock() + mock_instructions = mock.MagicMock() + mock_adapter_cls = mock.MagicMock() + kwargs = { + "planned_removal_date": mock_planned_removal_date, + "planned_removal_release": mock_planned_removal_release, + "use_instead": mock_use_instead, + "reason": mock_reason, + "instructions": mock_instructions, + "adapter_cls": mock_adapter_cls, + } + extra_kwargs = { + "test1": "test1", + "test2": "test2", + } + extra_args = ["test3", "test4"] + + deprecated(*extra_args, **{**kwargs, **extra_kwargs}) + + mock_standard_deprecated.assert_called_once_with(*extra_args, **{**kwargs, **extra_kwargs}) diff --git a/tests/providers/google/marketing_platform/hooks/test_analytics.py b/tests/providers/google/marketing_platform/hooks/test_analytics.py index e7010b9898bf7..e88e8fe862a35 100644 --- a/tests/providers/google/marketing_platform/hooks/test_analytics.py +++ b/tests/providers/google/marketing_platform/hooks/test_analytics.py @@ -34,11 +34,6 @@ GCP_CONN_ID = "test_gcp_conn_id" DELEGATE_TO = "TEST_DELEGATE_TO" IMPERSONATION_CHAIN = ["ACCOUNT_1", "ACCOUNT_2", "ACCOUNT_3"] -DEPRECATION_MESSAGE = ( - r"Call to deprecated class GoogleAnalyticsHook\." - r" \(The `GoogleAnalyticsHook` class is deprecated," - r" please use `GoogleAnalyticsAdminHook` instead\.\)" -) class TestGoogleAnalyticsHook: @@ -52,7 +47,7 @@ def setup_method(self): @mock.patch("airflow.providers.google.common.hooks.base_google.GoogleBaseHook.__init__") def test_init(self, mock_base_init): - with pytest.warns(AirflowProviderDeprecationWarning, match=DEPRECATION_MESSAGE): + with pytest.warns(AirflowProviderDeprecationWarning): hook = GoogleAnalyticsHook( API_VERSION, GCP_CONN_ID, diff --git a/tests/providers/google/marketing_platform/operators/test_analytics.py b/tests/providers/google/marketing_platform/operators/test_analytics.py index 5405ed489dd24..5ef8fa7fddba3 100644 --- a/tests/providers/google/marketing_platform/operators/test_analytics.py +++ b/tests/providers/google/marketing_platform/operators/test_analytics.py @@ -45,11 +45,7 @@ class TestGoogleAnalyticsListAccountsOperator: @mock.patch("airflow.providers.google.marketing_platform.operators.analytics.GoogleAnalyticsHook") def test_execute(self, hook_mock): - with pytest.warns( - AirflowProviderDeprecationWarning, - match="The `GoogleAnalyticsListAccountsOperator` class is deprecated, please use " - "`GoogleAnalyticsAdminListAccountsOperator` instead.", - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = GoogleAnalyticsListAccountsOperator( api_version=API_VERSION, gcp_conn_id=GCP_CONN_ID, @@ -64,11 +60,7 @@ def test_execute(self, hook_mock): class TestGoogleAnalyticsRetrieveAdsLinksListOperator: @mock.patch("airflow.providers.google.marketing_platform.operators.analytics.GoogleAnalyticsHook") def test_execute(self, hook_mock): - with pytest.warns( - AirflowProviderDeprecationWarning, - match="The `GoogleAnalyticsRetrieveAdsLinksListOperator` class is deprecated, please use " - "`GoogleAnalyticsAdminListGoogleAdsLinksOperator` instead.", - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = GoogleAnalyticsRetrieveAdsLinksListOperator( account_id=ACCOUNT_ID, web_property_id=WEB_PROPERTY_ID, @@ -93,11 +85,7 @@ def test_execute(self, hook_mock): class TestGoogleAnalyticsGetAdsLinkOperator: @mock.patch("airflow.providers.google.marketing_platform.operators.analytics.GoogleAnalyticsHook") def test_execute(self, hook_mock): - with pytest.warns( - AirflowProviderDeprecationWarning, - match="The `GoogleAnalyticsGetAdsLinkOperator` class is deprecated, please use " - "`GoogleAnalyticsAdminGetGoogleAdsLinkOperator` instead.", - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = GoogleAnalyticsGetAdsLinkOperator( account_id=ACCOUNT_ID, web_property_id=WEB_PROPERTY_ID, @@ -130,11 +118,7 @@ def test_execute(self, mock_tempfile, gcs_hook_mock, ga_hook_mock): filename = "file/" mock_tempfile.return_value.__enter__.return_value.name = filename - with pytest.warns( - AirflowProviderDeprecationWarning, - match="The `GoogleAnalyticsDataImportUploadOperator` class is deprecated, " - "please use `GoogleAnalyticsAdminCreateDataStreamOperator` instead.", - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = GoogleAnalyticsDataImportUploadOperator( account_id=ACCOUNT_ID, web_property_id=WEB_PROPERTY_ID, @@ -177,11 +161,7 @@ def test_execute(self, mock_hook): {"id": 2}, {"id": 3}, ] - with pytest.warns( - AirflowProviderDeprecationWarning, - match="The `GoogleAnalyticsDeletePreviousDataUploadsOperator` class is deprecated, please use " - "`GoogleAnalyticsAdminDeleteDataStreamOperator` instead.", - ): + with pytest.warns(AirflowProviderDeprecationWarning): op = GoogleAnalyticsDeletePreviousDataUploadsOperator( account_id=ACCOUNT_ID, web_property_id=WEB_PROPERTY_ID,