You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by po...@apache.org on 2022/10/31 00:38:35 UTC

[airflow] branch main updated: Migration of System Tests: Cloud Vision Operators (AIP-47) (#26963)

This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 4e55d7fa2b Migration of System Tests: Cloud Vision Operators (AIP-47) (#26963)
4e55d7fa2b is described below

commit 4e55d7fa2b7d5f8d63465d2c5270edf2d85f08c6
Author: Beata Kossakowska <10...@users.noreply.github.com>
AuthorDate: Mon Oct 31 01:38:26 2022 +0100

    Migration of System Tests: Cloud Vision Operators (AIP-47) (#26963)
---
 .../google/cloud/example_dags/example_vision.py    | 528 ---------------------
 airflow/providers/google/cloud/hooks/vision.py     |   5 +-
 .../operators/cloud/vision.rst                     | 124 ++---
 .../google/cloud/operators/test_vision_system.py   |  61 ---
 .../providers/google/cloud/vision/__init__.py      |  16 +
 .../cloud/vision/example_vision_annotate_image.py  | 201 ++++++++
 .../cloud/vision/example_vision_autogenerated.py   | 278 +++++++++++
 .../google/cloud/vision/example_vision_explicit.py | 287 +++++++++++
 8 files changed, 846 insertions(+), 654 deletions(-)

diff --git a/airflow/providers/google/cloud/example_dags/example_vision.py b/airflow/providers/google/cloud/example_dags/example_vision.py
deleted file mode 100644
index 9c57bebeca..0000000000
--- a/airflow/providers/google/cloud/example_dags/example_vision.py
+++ /dev/null
@@ -1,528 +0,0 @@
-#
-# 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.
-"""
-Example Airflow DAG that creates, gets, updates and deletes Products and Product Sets in the Google Cloud
-Vision service.
-
-This DAG relies on the following OS environment variables
-
-* GCP_VISION_LOCATION - Zone where the instance exists.
-* GCP_VISION_PRODUCT_SET_ID - Product Set ID.
-* GCP_VISION_PRODUCT_ID - Product  ID.
-* GCP_VISION_REFERENCE_IMAGE_ID - Reference Image ID.
-* GCP_VISION_REFERENCE_IMAGE_URL - A link to the bucket that contains the reference image.
-* GCP_VISION_ANNOTATE_IMAGE_URL - A link to the bucket that contains the file to be annotated.
-
-"""
-from __future__ import annotations
-
-import os
-from datetime import datetime
-
-from airflow import models
-from airflow.operators.bash import BashOperator
-from airflow.providers.google.cloud.operators.vision import (
-    CloudVisionAddProductToProductSetOperator,
-    CloudVisionCreateProductOperator,
-    CloudVisionCreateProductSetOperator,
-    CloudVisionCreateReferenceImageOperator,
-    CloudVisionDeleteProductOperator,
-    CloudVisionDeleteProductSetOperator,
-    CloudVisionDeleteReferenceImageOperator,
-    CloudVisionDetectImageLabelsOperator,
-    CloudVisionDetectImageSafeSearchOperator,
-    CloudVisionDetectTextOperator,
-    CloudVisionGetProductOperator,
-    CloudVisionGetProductSetOperator,
-    CloudVisionImageAnnotateOperator,
-    CloudVisionRemoveProductFromProductSetOperator,
-    CloudVisionTextDetectOperator,
-    CloudVisionUpdateProductOperator,
-    CloudVisionUpdateProductSetOperator,
-)
-
-# [START howto_operator_vision_retry_import]
-
-
-from google.api_core.retry import Retry  # isort:skip
-
-# [END howto_operator_vision_retry_import]
-# [START howto_operator_vision_product_set_import]
-from google.cloud.vision_v1.types import ProductSet  # isort:skip
-
-# [END howto_operator_vision_product_set_import]
-# [START howto_operator_vision_product_import]
-from google.cloud.vision_v1.types import Product  # isort:skip
-
-# [END howto_operator_vision_product_import]
-# [START howto_operator_vision_reference_image_import]
-from google.cloud.vision_v1.types import ReferenceImage  # isort:skip
-
-# [END howto_operator_vision_reference_image_import]
-# [START howto_operator_vision_enums_import]
-from google.cloud.vision import enums  # isort:skip
-
-# [END howto_operator_vision_enums_import]
-
-START_DATE = datetime(2021, 1, 1)
-
-GCP_VISION_LOCATION = os.environ.get("GCP_VISION_LOCATION", "europe-west1")
-
-GCP_VISION_PRODUCT_SET_ID = os.environ.get("GCP_VISION_PRODUCT_SET_ID", "product_set_explicit_id")
-GCP_VISION_PRODUCT_ID = os.environ.get("GCP_VISION_PRODUCT_ID", "product_explicit_id")
-GCP_VISION_REFERENCE_IMAGE_ID = os.environ.get("GCP_VISION_REFERENCE_IMAGE_ID", "reference_image_explicit_id")
-GCP_VISION_REFERENCE_IMAGE_URL = os.environ.get(
-    "GCP_VISION_REFERENCE_IMAGE_URL", "gs://INVALID BUCKET NAME/image1.jpg"
-)
-GCP_VISION_ANNOTATE_IMAGE_URL = os.environ.get(
-    "GCP_VISION_ANNOTATE_IMAGE_URL", "gs://INVALID BUCKET NAME/image2.jpg"
-)
-
-# [START howto_operator_vision_product_set]
-product_set = ProductSet(display_name="My Product Set")
-# [END howto_operator_vision_product_set]
-
-# [START howto_operator_vision_product]
-product = Product(display_name="My Product 1", product_category="toys")
-# [END howto_operator_vision_product]
-
-# [START howto_operator_vision_reference_image]
-reference_image = ReferenceImage(uri=GCP_VISION_REFERENCE_IMAGE_URL)
-# [END howto_operator_vision_reference_image]
-
-# [START howto_operator_vision_annotate_image_request]
-annotate_image_request = {
-    "image": {"source": {"image_uri": GCP_VISION_ANNOTATE_IMAGE_URL}},
-    "features": [{"type": enums.Feature.Type.LOGO_DETECTION}],
-}
-# [END howto_operator_vision_annotate_image_request]
-
-# [START howto_operator_vision_detect_image_param]
-DETECT_IMAGE = {"source": {"image_uri": GCP_VISION_ANNOTATE_IMAGE_URL}}
-# [END howto_operator_vision_detect_image_param]
-
-with models.DAG(
-    "example_gcp_vision_autogenerated_id",
-    start_date=START_DATE,
-    catchup=False,
-) as dag_autogenerated_id:
-    # ################################## #
-    # ### Autogenerated IDs examples ### #
-    # ################################## #
-
-    # [START howto_operator_vision_product_set_create]
-    product_set_create = CloudVisionCreateProductSetOperator(
-        location=GCP_VISION_LOCATION,
-        product_set=product_set,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="product_set_create",
-    )
-    # [END howto_operator_vision_product_set_create]
-
-    product_set_create_output = product_set_create.output
-
-    # [START howto_operator_vision_product_set_get]
-    product_set_get = CloudVisionGetProductSetOperator(
-        location=GCP_VISION_LOCATION,
-        product_set_id=product_set_create_output,
-        task_id="product_set_get",
-    )
-    # [END howto_operator_vision_product_set_get]
-
-    # [START howto_operator_vision_product_set_update]
-    product_set_update = CloudVisionUpdateProductSetOperator(
-        location=GCP_VISION_LOCATION,
-        product_set_id=product_set_create_output,
-        product_set=ProductSet(display_name="My Product Set 2"),
-        task_id="product_set_update",
-    )
-    # [END howto_operator_vision_product_set_update]
-
-    # [START howto_operator_vision_product_set_delete]
-    product_set_delete = CloudVisionDeleteProductSetOperator(
-        location=GCP_VISION_LOCATION,
-        product_set_id=product_set_create_output,
-        task_id="product_set_delete",
-    )
-    # [END howto_operator_vision_product_set_delete]
-
-    # [START howto_operator_vision_product_create]
-    product_create = CloudVisionCreateProductOperator(
-        location=GCP_VISION_LOCATION,
-        product=product,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="product_create",
-    )
-    # [END howto_operator_vision_product_create]
-
-    product_create_output = product_create.output
-
-    # [START howto_operator_vision_product_get]
-    product_get = CloudVisionGetProductOperator(
-        location=GCP_VISION_LOCATION,
-        product_id=product_create_output,
-        task_id="product_get",
-    )
-    # [END howto_operator_vision_product_get]
-
-    # [START howto_operator_vision_product_update]
-    product_update = CloudVisionUpdateProductOperator(
-        location=GCP_VISION_LOCATION,
-        product_id=product_create_output,
-        product=Product(display_name="My Product 2", description="My updated description"),
-        task_id="product_update",
-    )
-    # [END howto_operator_vision_product_update]
-
-    # [START howto_operator_vision_product_delete]
-    product_delete = CloudVisionDeleteProductOperator(
-        location=GCP_VISION_LOCATION,
-        product_id=product_create_output,
-        task_id="product_delete",
-    )
-    # [END howto_operator_vision_product_delete]
-
-    # [START howto_operator_vision_reference_image_create]
-    reference_image_create = CloudVisionCreateReferenceImageOperator(
-        location=GCP_VISION_LOCATION,
-        reference_image=reference_image,
-        product_id=product_create_output,
-        reference_image_id=GCP_VISION_REFERENCE_IMAGE_ID,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="reference_image_create",
-    )
-    # [END howto_operator_vision_reference_image_create]
-
-    # [START howto_operator_vision_reference_image_delete]
-    reference_image_delete = CloudVisionDeleteReferenceImageOperator(
-        location=GCP_VISION_LOCATION,
-        product_id=product_create_output,
-        reference_image_id=GCP_VISION_REFERENCE_IMAGE_ID,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="reference_image_delete",
-    )
-    # [END howto_operator_vision_reference_image_delete]
-
-    # [START howto_operator_vision_add_product_to_product_set]
-    add_product_to_product_set = CloudVisionAddProductToProductSetOperator(
-        location=GCP_VISION_LOCATION,
-        product_set_id=product_set_create_output,
-        product_id=product_create_output,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="add_product_to_product_set",
-    )
-    # [END howto_operator_vision_add_product_to_product_set]
-
-    # [START howto_operator_vision_remove_product_from_product_set]
-    remove_product_from_product_set = CloudVisionRemoveProductFromProductSetOperator(
-        location=GCP_VISION_LOCATION,
-        product_set_id=product_set_create_output,
-        product_id=product_create_output,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="remove_product_from_product_set",
-    )
-    # [END howto_operator_vision_remove_product_from_product_set]
-
-    # Product path
-    product_create >> product_get >> product_update >> product_delete
-
-    # ProductSet path
-    product_set_get >> product_set_update >> product_set_delete
-
-    # ReferenceImage path
-    reference_image_create >> reference_image_delete >> product_delete
-
-    # Product/ProductSet path
-    product_create >> add_product_to_product_set
-    add_product_to_product_set >> remove_product_from_product_set
-    remove_product_from_product_set >> product_delete
-    remove_product_from_product_set >> product_set_delete
-
-    # Task dependencies created via `XComArgs`:
-    #   product_set_create >> product_set_get
-    #   product_set_create >> product_set_update
-    #   product_set_create >> product_set_delete
-    #   product_create >> product_get
-    #   product_create >> product_delete
-    #   product_create >> reference_image_create
-    #   product_create >> reference_image_delete
-    #   product_set_create >> add_product_to_product_set
-    #   product_create >> add_product_to_product_set
-    #   product_set_create >> remove_product_from_product_set
-    #   product_create >> remove_product_from_product_set
-
-
-with models.DAG(
-    "example_gcp_vision_explicit_id",
-    start_date=START_DATE,
-    catchup=False,
-) as dag_explicit_id:
-    # ############################# #
-    # ### Explicit IDs examples ### #
-    # ############################# #
-
-    # [START howto_operator_vision_product_set_create_2]
-    product_set_create_2 = CloudVisionCreateProductSetOperator(
-        product_set_id=GCP_VISION_PRODUCT_SET_ID,
-        location=GCP_VISION_LOCATION,
-        product_set=product_set,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="product_set_create_2",
-    )
-    # [END howto_operator_vision_product_set_create_2]
-
-    # Second 'create' task with the same product_set_id to demonstrate idempotence
-    product_set_create_2_idempotence = CloudVisionCreateProductSetOperator(
-        product_set_id=GCP_VISION_PRODUCT_SET_ID,
-        location=GCP_VISION_LOCATION,
-        product_set=product_set,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="product_set_create_2_idempotence",
-    )
-
-    # [START howto_operator_vision_product_set_get_2]
-    product_set_get_2 = CloudVisionGetProductSetOperator(
-        location=GCP_VISION_LOCATION, product_set_id=GCP_VISION_PRODUCT_SET_ID, task_id="product_set_get_2"
-    )
-    # [END howto_operator_vision_product_set_get_2]
-
-    # [START howto_operator_vision_product_set_update_2]
-    product_set_update_2 = CloudVisionUpdateProductSetOperator(
-        location=GCP_VISION_LOCATION,
-        product_set_id=GCP_VISION_PRODUCT_SET_ID,
-        product_set=ProductSet(display_name="My Product Set 2"),
-        task_id="product_set_update_2",
-    )
-    # [END howto_operator_vision_product_set_update_2]
-
-    # [START howto_operator_vision_product_set_delete_2]
-    product_set_delete_2 = CloudVisionDeleteProductSetOperator(
-        location=GCP_VISION_LOCATION, product_set_id=GCP_VISION_PRODUCT_SET_ID, task_id="product_set_delete_2"
-    )
-    # [END howto_operator_vision_product_set_delete_2]
-
-    # [START howto_operator_vision_product_create_2]
-    product_create_2 = CloudVisionCreateProductOperator(
-        product_id=GCP_VISION_PRODUCT_ID,
-        location=GCP_VISION_LOCATION,
-        product=product,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="product_create_2",
-    )
-    # [END howto_operator_vision_product_create_2]
-
-    # Second 'create' task with the same product_id to demonstrate idempotence
-    product_create_2_idempotence = CloudVisionCreateProductOperator(
-        product_id=GCP_VISION_PRODUCT_ID,
-        location=GCP_VISION_LOCATION,
-        product=product,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="product_create_2_idempotence",
-    )
-
-    # [START howto_operator_vision_product_get_2]
-    product_get_2 = CloudVisionGetProductOperator(
-        location=GCP_VISION_LOCATION, product_id=GCP_VISION_PRODUCT_ID, task_id="product_get_2"
-    )
-    # [END howto_operator_vision_product_get_2]
-
-    # [START howto_operator_vision_product_update_2]
-    product_update_2 = CloudVisionUpdateProductOperator(
-        location=GCP_VISION_LOCATION,
-        product_id=GCP_VISION_PRODUCT_ID,
-        product=Product(display_name="My Product 2", description="My updated description"),
-        task_id="product_update_2",
-    )
-    # [END howto_operator_vision_product_update_2]
-
-    # [START howto_operator_vision_product_delete_2]
-    product_delete_2 = CloudVisionDeleteProductOperator(
-        location=GCP_VISION_LOCATION, product_id=GCP_VISION_PRODUCT_ID, task_id="product_delete_2"
-    )
-    # [END howto_operator_vision_product_delete_2]
-
-    # [START howto_operator_vision_reference_image_create_2]
-    reference_image_create_2 = CloudVisionCreateReferenceImageOperator(
-        location=GCP_VISION_LOCATION,
-        reference_image=reference_image,
-        product_id=GCP_VISION_PRODUCT_ID,
-        reference_image_id=GCP_VISION_REFERENCE_IMAGE_ID,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="reference_image_create_2",
-    )
-    # [END howto_operator_vision_reference_image_create_2]
-
-    # [START howto_operator_vision_reference_image_delete_2]
-    reference_image_delete_2 = CloudVisionDeleteReferenceImageOperator(
-        location=GCP_VISION_LOCATION,
-        reference_image_id=GCP_VISION_REFERENCE_IMAGE_ID,
-        product_id=GCP_VISION_PRODUCT_ID,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="reference_image_delete_2",
-    )
-    # [END howto_operator_vision_reference_image_delete_2]
-
-    # Second 'create' task with the same product_id to demonstrate idempotence
-    reference_image_create_2_idempotence = CloudVisionCreateReferenceImageOperator(
-        location=GCP_VISION_LOCATION,
-        reference_image=reference_image,
-        product_id=GCP_VISION_PRODUCT_ID,
-        reference_image_id=GCP_VISION_REFERENCE_IMAGE_ID,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="reference_image_create_2_idempotence",
-    )
-
-    # [START howto_operator_vision_add_product_to_product_set_2]
-    add_product_to_product_set_2 = CloudVisionAddProductToProductSetOperator(
-        location=GCP_VISION_LOCATION,
-        product_set_id=GCP_VISION_PRODUCT_SET_ID,
-        product_id=GCP_VISION_PRODUCT_ID,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="add_product_to_product_set_2",
-    )
-    # [END howto_operator_vision_add_product_to_product_set_2]
-
-    # [START howto_operator_vision_remove_product_from_product_set_2]
-    remove_product_from_product_set_2 = CloudVisionRemoveProductFromProductSetOperator(
-        location=GCP_VISION_LOCATION,
-        product_set_id=GCP_VISION_PRODUCT_SET_ID,
-        product_id=GCP_VISION_PRODUCT_ID,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="remove_product_from_product_set_2",
-    )
-    # [END howto_operator_vision_remove_product_from_product_set_2]
-
-    # Product path
-    product_create_2 >> product_create_2_idempotence >> product_get_2 >> product_update_2 >> product_delete_2
-
-    # ProductSet path
-    product_set_create_2 >> product_set_get_2 >> product_set_update_2 >> product_set_delete_2
-    product_set_create_2 >> product_set_create_2_idempotence >> product_set_delete_2
-
-    # ReferenceImage path
-    product_create_2 >> reference_image_create_2 >> reference_image_create_2_idempotence
-    reference_image_create_2_idempotence >> reference_image_delete_2 >> product_delete_2
-
-    # Product/ProductSet path
-    add_product_to_product_set_2 >> remove_product_from_product_set_2
-    product_set_create_2 >> add_product_to_product_set_2
-    product_create_2 >> add_product_to_product_set_2
-    remove_product_from_product_set_2 >> product_set_delete_2
-    remove_product_from_product_set_2 >> product_delete_2
-
-with models.DAG(
-    "example_gcp_vision_annotate_image",
-    start_date=START_DATE,
-    catchup=False,
-) as dag_annotate_image:
-    # ############################## #
-    # ### Annotate image example ### #
-    # ############################## #
-
-    # [START howto_operator_vision_annotate_image]
-    annotate_image = CloudVisionImageAnnotateOperator(
-        request=annotate_image_request, retry=Retry(maximum=10.0), timeout=5, task_id="annotate_image"
-    )
-    # [END howto_operator_vision_annotate_image]
-
-    # [START howto_operator_vision_annotate_image_result]
-    annotate_image_result = BashOperator(
-        bash_command="echo {{ task_instance.xcom_pull('annotate_image')"
-        "['logoAnnotations'][0]['description'] }}",
-        task_id="annotate_image_result",
-    )
-    # [END howto_operator_vision_annotate_image_result]
-
-    # [START howto_operator_vision_detect_text]
-    detect_text = CloudVisionDetectTextOperator(
-        image=DETECT_IMAGE,
-        retry=Retry(maximum=10.0),
-        timeout=5,
-        task_id="detect_text",
-        language_hints="en",
-        web_detection_params={"include_geo_results": True},
-    )
-    # [END howto_operator_vision_detect_text]
-
-    # [START howto_operator_vision_detect_text_result]
-    detect_text_result = BashOperator(
-        bash_command="echo {{ task_instance.xcom_pull('detect_text')['textAnnotations'][0] }}",
-        task_id="detect_text_result",
-    )
-    # [END howto_operator_vision_detect_text_result]
-
-    # [START howto_operator_vision_document_detect_text]
-    document_detect_text = CloudVisionTextDetectOperator(
-        image=DETECT_IMAGE, retry=Retry(maximum=10.0), timeout=5, task_id="document_detect_text"
-    )
-    # [END howto_operator_vision_document_detect_text]
-
-    # [START howto_operator_vision_document_detect_text_result]
-    document_detect_text_result = BashOperator(
-        bash_command="echo {{ task_instance.xcom_pull('document_detect_text')['textAnnotations'][0] }}",
-        task_id="document_detect_text_result",
-    )
-    # [END howto_operator_vision_document_detect_text_result]
-
-    # [START howto_operator_vision_detect_labels]
-    detect_labels = CloudVisionDetectImageLabelsOperator(
-        image=DETECT_IMAGE, retry=Retry(maximum=10.0), timeout=5, task_id="detect_labels"
-    )
-    # [END howto_operator_vision_detect_labels]
-
-    # [START howto_operator_vision_detect_labels_result]
-    detect_labels_result = BashOperator(
-        bash_command="echo {{ task_instance.xcom_pull('detect_labels')['labelAnnotations'][0] }}",
-        task_id="detect_labels_result",
-    )
-    # [END howto_operator_vision_detect_labels_result]
-
-    # [START howto_operator_vision_detect_safe_search]
-    detect_safe_search = CloudVisionDetectImageSafeSearchOperator(
-        image=DETECT_IMAGE, retry=Retry(maximum=10.0), timeout=5, task_id="detect_safe_search"
-    )
-    # [END howto_operator_vision_detect_safe_search]
-
-    # [START howto_operator_vision_detect_safe_search_result]
-    detect_safe_search_result = BashOperator(
-        bash_command=f"echo {detect_safe_search.output}",
-        task_id="detect_safe_search_result",
-    )
-    # [END howto_operator_vision_detect_safe_search_result]
-
-    annotate_image >> annotate_image_result
-
-    detect_text >> detect_text_result
-    document_detect_text >> document_detect_text_result
-    detect_labels >> detect_labels_result
-    detect_safe_search >> detect_safe_search_result
diff --git a/airflow/providers/google/cloud/hooks/vision.py b/airflow/providers/google/cloud/hooks/vision.py
index fb4d713e69..5ebdb0e914 100644
--- a/airflow/providers/google/cloud/hooks/vision.py
+++ b/airflow/providers/google/cloud/hooks/vision.py
@@ -421,7 +421,7 @@ class CloudVisionHook(GoogleBaseHook):
         retry: Retry | _MethodDefault = DEFAULT,
         timeout: float | None = None,
         metadata: Sequence[tuple[str, str]] = (),
-    ) -> dict:
+    ) -> None:
         """
         For the documentation see:
         :py:class:`~airflow.providers.google.cloud.operators.vision.CloudVisionDeleteReferenceImageOperator`
@@ -432,7 +432,7 @@ class CloudVisionHook(GoogleBaseHook):
             project=project_id, location=location, product=product_id, reference_image=reference_image_id
         )
 
-        response = client.delete_reference_image(
+        client.delete_reference_image(
             name=name,
             retry=retry,
             timeout=timeout,
@@ -440,7 +440,6 @@ class CloudVisionHook(GoogleBaseHook):
         )
 
         self.log.info("ReferenceImage with the name [%s] deleted.", name)
-        return MessageToDict(response)
 
     @GoogleBaseHook.fallback_to_default_project_id
     def add_product_to_product_set(
diff --git a/docs/apache-airflow-providers-google/operators/cloud/vision.rst b/docs/apache-airflow-providers-google/operators/cloud/vision.rst
index 49f4628c27..71b9fba990 100644
--- a/docs/apache-airflow-providers-google/operators/cloud/vision.rst
+++ b/docs/apache-airflow-providers-google/operators/cloud/vision.rst
@@ -42,17 +42,17 @@ We are using the :class:`~google.cloud.vision_v1.types.Product`,
 :class:`~google.cloud.vision_v1.types.ProductSet` and :class:`~google.api_core.retry.Retry` objects from
 Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_retry_import]
       :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_product_set_import]
       :end-before: [END howto_operator_vision_product_set_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_product_import]
       :end-before: [END howto_operator_vision_product_import]
@@ -60,7 +60,7 @@ Google libraries:
 
 If ``product_set_id`` and ``product_id`` was generated by the API it can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_add_product_to_product_set]
@@ -68,7 +68,7 @@ If ``product_set_id`` and ``product_id`` was generated by the API it can be extr
 
 Otherwise it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_add_product_to_product_set_2]
@@ -107,18 +107,18 @@ Using the operator
 We are using the :class:`~google.cloud.vision.enums` and :class:`~google.api_core.retry.Retry` objects from
 Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :start-after: [START howto_operator_vision_retry_import]
       :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :start-after: [START howto_operator_vision_enums_import]
       :end-before: [END howto_operator_vision_enums_import]
 
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_annotate_image]
@@ -126,7 +126,7 @@ Google libraries:
 
 The result can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_annotate_image_result]
@@ -169,24 +169,24 @@ Using the operator
 
 We are using the ``Product`` and :class:`~google.api_core.retry.Retry` objects from Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :start-after: [START howto_operator_vision_product_import]
     :end-before: [END howto_operator_vision_product_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :start-after: [START howto_operator_vision_retry_import]
     :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :start-after: [START howto_operator_vision_product]
     :end-before: [END howto_operator_vision_product]
 
 The ``product_id`` argument can be omitted (it will be generated by the API):
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_create]
@@ -194,7 +194,7 @@ The ``product_id`` argument can be omitted (it will be generated by the API):
 
 Or it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_create_2]
@@ -239,7 +239,7 @@ Using the operator
 
 If ``product_id`` was generated by the API it can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_delete]
@@ -247,7 +247,7 @@ If ``product_id`` was generated by the API it can be extracted from XCOM:
 
 Otherwise it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_delete_2]
@@ -287,7 +287,7 @@ Using the operator
 
 If ``product_id`` was generated by the API it can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_get]
@@ -295,7 +295,7 @@ If ``product_id`` was generated by the API it can be extracted from XCOM:
 
 Otherwise it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_get_2]
@@ -331,24 +331,24 @@ Using the operator
 
 We are using the ``ProductSet`` and :class:`~google.api_core.retry.Retry` objects from Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :start-after: [START howto_operator_vision_product_set_import]
     :end-before: [END howto_operator_vision_product_set_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :start-after: [START howto_operator_vision_retry_import]
     :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :start-after: [START howto_operator_vision_product_set]
     :end-before: [END howto_operator_vision_product_set]
 
 The ``product_set_id`` argument can be omitted (it will be generated by the API):
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_set_create]
@@ -356,7 +356,7 @@ The ``product_set_id`` argument can be omitted (it will be generated by the API)
 
 Or it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_set_create_2]
@@ -395,7 +395,7 @@ Using the operator
 
 If ``product_set_id`` was generated by the API it can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_set_delete]
@@ -403,7 +403,7 @@ If ``product_set_id`` was generated by the API it can be extracted from XCOM:
 
 Otherwise it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_set_delete_2]
@@ -439,7 +439,7 @@ Using the operator
 
 If ``product_set_id`` was generated by the API it can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_set_get]
@@ -447,7 +447,7 @@ If ``product_set_id`` was generated by the API it can be extracted from XCOM:
 
 Otherwise it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_set_get_2]
@@ -495,12 +495,12 @@ Using the operator
 
 We are using the ``ProductSet`` object from the Google Cloud Vision library:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :start-after: [START howto_operator_vision_product_set_import]
     :end-before: [END howto_operator_vision_product_set_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :start-after: [START howto_operator_vision_product_set]
     :end-before: [END howto_operator_vision_product_set]
@@ -509,7 +509,7 @@ Initialization of the task:
 
 If ``product_set_id`` was generated by the API it can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_set_update]
@@ -517,7 +517,7 @@ If ``product_set_id`` was generated by the API it can be extracted from XCOM:
 
 Otherwise it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_set_update_2]
@@ -576,19 +576,19 @@ Using the operator
 
 We are using the ``Product`` object from the Google Cloud Vision library:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :start-after: [START howto_operator_vision_product_import]
     :end-before: [END howto_operator_vision_product_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :start-after: [START howto_operator_vision_product]
     :end-before: [END howto_operator_vision_product]
 
 If ``product_id`` was generated by the API it can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_update]
@@ -596,7 +596,7 @@ If ``product_id`` was generated by the API it can be extracted from XCOM:
 
 Otherwise it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
     :language: python
     :dedent: 4
     :start-after: [START howto_operator_vision_product_update_2]
@@ -632,24 +632,24 @@ Using the operator
 
 We are using the :class:`~google.cloud.vision_v1.types.ReferenceImage` and :class:`~google.api_core.retry.Retry` objects from Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_reference_image_import]
       :end-before: [END howto_operator_vision_reference_image_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_retry_import]
       :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_reference_image]
       :end-before: [END howto_operator_vision_reference_image]
 
 The ``product_set_id`` argument can be omitted (it will be generated by the API):
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_reference_image_create]
@@ -657,7 +657,7 @@ The ``product_set_id`` argument can be omitted (it will be generated by the API)
 
 Or it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_reference_image_create_2]
@@ -694,24 +694,24 @@ Using the operator
 
 We are using the :class:`~google.cloud.vision_v1.types.ReferenceImage` and :class:`~google.api_core.retry.Retry` objects from Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_reference_image_import]
       :end-before: [END howto_operator_vision_reference_image_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_retry_import]
       :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_reference_image]
       :end-before: [END howto_operator_vision_reference_image]
 
 The ``product_set_id`` argument can be omitted (it will be generated by the API):
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_reference_image_delete]
@@ -719,7 +719,7 @@ The ``product_set_id`` argument can be omitted (it will be generated by the API)
 
 Or it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_reference_image_delete_2]
@@ -758,17 +758,17 @@ We are using the :class:`~google.cloud.vision_v1.types.Product`,
 :class:`~google.cloud.vision_v1.types.ProductSet` and :class:`~google.api_core.retry.Retry` objects from
 Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_retry_import]
       :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_product_set_import]
       :end-before: [END howto_operator_vision_product_set_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :start-after: [START howto_operator_vision_product_import]
       :end-before: [END howto_operator_vision_product_import]
@@ -776,7 +776,7 @@ Google libraries:
 
 If ``product_set_id`` and ``product_id`` was generated by the API it can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_remove_product_from_product_set]
@@ -784,7 +784,7 @@ If ``product_set_id`` and ``product_id`` was generated by the API it can be extr
 
 Otherwise it can be specified explicitly:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_explicit.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_remove_product_from_product_set_2]
@@ -824,12 +824,12 @@ Using the operator
 We are using the :class:`~google.api_core.retry.Retry` objects from
 Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :start-after: [START howto_operator_vision_retry_import]
       :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_detect_text]
@@ -837,7 +837,7 @@ Google libraries:
 
 The result can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_detect_text_result]
@@ -876,12 +876,12 @@ Using the operator
 We are using the :class:`~google.api_core.retry.Retry` objects from
 Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :start-after: [START howto_operator_vision_retry_import]
       :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_document_detect_text]
@@ -889,7 +889,7 @@ Google libraries:
 
 The result can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_document_detect_text_result]
@@ -929,12 +929,12 @@ Using the operator
 We are using the :class:`~google.api_core.retry.Retry` objects from
 Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :start-after: [START howto_operator_vision_retry_import]
       :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_detect_labels]
@@ -942,7 +942,7 @@ Google libraries:
 
 The result can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_detect_labels_result]
@@ -981,12 +981,12 @@ Using the operator
 We are using the :class:`~google.api_core.retry.Retry` objects from
 Google libraries:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :start-after: [START howto_operator_vision_retry_import]
       :end-before: [END howto_operator_vision_retry_import]
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_detect_safe_search]
@@ -994,7 +994,7 @@ Google libraries:
 
 The result can be extracted from XCOM:
 
-.. exampleinclude:: /../../airflow/providers/google/cloud/example_dags/example_vision.py
+.. exampleinclude:: /../../tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
       :language: python
       :dedent: 4
       :start-after: [START howto_operator_vision_detect_safe_search_result]
diff --git a/tests/providers/google/cloud/operators/test_vision_system.py b/tests/providers/google/cloud/operators/test_vision_system.py
deleted file mode 100644
index 57168562ec..0000000000
--- a/tests/providers/google/cloud/operators/test_vision_system.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# 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 os
-from tempfile import NamedTemporaryFile
-
-import pytest
-
-from tests.providers.google.cloud.utils.gcp_authenticator import GCP_AI_KEY, GCP_GCS_KEY
-from tests.test_utils.gcp_system_helpers import CLOUD_DAG_FOLDER, GoogleSystemTest, provide_gcp_context
-
-GCP_BUCKET_NAME = os.environ.get("GCP_VISION_BUCKET_NAME", "vision-bucket-system-test")
-GCP_REFERENCE_IMAGE_URL = os.environ.get("GCP_VISION_REFERENCE_IMAGE_URL", "gs://bucket-name/image.png")
-GCP_ANNOTATE_IMAGE_URL = os.environ.get("GCP_VISION_ANNOTATE_IMAGE_URL", "gs://bucket-name/image.png")
-GCP_VIDEO_SOURCE_URL = os.environ.get("GCP_VISION_SOURCE_IMAGE_URL", "http://google.com/image.jpg")
-
-
-@pytest.mark.system("google.cloud")
-@pytest.mark.credential_file(GCP_AI_KEY)
-class CloudVisionExampleDagsSystemTest(GoogleSystemTest):
-    @provide_gcp_context(GCP_AI_KEY)
-    def setUp(self):
-        super().setUp()
-        self.create_gcs_bucket(GCP_BUCKET_NAME, location="europe-north1")
-        with NamedTemporaryFile(suffix=".png") as file:
-            self.execute_cmd(["curl", "-s", GCP_VIDEO_SOURCE_URL, "-o", file.name])
-            self.execute_with_ctx(["gsutil", "cp", file.name, GCP_REFERENCE_IMAGE_URL], key=GCP_GCS_KEY)
-            self.execute_with_ctx(["gsutil", "cp", file.name, GCP_ANNOTATE_IMAGE_URL], key=GCP_GCS_KEY)
-
-    @provide_gcp_context(GCP_AI_KEY)
-    def tearDown(self):
-        self.delete_gcs_bucket(GCP_BUCKET_NAME)
-        super().tearDown()
-
-    @provide_gcp_context(GCP_AI_KEY)
-    def test_run_example_gcp_vision_autogenerated_id_dag(self):
-        self.run_dag("example_gcp_vision_autogenerated_id", CLOUD_DAG_FOLDER)
-
-    @provide_gcp_context(GCP_AI_KEY)
-    def test_run_example_gcp_vision_explicit_id_dag(self):
-        self.run_dag("example_gcp_vision_explicit_id", CLOUD_DAG_FOLDER)
-
-    @provide_gcp_context(GCP_AI_KEY)
-    def test_run_example_gcp_vision_annotate_image_dag(self):
-        self.run_dag("example_gcp_vision_annotate_image", CLOUD_DAG_FOLDER)
diff --git a/tests/system/providers/google/cloud/vision/__init__.py b/tests/system/providers/google/cloud/vision/__init__.py
new file mode 100644
index 0000000000..13a83393a9
--- /dev/null
+++ b/tests/system/providers/google/cloud/vision/__init__.py
@@ -0,0 +1,16 @@
+# 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.
diff --git a/tests/system/providers/google/cloud/vision/example_vision_annotate_image.py b/tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
new file mode 100644
index 0000000000..b65199098b
--- /dev/null
+++ b/tests/system/providers/google/cloud/vision/example_vision_annotate_image.py
@@ -0,0 +1,201 @@
+# 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 os
+from datetime import datetime
+
+from airflow import models
+from airflow.models.baseoperator import chain
+from airflow.operators.bash import BashOperator
+from airflow.providers.google.cloud.operators.gcs import GCSCreateBucketOperator, GCSDeleteBucketOperator
+from airflow.providers.google.cloud.operators.vision import (
+    CloudVisionDetectImageLabelsOperator,
+    CloudVisionDetectImageSafeSearchOperator,
+    CloudVisionDetectTextOperator,
+    CloudVisionImageAnnotateOperator,
+    CloudVisionTextDetectOperator,
+)
+from airflow.providers.google.cloud.transfers.gcs_to_gcs import GCSToGCSOperator
+from airflow.utils.trigger_rule import TriggerRule
+
+# [START howto_operator_vision_retry_import]
+from google.api_core.retry import Retry  # isort:skip
+
+# [END howto_operator_vision_retry_import]
+
+# [START howto_operator_vision_enums_import]
+from google.cloud.vision import enums  # isort:skip
+
+# [END howto_operator_vision_enums_import]
+
+ENV_ID = os.environ.get("SYSTEM_TESTS_ENV_ID")
+PROJECT_ID = os.environ.get("SYSTEM_TESTS_GCP_PROJECT")
+
+DAG_ID = "example_gcp_vision_annotate_image"
+
+LOCATION = "europe-west1"
+
+BUCKET_NAME = f"bucket-{DAG_ID}-{ENV_ID}"
+FILE_NAME = "image1.jpg"
+
+GCP_VISION_ANNOTATE_IMAGE_URL = f"gs://{BUCKET_NAME}/{FILE_NAME}"
+
+# [START howto_operator_vision_annotate_image_request]
+annotate_image_request = {
+    "image": {"source": {"image_uri": GCP_VISION_ANNOTATE_IMAGE_URL}},
+    "features": [{"type": enums.Feature.Type.LOGO_DETECTION}],
+}
+# [END howto_operator_vision_annotate_image_request]
+
+# [START howto_operator_vision_detect_image_param]
+DETECT_IMAGE = {"source": {"image_uri": GCP_VISION_ANNOTATE_IMAGE_URL}}
+# [END howto_operator_vision_detect_image_param]
+
+
+# Public bucket holding the sample data
+BUCKET_NAME_SRC = "cloud-samples-data"
+# Path to the data inside the public bucket
+PATH_SRC = "vision/ocr/sign.jpg"
+
+
+with models.DAG(
+    DAG_ID,
+    schedule="@once",
+    start_date=datetime(2021, 1, 1),
+    catchup=False,
+    tags=["example", "vision"],
+) as dag:
+
+    create_bucket = GCSCreateBucketOperator(
+        task_id="create_bucket", project_id=PROJECT_ID, bucket_name=BUCKET_NAME
+    )
+
+    copy_single_file = GCSToGCSOperator(
+        task_id="copy_single_gcs_file",
+        source_bucket=BUCKET_NAME_SRC,
+        source_object=PATH_SRC,
+        destination_bucket=BUCKET_NAME,
+        destination_object=FILE_NAME,
+    )
+
+    # [START howto_operator_vision_annotate_image]
+    annotate_image = CloudVisionImageAnnotateOperator(
+        request=annotate_image_request,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="annotate_image",
+    )
+    # [END howto_operator_vision_annotate_image]
+
+    # [START howto_operator_vision_annotate_image_result]
+    annotate_image_result = BashOperator(
+        bash_command="echo {{ task_instance.xcom_pull('annotate_image')"
+        "['logoAnnotations'][0]['description'] }}",
+        task_id="annotate_image_result",
+    )
+    # [END howto_operator_vision_annotate_image_result]
+
+    # [START howto_operator_vision_detect_text]
+    detect_text = CloudVisionDetectTextOperator(
+        image=DETECT_IMAGE,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="detect_text",
+        language_hints="en",
+        web_detection_params={"include_geo_results": True},
+    )
+    # [END howto_operator_vision_detect_text]
+
+    # [START howto_operator_vision_detect_text_result]
+    detect_text_result = BashOperator(
+        bash_command="echo {{ task_instance.xcom_pull('detect_text')['textAnnotations'][0] }}",
+        task_id="detect_text_result",
+    )
+    # [END howto_operator_vision_detect_text_result]
+
+    # [START howto_operator_vision_document_detect_text]
+    document_detect_text = CloudVisionTextDetectOperator(
+        image=DETECT_IMAGE, retry=Retry(maximum=10.0), timeout=5, task_id="document_detect_text"
+    )
+    # [END howto_operator_vision_document_detect_text]
+
+    # [START howto_operator_vision_document_detect_text_result]
+    document_detect_text_result = BashOperator(
+        bash_command="echo {{ task_instance.xcom_pull('document_detect_text')['textAnnotations'][0] }}",
+        task_id="document_detect_text_result",
+    )
+    # [END howto_operator_vision_document_detect_text_result]
+
+    # [START howto_operator_vision_detect_labels]
+    detect_labels = CloudVisionDetectImageLabelsOperator(
+        image=DETECT_IMAGE, retry=Retry(maximum=10.0), timeout=5, task_id="detect_labels"
+    )
+    # [END howto_operator_vision_detect_labels]
+
+    # [START howto_operator_vision_detect_labels_result]
+    detect_labels_result = BashOperator(
+        bash_command="echo {{ task_instance.xcom_pull('detect_labels')['labelAnnotations'][0] }}",
+        task_id="detect_labels_result",
+    )
+    # [END howto_operator_vision_detect_labels_result]
+
+    # [START howto_operator_vision_detect_safe_search]
+    detect_safe_search = CloudVisionDetectImageSafeSearchOperator(
+        image=DETECT_IMAGE, retry=Retry(maximum=10.0), timeout=5, task_id="detect_safe_search"
+    )
+    # [END howto_operator_vision_detect_safe_search]
+
+    # [START howto_operator_vision_detect_safe_search_result]
+    detect_safe_search_result = BashOperator(
+        bash_command=f"echo {detect_safe_search.output}",
+        task_id="detect_safe_search_result",
+    )
+    # [END howto_operator_vision_detect_safe_search_result]
+
+    delete_bucket = GCSDeleteBucketOperator(
+        task_id="delete_bucket", bucket_name=BUCKET_NAME, trigger_rule=TriggerRule.ALL_DONE
+    )
+
+    chain(
+        create_bucket,
+        copy_single_file,
+        annotate_image,
+        annotate_image_result,
+        detect_text,
+        detect_text_result,
+        document_detect_text,
+        document_detect_text_result,
+        detect_labels,
+        detect_labels_result,
+        detect_safe_search,
+        detect_safe_search_result,
+        delete_bucket,
+    )
+
+    from tests.system.utils.watcher import watcher
+
+    # This test needs watcher in order to properly mark success/failure
+    # when "teardown" task with trigger rule is part of the DAG
+    list(dag.tasks) >> watcher()
+
+
+from tests.system.utils import get_test_run  # noqa: E402
+
+# Needed to run the example DAG with pytest (see: tests/system/README.md#run_via_pytest)
+test_run = get_test_run(dag)
diff --git a/tests/system/providers/google/cloud/vision/example_vision_autogenerated.py b/tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
new file mode 100644
index 0000000000..12820cfeb2
--- /dev/null
+++ b/tests/system/providers/google/cloud/vision/example_vision_autogenerated.py
@@ -0,0 +1,278 @@
+#
+# 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 os
+from datetime import datetime
+
+from airflow import models
+from airflow.models.baseoperator import chain
+from airflow.providers.google.cloud.operators.gcs import GCSCreateBucketOperator, GCSDeleteBucketOperator
+from airflow.providers.google.cloud.operators.vision import (
+    CloudVisionAddProductToProductSetOperator,
+    CloudVisionCreateProductOperator,
+    CloudVisionCreateProductSetOperator,
+    CloudVisionCreateReferenceImageOperator,
+    CloudVisionDeleteProductOperator,
+    CloudVisionDeleteProductSetOperator,
+    CloudVisionDeleteReferenceImageOperator,
+    CloudVisionGetProductOperator,
+    CloudVisionGetProductSetOperator,
+    CloudVisionRemoveProductFromProductSetOperator,
+    CloudVisionUpdateProductOperator,
+    CloudVisionUpdateProductSetOperator,
+)
+from airflow.providers.google.cloud.transfers.gcs_to_gcs import GCSToGCSOperator
+from airflow.utils.trigger_rule import TriggerRule
+
+# [START howto_operator_vision_retry_import]
+from google.api_core.retry import Retry  # isort:skip
+
+# [END howto_operator_vision_retry_import]
+# [START howto_operator_vision_product_set_import]
+from google.cloud.vision_v1.types import ProductSet  # isort:skip
+
+# [END howto_operator_vision_product_set_import]
+# [START howto_operator_vision_product_import]
+from google.cloud.vision_v1.types import Product  # isort:skip
+
+# [END howto_operator_vision_product_import]
+# [START howto_operator_vision_reference_image_import]
+from google.cloud.vision_v1.types import ReferenceImage  # isort:skip
+
+# [END howto_operator_vision_reference_image_import]
+# [START howto_operator_vision_enums_import]
+from google.cloud.vision import enums  # isort:skip
+
+# [END howto_operator_vision_enums_import]
+
+ENV_ID = os.environ.get("SYSTEM_TESTS_ENV_ID")
+PROJECT_ID = os.environ.get("SYSTEM_TESTS_GCP_PROJECT")
+
+DAG_ID = "example_gcp_vision_autogenerated_id"
+
+LOCATION = "europe-west1"
+
+BUCKET_NAME = f"bucket-{DAG_ID}-{ENV_ID}"
+FILE_NAME = "image1.jpg"
+
+GCP_VISION_PRODUCT_SET_ID = "product_set_explicit_id"
+GCP_VISION_PRODUCT_ID = "product_explicit_id"
+GCP_VISION_REFERENCE_IMAGE_ID = f"reference_image_explicit_id-{ENV_ID}"
+
+VISION_IMAGE_URL = f"gs://{BUCKET_NAME}/{FILE_NAME}"
+
+# [START howto_operator_vision_product_set]
+product_set = ProductSet(display_name="My Product Set")
+# [END howto_operator_vision_product_set]
+
+# [START howto_operator_vision_product]
+product = Product(display_name="My Product 1", product_category="toys")
+# [END howto_operator_vision_product]
+
+# [START howto_operator_vision_reference_image]
+reference_image = ReferenceImage(uri=VISION_IMAGE_URL)
+# [END howto_operator_vision_reference_image]
+
+# [START howto_operator_vision_annotate_image_request]
+annotate_image_request = {
+    "image": {"source": {"image_uri": VISION_IMAGE_URL}},
+    "features": [{"type": enums.Feature.Type.LOGO_DETECTION}],
+}
+# [END howto_operator_vision_annotate_image_request]
+
+# [START howto_operator_vision_detect_image_param]
+DETECT_IMAGE = {"source": {"image_uri": VISION_IMAGE_URL}}
+# [END howto_operator_vision_detect_image_param]
+
+# Public bucket holding the sample data
+BUCKET_NAME_SRC = "cloud-samples-data"
+# Path to the data inside the public bucket
+PATH_SRC = "vision/ocr/sign.jpg"
+
+with models.DAG(
+    DAG_ID,
+    schedule="@once",
+    start_date=datetime(2021, 1, 1),
+    catchup=False,
+    tags=["example", "vision"],
+) as dag:
+
+    create_bucket = GCSCreateBucketOperator(
+        task_id="create_bucket", project_id=PROJECT_ID, bucket_name=BUCKET_NAME
+    )
+
+    copy_single_file = GCSToGCSOperator(
+        task_id="copy_single_gcs_file",
+        source_bucket=BUCKET_NAME_SRC,
+        source_object=PATH_SRC,
+        destination_bucket=BUCKET_NAME,
+        destination_object=FILE_NAME,
+    )
+
+    # [START howto_operator_vision_product_set_create]
+    product_set_create = CloudVisionCreateProductSetOperator(
+        location=LOCATION,
+        product_set=product_set,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="product_set_create",
+    )
+    # [END howto_operator_vision_product_set_create]
+
+    product_set_create_output = "{{ task_instance.xcom_pull('product_set_create') }}"
+
+    # [START howto_operator_vision_product_set_get]
+    product_set_get = CloudVisionGetProductSetOperator(
+        location=LOCATION,
+        product_set_id=product_set_create_output,
+        task_id="product_set_get",
+    )
+    # [END howto_operator_vision_product_set_get]
+
+    # [START howto_operator_vision_product_set_update]
+    product_set_update = CloudVisionUpdateProductSetOperator(
+        location=LOCATION,
+        product_set_id=product_set_create_output,
+        product_set=ProductSet(display_name="My Product Set 2"),
+        task_id="product_set_update",
+    )
+    # [END howto_operator_vision_product_set_update]
+
+    # [START howto_operator_vision_product_set_delete]
+    product_set_delete = CloudVisionDeleteProductSetOperator(
+        location=LOCATION,
+        product_set_id=product_set_create_output,
+        task_id="product_set_delete",
+    )
+    # [END howto_operator_vision_product_set_delete]
+
+    # [START howto_operator_vision_product_create]
+    product_create = CloudVisionCreateProductOperator(
+        location=LOCATION,
+        product=product,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="product_create",
+    )
+    # [END howto_operator_vision_product_create]
+
+    # [START howto_operator_vision_product_get]
+    product_get = CloudVisionGetProductOperator(
+        location=LOCATION,
+        product_id="{{ task_instance.xcom_pull('product_create') }}",
+        task_id="product_get",
+    )
+    # [END howto_operator_vision_product_get]
+
+    # [START howto_operator_vision_product_update]
+    product_update = CloudVisionUpdateProductOperator(
+        location=LOCATION,
+        product_id="{{ task_instance.xcom_pull('product_create') }}",
+        product=Product(display_name="My Product 2", description="My updated description"),
+        task_id="product_update",
+    )
+    # [END howto_operator_vision_product_update]
+
+    # [START howto_operator_vision_product_delete]
+    product_delete = CloudVisionDeleteProductOperator(
+        location=LOCATION,
+        product_id="{{ task_instance.xcom_pull('product_create') }}",
+        task_id="product_delete",
+    )
+    # [END howto_operator_vision_product_delete]
+
+    # [START howto_operator_vision_reference_image_create]
+    reference_image_create = CloudVisionCreateReferenceImageOperator(
+        location=LOCATION,
+        reference_image=reference_image,
+        product_id="{{ task_instance.xcom_pull('product_create') }}",
+        reference_image_id=GCP_VISION_REFERENCE_IMAGE_ID,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="reference_image_create",
+    )
+    # [END howto_operator_vision_reference_image_create]
+
+    # [START howto_operator_vision_reference_image_delete]
+    reference_image_delete = CloudVisionDeleteReferenceImageOperator(
+        location=LOCATION,
+        product_id="{{ task_instance.xcom_pull('product_create') }}",
+        reference_image_id=GCP_VISION_REFERENCE_IMAGE_ID,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="reference_image_delete",
+    )
+    # [END howto_operator_vision_reference_image_delete]
+
+    # [START howto_operator_vision_add_product_to_product_set]
+    add_product_to_product_set = CloudVisionAddProductToProductSetOperator(
+        location=LOCATION,
+        product_set_id=product_set_create_output,
+        product_id="{{ task_instance.xcom_pull('product_create') }}",
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="add_product_to_product_set",
+    )
+    # [END howto_operator_vision_add_product_to_product_set]
+
+    # [START howto_operator_vision_remove_product_from_product_set]
+    remove_product_from_product_set = CloudVisionRemoveProductFromProductSetOperator(
+        location=LOCATION,
+        product_set_id=product_set_create_output,
+        product_id="{{ task_instance.xcom_pull('product_create') }}",
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="remove_product_from_product_set",
+    )
+    # [END howto_operator_vision_remove_product_from_product_set]
+
+    delete_bucket = GCSDeleteBucketOperator(
+        task_id="delete_bucket", bucket_name=BUCKET_NAME, trigger_rule=TriggerRule.ALL_DONE
+    )
+
+    chain(
+        create_bucket,
+        copy_single_file,
+        product_create,
+        product_get,
+        product_update,
+        product_set_create,
+        product_set_get,
+        product_set_update,
+        reference_image_create,
+        add_product_to_product_set,
+        reference_image_delete,
+        remove_product_from_product_set,
+        product_set_delete,
+        product_delete,
+        delete_bucket,
+    )
+
+    from tests.system.utils.watcher import watcher
+
+    # This test needs watcher in order to properly mark success/failure
+    # when "teardown" task with trigger rule is part of the DAG
+    list(dag.tasks) >> watcher()
+
+
+from tests.system.utils import get_test_run  # noqa: E402
+
+# Needed to run the example DAG with pytest (see: tests/system/README.md#run_via_pytest)
+test_run = get_test_run(dag)
diff --git a/tests/system/providers/google/cloud/vision/example_vision_explicit.py b/tests/system/providers/google/cloud/vision/example_vision_explicit.py
new file mode 100644
index 0000000000..d386b7933d
--- /dev/null
+++ b/tests/system/providers/google/cloud/vision/example_vision_explicit.py
@@ -0,0 +1,287 @@
+# 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 os
+from datetime import datetime
+
+from airflow import models
+from airflow.models.baseoperator import chain
+from airflow.providers.google.cloud.operators.gcs import GCSCreateBucketOperator, GCSDeleteBucketOperator
+from airflow.providers.google.cloud.operators.vision import (
+    CloudVisionAddProductToProductSetOperator,
+    CloudVisionCreateProductOperator,
+    CloudVisionCreateProductSetOperator,
+    CloudVisionCreateReferenceImageOperator,
+    CloudVisionDeleteProductOperator,
+    CloudVisionDeleteProductSetOperator,
+    CloudVisionDeleteReferenceImageOperator,
+    CloudVisionGetProductOperator,
+    CloudVisionGetProductSetOperator,
+    CloudVisionRemoveProductFromProductSetOperator,
+    CloudVisionUpdateProductOperator,
+    CloudVisionUpdateProductSetOperator,
+)
+from airflow.providers.google.cloud.transfers.gcs_to_gcs import GCSToGCSOperator
+from airflow.utils.trigger_rule import TriggerRule
+
+# [START howto_operator_vision_retry_import]
+from google.api_core.retry import Retry  # isort:skip
+
+# [END howto_operator_vision_retry_import]
+# [START howto_operator_vision_product_set_import_2]
+from google.cloud.vision_v1.types import ProductSet  # isort:skip
+
+# [END howto_operator_vision_product_set_import_2]
+# [START howto_operator_vision_product_import_2]
+from google.cloud.vision_v1.types import Product  # isort:skip
+
+# [END howto_operator_vision_product_import_2]
+# [START howto_operator_vision_reference_image_import_2]
+from google.cloud.vision_v1.types import ReferenceImage  # isort:skip
+
+# [END howto_operator_vision_reference_image_import_2]
+
+
+ENV_ID = os.environ.get("SYSTEM_TESTS_ENV_ID")
+PROJECT_ID = os.environ.get("SYSTEM_TESTS_GCP_PROJECT")
+
+DAG_ID = "example_gcp_vision_explicit_id"
+
+LOCATION = "europe-west1"
+
+BUCKET_NAME = f"bucket-{DAG_ID}-{ENV_ID}"
+FILE_NAME = "image1.jpg"
+
+GCP_VISION_PRODUCT_SET_ID = "product_set_explicit_id"
+GCP_VISION_PRODUCT_ID = "product_explicit_id"
+GCP_VISION_REFERENCE_IMAGE_ID = "reference_image_explicit_id"
+
+VISION_IMAGE_URL = f"gs://{BUCKET_NAME}/{FILE_NAME}"
+
+# [START howto_operator_vision_product_set]
+product_set = ProductSet(display_name="My Product Set")
+# [END howto_operator_vision_product_set]
+
+# [START howto_operator_vision_product]
+product = Product(display_name="My Product 1", product_category="toys")
+# [END howto_operator_vision_product]
+
+# [START howto_operator_vision_reference_image]
+reference_image = ReferenceImage(uri=VISION_IMAGE_URL)
+# [END howto_operator_vision_reference_image]
+
+# Public bucket holding the sample data
+BUCKET_NAME_SRC = "cloud-samples-data"
+# Path to the data inside the public bucket
+PATH_SRC = "vision/ocr/sign.jpg"
+
+
+with models.DAG(
+    DAG_ID,
+    schedule="@once",
+    start_date=datetime(2021, 1, 1),
+    catchup=False,
+    tags=["example", "vision"],
+) as dag:
+
+    create_bucket = GCSCreateBucketOperator(
+        task_id="create_bucket", project_id=PROJECT_ID, bucket_name=BUCKET_NAME
+    )
+
+    copy_single_file = GCSToGCSOperator(
+        task_id="copy_single_gcs_file",
+        source_bucket=BUCKET_NAME_SRC,
+        source_object=PATH_SRC,
+        destination_bucket=BUCKET_NAME,
+        destination_object=FILE_NAME,
+    )
+
+    # [START howto_operator_vision_product_set_create_2]
+    product_set_create_2 = CloudVisionCreateProductSetOperator(
+        product_set_id=GCP_VISION_PRODUCT_SET_ID,
+        location=LOCATION,
+        product_set=product_set,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="product_set_create_2",
+    )
+    # [END howto_operator_vision_product_set_create_2]
+
+    # Second 'create' task with the same product_set_id to demonstrate idempotence
+    product_set_create_2_idempotence = CloudVisionCreateProductSetOperator(
+        product_set_id=GCP_VISION_PRODUCT_SET_ID,
+        location=LOCATION,
+        product_set=product_set,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="product_set_create_2_idempotence",
+    )
+
+    # [START howto_operator_vision_product_set_get_2]
+    product_set_get_2 = CloudVisionGetProductSetOperator(
+        location=LOCATION, product_set_id=GCP_VISION_PRODUCT_SET_ID, task_id="product_set_get_2"
+    )
+    # [END howto_operator_vision_product_set_get_2]
+
+    # [START howto_operator_vision_product_set_update_2]
+    product_set_update_2 = CloudVisionUpdateProductSetOperator(
+        location=LOCATION,
+        product_set_id=GCP_VISION_PRODUCT_SET_ID,
+        product_set=ProductSet(display_name="My Product Set 2"),
+        task_id="product_set_update_2",
+    )
+    # [END howto_operator_vision_product_set_update_2]
+
+    # [START howto_operator_vision_product_set_delete_2]
+    product_set_delete_2 = CloudVisionDeleteProductSetOperator(
+        location=LOCATION, product_set_id=GCP_VISION_PRODUCT_SET_ID, task_id="product_set_delete_2"
+    )
+    # [END howto_operator_vision_product_set_delete_2]
+
+    # [START howto_operator_vision_product_create_2]
+    product_create_2 = CloudVisionCreateProductOperator(
+        product_id=GCP_VISION_PRODUCT_ID,
+        location=LOCATION,
+        product=product,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="product_create_2",
+    )
+    # [END howto_operator_vision_product_create_2]
+
+    # Second 'create' task with the same product_id to demonstrate idempotence
+    product_create_2_idempotence = CloudVisionCreateProductOperator(
+        product_id=GCP_VISION_PRODUCT_ID,
+        location=LOCATION,
+        product=product,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="product_create_2_idempotence",
+    )
+
+    # [START howto_operator_vision_product_get_2]
+    product_get_2 = CloudVisionGetProductOperator(
+        location=LOCATION, product_id=GCP_VISION_PRODUCT_ID, task_id="product_get_2"
+    )
+    # [END howto_operator_vision_product_get_2]
+
+    # [START howto_operator_vision_product_update_2]
+    product_update_2 = CloudVisionUpdateProductOperator(
+        location=LOCATION,
+        product_id=GCP_VISION_PRODUCT_ID,
+        product=Product(display_name="My Product 2", description="My updated description"),
+        task_id="product_update_2",
+    )
+    # [END howto_operator_vision_product_update_2]
+
+    # [START howto_operator_vision_product_delete_2]
+    product_delete_2 = CloudVisionDeleteProductOperator(
+        location=LOCATION, product_id=GCP_VISION_PRODUCT_ID, task_id="product_delete_2"
+    )
+    # [END howto_operator_vision_product_delete_2]
+
+    # [START howto_operator_vision_reference_image_create_2]
+    reference_image_create_2 = CloudVisionCreateReferenceImageOperator(
+        location=LOCATION,
+        reference_image=reference_image,
+        product_id=GCP_VISION_PRODUCT_ID,
+        reference_image_id=GCP_VISION_REFERENCE_IMAGE_ID,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="reference_image_create_2",
+    )
+    # [END howto_operator_vision_reference_image_create_2]
+
+    # [START howto_operator_vision_reference_image_delete_2]
+    reference_image_delete_2 = CloudVisionDeleteReferenceImageOperator(
+        location=LOCATION,
+        reference_image_id=GCP_VISION_REFERENCE_IMAGE_ID,
+        product_id=GCP_VISION_PRODUCT_ID,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="reference_image_delete_2",
+    )
+    # [END howto_operator_vision_reference_image_delete_2]
+
+    # Second 'create' task with the same product_id to demonstrate idempotence
+    reference_image_create_2_idempotence = CloudVisionCreateReferenceImageOperator(
+        location=LOCATION,
+        reference_image=reference_image,
+        product_id=GCP_VISION_PRODUCT_ID,
+        reference_image_id=GCP_VISION_REFERENCE_IMAGE_ID,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="reference_image_create_2_idempotence",
+    )
+
+    # [START howto_operator_vision_add_product_to_product_set_2]
+    add_product_to_product_set_2 = CloudVisionAddProductToProductSetOperator(
+        location=LOCATION,
+        product_set_id=GCP_VISION_PRODUCT_SET_ID,
+        product_id=GCP_VISION_PRODUCT_ID,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="add_product_to_product_set_2",
+    )
+    # [END howto_operator_vision_add_product_to_product_set_2]
+
+    # [START howto_operator_vision_remove_product_from_product_set_2]
+    remove_product_from_product_set_2 = CloudVisionRemoveProductFromProductSetOperator(
+        location=LOCATION,
+        product_set_id=GCP_VISION_PRODUCT_SET_ID,
+        product_id=GCP_VISION_PRODUCT_ID,
+        retry=Retry(maximum=10.0),
+        timeout=5,
+        task_id="remove_product_from_product_set_2",
+    )
+    # [END howto_operator_vision_remove_product_from_product_set_2]
+
+    delete_bucket = GCSDeleteBucketOperator(
+        task_id="delete_bucket", bucket_name=BUCKET_NAME, trigger_rule=TriggerRule.ALL_DONE
+    )
+
+    chain(
+        product_set_create_2,
+        product_set_get_2,
+        product_set_update_2,
+        product_create_2,
+        product_create_2_idempotence,
+        product_get_2,
+        product_update_2,
+        reference_image_create_2,
+        reference_image_create_2_idempotence,
+        add_product_to_product_set_2,
+        remove_product_from_product_set_2,
+        reference_image_delete_2,
+        product_delete_2,
+        product_set_delete_2,
+        delete_bucket,
+    )
+
+    from tests.system.utils.watcher import watcher
+
+    # This test needs watcher in order to properly mark success/failure
+    # when "teardown" task with trigger rule is part of the DAG
+    list(dag.tasks) >> watcher()
+
+
+from tests.system.utils import get_test_run  # noqa: E402
+
+# Needed to run the example DAG with pytest (see: tests/system/README.md#run_via_pytest)
+test_run = get_test_run(dag)